先上公式:
//Forward:一层一层向输出层方向算
void Net::forward()
{
for (int i = 0; i < layer_neuron_num.size() - 1; ++i)
{
cv::Mat product = weights[i] * layer[i] + bias[i];//线性运算
layer[i + 1] = activationFunction(product, activation_function);激活函数的非线性运算
}
calcLoss(layer[layer.size() - 1], target, output_error, loss);
}
//Backward:一层一层往输入层方向算
void Net::backward()
{
//move this function to the end of the forward().
//calcLoss(layer[layer.size() - 1], target, output_error, loss);
deltaError();
updateWeights();
}
//Compute delta error
void Net::deltaError()
{
delta_err.resize(layer.size() - 1);
for (int i = delta_err.size() - 1; i >= 0; i--)//一层一层往输入层方向算
{
delta_err[i].create(layer[i + 1].size(), layer[i + 1].type());
//cv::Mat dx = layer[i+1].mul(1 - layer[i+1]);
cv::Mat dx = derivativeFunction(layer[i + 1], activation_function);
//计算输出层delta error
if (i == delta_err.size() - 1)
{
delta_err[i] = dx.mul(output_error);//激活函数导数乘output_error
}
else //计算隐藏层delta error
{
cv::Mat weight = weights[i];
cv::Mat weight_t = weights[i].t();
cv::Mat delta_err_1 = delta_err[i];
delta_err[i] = dx.mul((weights[i + 1]).t() * delta_err[i + 1]);//注意i层和i+1层的关系
}
}
}
//更新weights和bias
void Net::updateWeights()
{
for (int i = 0; i < weights.size(); ++i)
{
cv::Mat delta_weights = learning_rate * (delta_err[i] * layer[i].t());
cv::Mat delta_bias = learning_rate*delta_err[i];
weights[i] = weights[i] + delta_weights;
bias[i] = bias[i] + delta_bias;
}
}
代码出处