Skip to content
This repository has been archived by the owner on Nov 19, 2020. It is now read-only.

RandomForest not serializable #331

Closed
mmehrle opened this issue Oct 22, 2016 · 5 comments
Closed

RandomForest not serializable #331

mmehrle opened this issue Oct 22, 2016 · 5 comments

Comments

@mmehrle
Copy link

mmehrle commented Oct 22, 2016

I just attempted to serialize my random forest like this:

Serializer.Save<RandomForest>(forest, fileName); // forest is the obj, fileName is the path

Throws a RT error that it is not marked as serializable. Then I tried this:

using (FileStream fs = new FileStream(fileName, FileMode.Create)) { new BinaryFormatter().Serialize(fs, forest); }

I checked the definition and apparently it is 'ParallelOptions' breaking this. Not sure how to fix this (yet).

@mmehrle
Copy link
Author

mmehrle commented Oct 23, 2016

Okay, I think I was able to fix it. See the code below:

`
namespace Accord.MachineLearning.DecisionTrees
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using Accord.Statistics.Filters;
using Accord.Math;
using AForge;
using Accord.Statistics;
using System.Threading;

/// <summary>
///   Random Forest.
/// </summary>
/// 
/// <remarks>
/// <para>
///   Represents a random forest of <see cref="DecisionTree"/>s. For 
///   sample usage and example of learning, please see the documentation
///   page for <see cref="RandomForestLearning"/>.</para>
/// </remarks>
/// 
/// <seealso cref="DecisionTree"/>
/// <seealso cref="RandomForestLearning"/>
/// 
[Serializable]
public class RandomForest : MulticlassClassifierBase, IParallel
{
    private DecisionTree[] trees;
    **[NonSerialized]
    private ParallelOptions parallelOptions;**


    /// <summary>
    ///   Gets the trees in the random forest.
    /// </summary>
    /// 
    public DecisionTree[] Trees
    {
        get { return trees; }
    }

    /// <summary>
    ///   Gets the number of classes that can be recognized
    ///   by this random forest.
    /// </summary>
    /// 
    [Obsolete("Please use NumberOfOutputs instead.")]
    public int Classes { get { return NumberOfOutputs; } }

    /// <summary>
    ///   Gets or sets the parallelization options for this algorithm.
    /// </summary>
    ///
    **public ParallelOptions ParallelOptions { get { return parallelOptions; } set { parallelOptions = value; } }**

    /// <summary>
    /// Gets or sets a cancellation token that can be used
    /// to cancel the algorithm while it is running.
    /// </summary>
    /// 
    public CancellationToken Token
    {
        get { return ParallelOptions.CancellationToken; }
        set { ParallelOptions.CancellationToken = value; }
    }

    /// <summary>
    ///   Creates a new random forest.
    /// </summary>
    /// 
    /// <param name="trees">The number of trees in the forest.</param>
    /// <param name="classes">The number of classes in the classification problem.</param>
    /// 
    public RandomForest(int trees, int classes)
    {
        this.trees = new DecisionTree[trees];
        this.NumberOfOutputs = classes;
        this.ParallelOptions = new ParallelOptions();
    }

    /// <summary>
    ///   Computes the decision output for a given input vector.
    /// </summary>
    /// 
    /// <param name="data">The input vector.</param>
    /// 
    /// <returns>The forest decision for the given vector.</returns>
    /// 
    [Obsolete("Please use Decide() instead.")]
    public int Compute(double[] data)
    {
        return Decide(data);
    }


    /// <summary>
    /// Computes a class-label decision for a given <paramref name="input" />.
    /// </summary>
    /// <param name="input">The input vector that should be classified into
    /// one of the <see cref="ITransform.NumberOfOutputs" /> possible classes.</param>
    /// <returns>A class-label that best described <paramref name="input" /> according
    /// to this classifier.</returns>
    public override int Decide(double[] input)
    {
        int[] responses = new int[NumberOfOutputs];
        Parallel.For(0, trees.Length, ParallelOptions, i =>
        {
            int j = trees[i].Decide(input);
            Interlocked.Increment(ref responses[j]);
        });

        return responses.ArgMax();
    }

   [OnDeserializing()]
    internal void OnDeserializingMethod(StreamingContext context)
    {
        this.ParallelOptions = new ParallelOptions();
    }
}

}
`

@cesarsouza
Copy link
Member

Many thanks!

@Rbcody
Copy link

Rbcody commented Dec 28, 2016 via email

@cesarsouza
Copy link
Member

Thanks a lot. Your appreciation indeed really means a lot to me (and I am sure to other contributors of the project as well!).

Regards,
Cesar

@cesarsouza
Copy link
Member

Integrated in release 3.4.0.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants