tastynoob
Articles58
Tags18
Categories7
简单讲解反向传播算法

简单讲解反向传播算法

简单讲解反向传播算法

反向传播算法在神经网络中站很大的地位,大多数神经网络都能用反向传播算法进行训练,

但不少初学者不容易弄懂其中的具体公式(比如说我),所以讲解公式很有必要

(这里不讲前向传播,可自行寻找相关信息)

首先先规定一些宏:

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);
}

至此,反向传播的大致公式就完了,具体数学原理可自行查询(资料挺多的,应该不用担心)

Author:tastynoob
Link:https://tastynoob.github.io/2020/04/27/%E7%AE%97%E6%B3%95/%E7%AE%80%E5%8D%95%E8%AE%B2%E8%A7%A3%E5%8F%8D%E5%90%91%E4%BC%A0%E6%92%AD%E7%AE%97%E6%B3%95/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可
×