double Compute(double x)
method is generally not necessary, since the calculation of the output values of the group will be cheaper to do in the implementation of the softmax layer. But for completeness, and just in case, let it be -) internal class SoftMaxActivationFunction : IFunction { private ILayer _layer = null; private int _ownPosition = 0; internal SoftMaxActivationFunction(ILayer layer, int ownPosition) { _layer = layer; _ownPosition = ownPosition; } public double Compute(double x) { double numerator = Math.Exp(x); double denominator = numerator; for (int i = 0; i < _layer.Neurons.Length; i++) { if (i == _ownPosition) { continue; } denominator += Math.Exp(_layer.Neurons[i].LastNET); } return numerator/denominator; } public double ComputeFirstDerivative(double x) { double y = Compute(x); return y*(1 - y); } public double ComputeSecondDerivative(double x) { throw new NotImplementedException(); } }
internal class CrossEntropy : IMetrics<double> { internal CrossEntropy() { } /// <summary> /// \sum_i v1_i * ln(v2_i) /// </summary> public override double Calculate(double[] v1, double[] v2) { double d = 0; for (int i = 0; i < v1.Length; i++) { d += v1[i]*Math.Log(v2[i]); } return -d; } public override double CalculatePartialDerivaitveByV2Index(double[] v1, double[] v2, int v2Index) { return v2[v2Index] - v1[v2Index]; } }
double[] ComputeOutput(double[] inputVector)
neural network properly: public double[] ComputeOutput(double[] inputVector) { double[] outputVector = inputVector; for (int i = 0; i < _layers.Length; i++) { outputVector = _layers[i].Compute(outputVector); } return outputVector; }
internal class SoftmaxFullConnectedLayer : FullConnectedLayer { internal SoftmaxFullConnectedLayer(int inputDimension, int size) { _neurons = new INeuron[size]; for (int i = 0; i < size; i++) { IFunction smFunction = new SoftMaxActivationFunction(this, i); _neurons[i] = new InLayerFullConnectedNeuron(inputDimension, smFunction); } } public override double[] Compute(double[] inputVector) { double[] numerators = new double[_neurons.Length]; double denominator = 0; for (int i = 0; i < _neurons.Length; i++) { numerators[i] = Math.Exp(_neurons[i].NET(inputVector)); denominator += numerators[i]; } double[] output = new double[_neurons.Length]; for (int i = 0; i < _neurons.Length; i++) { output[i] = numerators[i]/denominator; _neurons[i].LastState = output[i]; } return output; } }
/// <summary> /// Creates network with softmax layer at the outlut, and hidden layes with theirs own activation functions /// </summary> internal FcMlFfNetwork(int inputDimension, int outputDimension, int[] hiddenLayerStructure, IFunction[] hiddenLayerFunctions, IWeightInitializer wi, ILearningStrategy<IMultilayerNeuralNetwork> trainingAlgorithm) { _learningStrategy = trainingAlgorithm; _layers = new ILayer[hiddenLayerFunctions.Length + 1]; _layers[0] = new FullConnectedLayer(inputDimension, hiddenLayerStructure[0], hiddenLayerFunctions[0]); for (int i = 1; i < hiddenLayerStructure.Length; i++) { _layers[i] = new FullConnectedLayer(_layers[i - 1].Neurons.Length, hiddenLayerStructure[i], hiddenLayerFunctions[i]); } //create softmax layer _layers[hiddenLayerStructure.Length] = new SoftmaxFullConnectedLayer(hiddenLayerStructure[hiddenLayerStructure.Length - 1], outputDimension); for (int i = 0; i < _layers.Length; i++) { for (int j = 0; j < _layers[i].Neurons.Length; j++) { _layers[i].Neurons[j].Bias = wi.GetWeight(); for (int k = 0; k < _layers[i].Neurons[j].Weights.Length; k++) { _layers[i].Neurons[j].Weights[k] = wi.GetWeight(); } } } }
Source: https://habr.com/ru/post/155235/
All Articles