0、问题
使用pytorch实现正向传播与反向传播算法
1、预先知识学习
1、pytorch数据结构-Tensor
参考自:https://zhuanlan.zhihu.com/p/48982978
在深度学习中,Tensor实际上就是一个多维数组(multidimensional array),其目的是能够创造更高维度的矩阵、向量
Tensor中存储两个元素,一个是w(权重的值)、一个是损失函数对权重的偏导数
3、反向传播过程
先进行前向传播,计算结果
反向传播:最终是要计算损失函数L对权重w的导数
以便使用梯度下降算法进行更新w
2、代码
1、构建数据集
import torch
x_data = [1.0,2.0,3.0]
y_data = [2.0,4.0,6.0]
w = torch.tensor([1.0])
#注意,需要计算梯度的时候加上此步骤
w.requires_grad = True
注意,我们需要计算w对于loss的偏导数,所以要加上使用梯度的那一步
2、构建前向传播
#前向传播
def forword(x):
return x*w
此处,因为w是Tensor类型的,所以x会进行自动类型转换,转换为Tensor类型
相当于构件出这样一幅图:
此处:因为传入的w是需要计算梯度的,所以默认结果也需要计算梯度
3、构建损失函数
#损失函数
def loss(x,y):
y_pred = forword(x)
return (y_pred-y)**2
#注意此处**2的表示方法
#此时,返回值也是Tensor类型
4、进行训练
print("predict (before training)",4,forword(4).item())
#训练网络,计算backward
for epoch in range(100):
for x,y in zip(x_data,y_data):
l = loss(x,y)
l.backward()
print('\t梯度:',x,y,w.grad.item())
w.data = w.data - 0.01 * w.grad.data
#注意,此处运算要使用Tensor中的data进行纯数值运算,如果使用Tensor数据结构其也还会构建一张图,保留grad梯度值,会吃内存
w.grad.zero_()
#将w中全部梯度的数据清零,如果不清零,梯度值会不断的对下次更新的l进行相加
print("progress:",epoch,l.item())
print("predict (after training)",4,forword(4).item())
l.backward()的过程实际上是进行偏导数计算,计算loss对w的偏导数,即为梯度下降的梯度
然后使用梯度下降算法对w进行更新,注意,更新的时候所有元素都要去Tensor中的data,即只进行纯数值更新,不记录其梯度
※注意,更新完成之后,要对梯度值进行清空,如果清空,下一次进行梯度值计算的时候会累加到上次的结果上
问题:
?学习率与循环次数如何进行选择
?为什么最后w已经更新成2了,还是会有误差值,虽然很小loss也一直在变?
从32次的时候就已经训练成2了
在第50次的时候梯度平稳不变,loss也不再改变
好像最终训练完了,结果也不是8:
predict (after training) 4 7.999998569488525