public void Learning(Dictionary <string, double[]> keyValuePairs, int outClass, int epochs, int miniBatchSize, string filePath, MNIST mnist /* Mnist */) { TextWriter textWriter = new StreamWriter(filePath + "learning_report.csv"); for (int e = 0; e < epochs; e++) { Console.WriteLine("Processing epoch {0} of {1}", e + 1, epochs + 1); var recognition = 0; var recRate = 0.0; // shuffle training input //var list = keyValuePairs.Keys.ToList(); //var rnd = new Random(); //var rndList = list.OrderBy(x => rnd.Next()).ToList(); //Dictionary<string, double[]> rndKeyValuePairs = new Dictionary<string, double[]>(); //foreach (var key in rndList) //{ // rndKeyValuePairs.Add(key, keyValuePairs[key]); //} // ------------------------ MNIST Dataset ------------------------ mnist.ShuffleTrainingImgs(); // ------------------------ MNIST Dataset ------------------------ // training data for (int i = 0; i < /*rndKeyValuePairs.Count*/ mnist.TrainingImgs.Count; i++) { double[] output = new double[outClass]; // forward pass for (int j = 0; j < this.Layers.Count; j++) { if (this.Layers[j].GetType().Equals(typeof(InputLayer))) { this.Layers[j].FeedForward(/*new Bitmap(rndKeyValuePairs.ElementAt(i).Key)*/ null, null, /*null*/ mnist.TrainingImgs[i].Pixels); // MNIST continue; } if (this.Layers[j].GetType().Equals(typeof(ConvolutionLayer))) { if (e == 0 && i == 0) { this.Layers[j].RandInitFilter(); } this.Layers[j].FeedForward(null, null, this.Layers[j - 1].ImgMatrix); continue; } if (this.Layers[j].GetType().Equals(typeof(PoolingLayer))) { this.Layers[j].FeedForward(null, null, this.Layers[j - 1].ImgMatrix); if (this.Layers[j + 1].GetType().Equals(typeof(FullyConnectedLayer))) { this.Layers[j].Flattening(); } continue; } if (this.Layers[j].GetType().Equals(typeof(FullyConnectedLayer))) { if (this.Layers[j + 1].GetType().Equals(typeof(OutputLayer))) { this.Layers[j].InitLayer(this.Layers[j - 1].FlatArray.Length, outClass); } else { this.Layers[j].InitLayer(this.Layers[j - 1].FlatArray.Length, this.Layers[j - 1].FlatArray.Length); } if (e == 0 && i == 0) { this.Layers[j].RandInitLayerMat(); } this.Layers[j].FeedForward(null, this.Layers[j - 1].FlatArray, null); continue; } if (this.Layers[j].GetType().Equals(typeof(OutputLayer))) { this.Layers[j].FeedForward(null, this.Layers[j - 1].FlatArray, null); output = this.Layers[j].GetOutputArray(); } } // backward pass for (int j = this.Layers.Count - 1; j >= 0; j--) { if (this.Layers[j].GetType().Equals(typeof(ConvolutionLayer))) { this.Layers[j].BackwardPass(null, this.Layers[j + 1].DeltaMatrix); continue; } if (this.Layers[j].GetType().Equals(typeof(PoolingLayer))) { if (this.Layers[j + 1].GetType().Equals(typeof(FullyConnectedLayer))) { this.Layers[j].BackwardPass(this.Layers[j + 1].DeltaArray, null); } else { this.Layers[j].BackwardPass(null, this.Layers[j + 1].DeltaMatrix); } continue; } if (this.Layers[j].GetType().Equals(typeof(FullyConnectedLayer))) { this.Layers[j].BackwardPass(this.Layers[j + 1].DeltaArray, null); continue; } if (this.Layers[j].GetType().Equals(typeof(OutputLayer))) { this.Layers[j].BackwardPass(/*rndKeyValuePairs.ElementAt(i).Value*/ mnist.TrainingImgs[i].Label, null); // MNIST } } // update for every mini Batch if (i % miniBatchSize == miniBatchSize - 1) { // update forward pass for (int j = 0; j < this.Layers.Count; j++) { if (this.Layers[j].GetType().Equals(typeof(ConvolutionLayer)) || this.Layers[j].GetType().Equals(typeof(FullyConnectedLayer))) { this.Layers[j].UpdateWeights(miniBatchSize); } } //Console.WriteLine("\t" + "Weights updated after {0} inputs", i + 1); } // recognition rate computation recognition += RecognitionRate(output, /*rndKeyValuePairs.ElementAt(i).Value*/ mnist.TrainingImgs[i].Label); // MNIST } recRate = (double)recognition / (double)/*rndKeyValuePairs.Count*/ mnist.TrainingImgs.Count; // MNIST Console.WriteLine("Recognition rate in epoch {0}: {1}", e + 1, recRate); // save recognition rate to csv after each epoch textWriter.WriteLine(recRate); textWriter.Flush(); // store weights for (int j = 0; j < this.Layers.Count; j++) { if (this.Layers[j].GetType().Equals(typeof(ConvolutionLayer)) || this.Layers[j].GetType().Equals(typeof(FullyConnectedLayer))) { // store weights this.Layers[j].StoreWeights(); } } if (recRate == 1) { Console.WriteLine("Learning stopped in epoch {0} of {1}", e + 1, epochs); break; } } }