1.梯度下降
用于优化问题,在二元函数时可用导数求梯度,在多元函数时可用偏导求梯度,根据负梯度方向更新模型参数
2.反向传播
即误差反向传播
首先向前传播,计算输出,而后计算输出值和预测值之间的误差,将误差反向传播到每一层,计算每个参数对误差的影响(用相应参数对损失函数求偏导,局部梯度),用学习率控制“下山”步幅,更新网络中的参数,重复迭代,直至达到期望效果或达到最大迭代次数。
3.计算图
该图中,非叶子节点通常表示神经元或操作,而叶子节点则通常表示网络中的参数或输入数据。箭头正向表示输入求输出,反向可沿着路径求每个节点的梯度,并使用梯度下降算法来更新神经网络的参数。
4.使用Numpy编程实现例题
使用PPT中给定输入值、权重、真实值:
1、实现一次更新:结果见下:学习率为1
2、将正向计算和反向传播均用封装成函数,学习率仍为1,实现五次反向传播以调参,结果见下,由每次求得的均方误差可看出,预测结果于实际结果差距越来越小
=====输入值:x1, x2;真实输出值:y1, y2=====
0.5 0.3 0.23 -0.07
=====更新前的权值=====
0.2 -0.4 0.5 0.6 0.1 -0.5 -0.3 0.8
正向计算:h1, h2, o1 ,o2
0.56 0.5 0.48 0.53
损失函数:均方误差
0.21
反向传播:误差传给每个权值
0.01 0.01 0.01 0.01 0.03 0.08 0.03 0.07
第1轮更新后的权值
0.19 -0.41 0.49 0.59 0.07 -0.58 -0.33 0.73
=====第2轮=====
正向计算:h1, h2, o1 ,o2
0.56 0.49 0.47 0.51
损失函数:均方误差
0.2
反向传播:误差传给每个权值
0.01 0.01 0.01 0.01 0.03 0.08 0.03 0.07
=====第3轮=====
正向计算:h1, h2, o1 ,o2
0.56 0.49 0.46 0.49
损失函数:均方误差
0.18
反向传播:误差传给每个权值
0.01 0.01 0.01 0.01 0.03 0.08 0.03 0.07
=====第4轮=====
正向计算:h1, h2, o1 ,o2
0.56 0.49 0.45 0.47
损失函数:均方误差
0.17
反向传播:误差传给每个权值
0.01 0.01 0.01 0.01 0.03 0.07 0.03 0.07
=====第5轮=====
正向计算:h1, h2, o1 ,o2
0.55 0.49 0.45 0.45
损失函数:均方误差
0.16
反向传播:误差传给每个权值
0.01 0.01 0.01 0.01 0.03 0.07 0.03 0.06
=====第6轮=====
正向计算:h1, h2, o1 ,o2
0.55 0.48 0.44 0.43
损失函数:均方误差
0.15
更新后的权值
0.13 -0.46 0.46 0.56 -0.06 -0.89 -0.44 0.46
3、在2的基础上,将学习率由1变成50,step=50,结果见下:
可看出经过一次反向传播调参,均方误差从0.21到0.01后,剩余几次均方误差不改变,还是0.01,且除了第一次反向求误差外,其余次数得到误差结果均为0,可见开始时,收敛很快,后来就保持不变。学习率在开始时是较为合适的,但是快到“山底”时应该减小学习率。
=====输入值:x1, x2;真实输出值:y1, y2=====
0.5 0.3 0.23 -0.07
=====更新前的权值=====
0.2 -0.4 0.5 0.6 0.1 -0.5 -0.3 0.8
正向计算:o1 ,o2
0.48 0.53
损失函数:均方误差
0.21
反向传播:误差传给每个权值
0.01 0.01 0.01 0.01 0.03 0.08 0.03 0.07
第1轮更新后的权值
-0.53 -1.05 0.06 0.21 -1.63 -4.69 -1.82 -2.89
=====第2轮=====
正向计算:o1 ,o2
0.19 0.04
损失函数:均方误差
0.01
反向传播:误差传给每个权值
-0.0 -0.0 -0.0 -0.0 -0.0 0.0 -0.0 0.0
=====第3轮=====
正向计算:o1 ,o2
0.21 0.04
损失函数:均方误差
0.01
反向传播:误差传给每个权值
0.0 0.0 0.0 0.0 -0.0 0.0 -0.0 0.0
=====第4轮=====
正向计算:o1 ,o2
0.22 0.03
损失函数:均方误差
0.01
反向传播:误差传给每个权值
0.0 0.0 0.0 0.0 -0.0 0.0 -0.0 0.0
=====第5轮=====
正向计算:o1 ,o2
0.23 0.03
损失函数:均方误差
0.01
反向传播:误差传给每个权值
0.0 0.0 0.0 0.0 -0.0 0.0 -0.0 0.0
=====第6轮=====
正向计算:o1 ,o2
0.23 0.03
损失函数:均方误差
0.01
更新后的权值
-0.54 -1.06 0.06 0.2 -1.38 -5.02 -1.6 -3.18
4、学习率变为5,训练1000次,最后部分结果见下:
由结果可观察到:开始时调参幅度大,后来越来越小,结果逐渐收敛,且最终训练效果为均方误差0.00316。学习率为5虽然没有50开始训练结果明显,但是一直在靠近想要的结果,而50的学习率不能使结果收敛,所以学习率为5比为50合适。
5、最终学习率为10,迭代次数设为10,绘制一条能看出训练收敛效果的图,图中横坐标表示训练次数,纵坐标表示均方误差,见下:
5.使用PyTorch的Backward()编程实现例题
以下代码实现训练了1000次,学习率为0.1
import torch
# 设置随机数种子以便复现结果
torch.manual_seed(0)
# 定义神经网络模型
class Net(torch.nn.Module):
def __init__(self):
super(Net, self).__init__()
# 定义各层的结构
self.hidden = torch.nn.Linear(2, 2)
self.output = torch.nn.Linear(2, 1)
self.sigmoid = torch.nn.Sigmoid()
def forward(self, x):
# 前向传播计算预测值
x = self.hidden(x)
x = self.sigmoid(x)
x = self.output(x)
x = self.sigmoid(x)
return x
# 创建神经网络模型
net = Net()
# 定义损失函数
criterion = torch.nn.MSELoss()
# 定义优化器
optimizer = torch.optim.SGD(net.parameters(), lr=0.1)
# 定义输入和目标张量
x = torch.tensor([0.5, 0.3])
target = torch.tensor([0.23])
# 训练神经网络
for epoch in range(1000):
# 梯度清零
optimizer.zero_grad()
# 前向传播计算预测值
y = net(x)
# 计算损失函数
loss = criterion(y, target)
# 反向传播计算梯度
loss.backward()
# 更新权值
optimizer.step()
# 打印训练结果
print(net(x))
结果为:
参考:
人工智能:模型与算法_浙江大学_中国大学MOOC(慕课) (icourse163.org)
【人工智能导论:模型与算法】MOOC 8.3 误差后向传播(BP) 例题 编程验证
一文解释 PyTorch求导相关 (backward, autograd.grad) - 知乎 (zhihu.com)