public void BackPropagation(TrainTuple train) { var nablaB = Biases.Select(it => Vector <double> .Build.Dense(it.Count, 0)).ToList(); var nablaW = Weights.Select(it => Matrix <double> .Build.Dense(it.RowCount, it.ColumnCount, 0)).ToList(); var activation = Vector <double> .Build.DenseOfEnumerable(train.Input.Select(it => (double)it)); var activations = new List <Vector <double> > { activation }; var zs = new List <Vector <double> >(); var weightsWithBiases = Biases.Zip(Weights, (vector, matrix) => (vector, matrix)); foreach (var(bias, weights) in weightsWithBiases) { var z = weights.TransposeThisAndMultiply(activation) + bias; zs.Add(z); activations.Add(z.Map(Sigmoid)); } var expected = Vector <double> .Build.DenseOfEnumerable(train.Output.Select(it => (double)it)); var delta = CostDerivative(activations.Last(), expected) * zs.Last().Map(SigmoidPrime); //nablaB[^0] = delta; }
/// <summary> /// Save wieghts and biases within a file /// </summary> /// <param name="file">path to the file</param> public void Save(string file) { NetworkMemory memory = new NetworkMemory { Biases = Biases.Select(b => b.mat).ToArray(), Weights = Weights.Select(b => b.mat).ToArray(), Sizes = Sizes }; JsonSerializer serializer = new JsonSerializer(); using (StreamWriter sw = new StreamWriter(file)) using (JsonWriter writer = new JsonTextWriter(sw)) { serializer.Serialize(writer, memory); } }
/// <summary> /// Update a mini batch of results representing a small portion of the neural network /// </summary> /// <param name="miniBatch">small batch of datas</param> /// <param name="eta">leaning rate</param> private void UpdateMiniBatch(List <Data> miniBatch, float eta) { Matrix[] nablaBiases = Biases.Select(b => new Matrix(new float[b.mat.GetLength(0), b.mat.GetLength(1)])).ToArray(); Matrix[] nablaWeights = Weights.Select(w => new Matrix(new float[w.mat.GetLength(0), w.mat.GetLength(1)])).ToArray(); float K = eta / miniBatch.Count; for (int n = 0; n < miniBatch.Count; n++) { DeltaNabla deltaNabla = BackPropagation(miniBatch[n]); for (int l = 0; l < NumberOfLayer - 1; l++) { nablaBiases[l] += deltaNabla.Biases[l]; nablaWeights[l] += deltaNabla.Weights[l]; } } for (int l = 0; l < NumberOfLayer - 1; l++) { Biases[l] -= K * nablaBiases[l]; Weights[l] -= K * nablaWeights[l]; } }