public override ISequenceModel Generate(Matrix X, Matrix Y) { // dense autoencoders learn the approximation identity function so ignore labels. // the output layer is the number of columns in X // default hidden layer to 2/3 of the input this.Preprocess(X); if (this.Density <= 0) this.Density = (int) System.Math.Ceiling(X.Cols * (2.0 / 3.0)); if (this.MaxIterations <= 0) MaxIterations = 400; // because Seth said so... Network network = Network.New().Create(X.Cols, X.Cols, this.Activation, this.OutputFunction, (i, j) => new AutoencoderNeuron(), epsilon: this.Epsilon, hiddenLayers: new int[] { this.Density }); var model = new AutoencoderModel { Descriptor = Descriptor, NormalizeFeatures = base.NormalizeFeatures, FeatureNormalizer = base.FeatureNormalizer, FeatureProperties = base.FeatureProperties, Network = network, OutputFunction = this.OutputFunction }; OnModelChanged(this, ModelEventArgs.Make(model, "Initialized")); NetworkTrainingProperties properties = NetworkTrainingProperties.Create(network, X.Rows, X.Cols, this.LearningRate, this.Lambda, this.MaxIterations, new { this.Density, this.Sparsity, this.SparsityWeight }); for (int i = 0; i < this.MaxIterations; i++) { properties.Iteration = i; for (int x = 0; x < X.Rows; x++) { network.Forward(X[x, VectorType.Row]); //OnModelChanged(this, ModelEventArgs.Make(model, "Forward")); network.Back(X[x, VectorType.Row], properties); } var result = String.Format("Run ({0}/{1}): {2}", i, MaxIterations, network.Cost); OnModelChanged(this, ModelEventArgs.Make(model, result)); } return model; }