简单讲解反向传播算法
简单讲解反向传播算法
反向传播算法在神经网络中站很大的地位,大多数神经网络都能用反向传播算法进行训练,
但不少初学者不容易弄懂其中的具体公式(比如说我),所以讲解公式很有必要
(这里不讲前向传播,可自行寻找相关信息)
首先先规定一些宏:
1 2 3 4 5 6 7 8 9 10 11 12 13
| LS:神经网络的层数 NF(n):神经网络第n层的神经元个数 BF(n,a):神经网络第n层第a个神经元的偏置(输入层没有偏置) WF(n,a,p):神经网络第n层第a个神经元的第p个权重(输入层没有权重) NETF(n,a):神经网络第n层第a个神经元的加权和(wx+b) OF(n,a):神经网络的第n层第a个神经元的输出(不包括输入层,OF可有可无,有点话使用某些激活函数可方便计算) SF(n,a):神经网络的第n层第a个神经元的误差 INF(n):神经网络的第n个输入 OUTF(n):神经网络的第n个实际输出(即输出层第n个输出) TAF(n):神经网络的第n个理想输出(即样本输出) LN:学习率 F(x):激活函数函数 F_(x):激活函数的导函数
|
注意:
在进行反向传播之前,首先需要先前向传播一次,计算好各个层的(加权和)和输出
首先是计算输入层的误差(为了更加容易理解,这里用文字和符号表述):
1 2 3
| SF(LS,1) = (2.0/NF(LS))*(OUTF(1) - TAF(1)) 输出层第1个神经元的误差 = (2.0/输出层神经元数量)*(实际第1个输出-理想第1个输出),以此类推 ps:注意这里是浮点数2.0不是整数2
|
更新输入层的权重和偏置:
1 2 3 4 5 6 7 8 9 10
| BF(LS,1) = BF(LS,1) - LN * SF(LS,1) 更新后的输出层第1个偏置 = 原偏置 - 学习率*输出层第1个误差,以此类推 WF(LS,1,2) = WF(LS,1,2) - LN * SF(LS,1) * OF(LS-1,2); 更新后的输出层第1个神经元的第2个权重 = 原权重 - 学习率 * 输出层第1个误差 * 上一层第2个输出
作为参照: WF(n,1,4) = WF(n,1,4) - LN * SF(n+1,4) * OF(n,4); 更新后的第n层第1个神经元的第4个权重 = 原权重 - 学习率 * 下一层层第4个误差 * 第n层第1个输出 以此类推
|
然后是隐藏层的误差:
1 2 3 4 5 6 7 8 9 10
| SF(n,4) = SF(n+1,1)*WF(n,4,1)*F_(NETF(n,4)) + SF(n+1,2)*WF(n,4,2)*F_(NETF(n,4)) + SF(n+1,3)*WF(n,4,3)*F_(NETF(n,4)) + ........... 第n层第4个神经元的误差 = 下一层第1个神经元的误差 * 第n层第4个神经元第1个权重 * 第n层的第4个神经元的导函数输出 + 下一层第2个神经元的误差 * 第n层第4个神经元第2个权重 * 第n层的第4个神经元的导函数输出 + 下一层第3个神经元的误差 * 第n层第4个神经元第3个权重 * 第n层的第4个神经元的导函数输出+ ........ ps:这里之所以用计算第n层第4个神经元的误差做例,是为了更好的理解 实际上就是个数学表达式: 第n层的误差数组 = (下一层的误差数组*第n层的权重矩阵)*第n层的加权和的导数数组
|
隐藏层的误差计算 , 权重和偏置的更新与输出层一样,这里就不加赘述了
由于输入层只有输入,所以没有误差
总之,神经网络搭建完后,就可以开始训练了,导入样本,然后开始前向传播一次,反向传播一次,反复计算
其中需要计算总误差:
1 2 3 4
| double val = 0; for (int a = 1; a <= NF(LS); a++) { val += ((OF(LS, a) - TAF(a)) * (OF(LS, a) - TAF(a))) / NF(LS); }
|
至此,反向传播的大致公式就完了,具体数学原理可自行查询(资料挺多的,应该不用担心)