MCPcopy Create free account
hub / github.com/FidoProject/Fido / getGradients

Method getGradients

src/NeuralNet.cpp:149–212  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

147}
148
149std::vector< std::vector< std::vector<double> > > NeuralNet::getGradients(const std::vector<double> &input, const std::vector<double> &correctOutput) {
150 std::vector< std::vector<double> > outputs = feedForward(input);
151 std::vector< std::vector< std::vector<double> > > weights = getWeights3D();
152 std::vector< std::vector<double> > errors;
153 ActivationFunction hiddenActivationFunctionDerivative = Layer::getDerivedActivationFunctionNames()[getHiddenActivationFunctionName()];
154 ActivationFunction outputActivationFunctionDerivative = Layer::getDerivedActivationFunctionNames()[getOutputActivationFunctionName()];
155
156 // Compute output layer error
157 std::vector<double> outputNeuronErrors;
158 std::vector<double> outputLayerOutput = outputs[outputs.size() - 1];
159 for(unsigned int neuronIndex = 0; neuronIndex < outputLayerOutput.size(); neuronIndex++) {
160 double outputNeuronError = (correctOutput[neuronIndex] - outputLayerOutput[neuronIndex]) * outputActivationFunctionDerivative(outputLayerOutput[neuronIndex]);
161 outputNeuronErrors.push_back(outputNeuronError);
162 }
163 errors.push_back(outputNeuronErrors);
164
165 // Compute hidden layer error
166 for(int layerIndex = net.size() - 2; layerIndex >= 0; layerIndex--) {
167 std::vector<double> currentLayerError;
168 const std::vector<double> &currentHiddenLayerOutput = outputs[layerIndex];
169 const std::vector<double> &lastLayerError = errors[errors.size() - 1];
170 const std::vector< std::vector<double> > &lastLayerWeights = weights[layerIndex + 1];
171
172 for(unsigned int neuronIndex = 0; neuronIndex < net[layerIndex].neurons.size(); neuronIndex++) {
173 double errorsTimesWeights = 0;
174 for(unsigned int previousNeuronIndex = 0; previousNeuronIndex < lastLayerError.size(); previousNeuronIndex++) {
175 errorsTimesWeights += lastLayerError[previousNeuronIndex] * lastLayerWeights[previousNeuronIndex][neuronIndex];
176 }
177 double hiddenNeuronError = hiddenActivationFunctionDerivative(currentHiddenLayerOutput[neuronIndex]) * errorsTimesWeights;
178 currentLayerError.push_back(hiddenNeuronError);
179 }
180 errors.push_back(currentLayerError);
181 }
182
183 // Compute gradients
184 std::vector< std::vector< std::vector<double> > > gradients(weights.size());
185 for(unsigned int errorIndex = 0; errorIndex < errors.size(); errorIndex++) {
186 int layerIndex = ((int)errors.size() - 1) - errorIndex;
187 std::vector< std::vector<double> > layerGradient;
188
189 for(unsigned int neuronIndex = 0; neuronIndex < errors[errorIndex].size(); neuronIndex++) {
190 std::vector<double> neuronGradient;
191
192 if(layerIndex == 0) {
193 for(unsigned int inputIndex = 0; inputIndex < input.size(); inputIndex++) {
194 neuronGradient.push_back(errors[errorIndex][neuronIndex] * input[inputIndex]);
195 }
196 } else {
197 for(unsigned int previousOutput = 0; previousOutput < outputs[layerIndex - 1].size(); previousOutput++) {
198 neuronGradient.push_back(errors[errorIndex][neuronIndex] * outputs[layerIndex - 1][previousOutput]);
199 }
200 }
201
202 // Activation weight gradient
203 neuronGradient.push_back(-errors[errorIndex][neuronIndex]);
204
205 layerGradient.push_back(neuronGradient);
206 }

Callers 2

trainOnDataPointMethod · 0.45
pruneMethod · 0.45

Calls 1

sizeMethod · 0.45

Tested by

no test coverage detected