赞
踩
注:了解计算图的同学可直接跳过。
无论在pytorch还是在tensorflow中,都是用计算图来计算前馈和反向传播过程。我们首先来介绍一个简单的计算图:
如上图所示,表示了y’ = w * x的前馈计算 r = y’ - y 为标准差 loss = r ^ 2 为均方误差 其中w的初始值随机设置为1,x = 1, y=2(实际值) 通过表达式计算得到的y’是预测值。
我们优化的目标函数就是loss,通过一步一步梯度下降得到loss的极小值(局部),那么我们需要得到的便是loss对w的求导结果(用来更新w.data),这就需要**反向传播(backward)**来完成
如下图所示,通过求导的链式法则,可以计算得到loss对w的梯度值。
链式法则:
我们希望得到y对x的梯度,但是y到x中间还有一个u函数进行了复合运算,那么我们可以计算y对u的导数和u对x的导数,并将其乘积得到的结果就为y对x的求导结果。
如下图所示,通过正向的前馈运算我们得到y’和r以及loss的值,再从loss的值反向计算对r的梯度对y’的梯度以及对w的梯度(每一步中代入的具体数值就是前馈计算出的数值,所以前馈和反向缺一不可)。
以上就是pytorch有关计算图、反向传播的大体流程,了解了这些之后我们便可以开始线性回归之旅。
1.准备数据集
2.设计模型
3.构造损失函数和优化器(利用pytorch API)
4.训练周期(前馈算损失、反馈算梯度、更新权重)
若有三个样本(x1, y1)(x2, y2)(x3, y3) 分别为(1, 2)(2, 4)(3, 6)
w和b都会进行广播
则,损失的表达形式为:
在构造初始数据时,x和y必须是(3, 1)的矩阵的形式(也可看作列向量)
import torch
#注意x和y都是列向量,一个中括号代表一行,放入一个数据
x_data = torch.Tensor([[1.0], [2.0], [3.0]])
y_data = torch.Tensor([[2.0], [4.0], [6.0]])
使用pytorch时,我们的重点不在求导,而在于构造计算图
其中z = w * x + b为仿射函数,又叫做线性单元
需要确定x和y的维度,即可确定w的维度。将计算得到的y放入loss函数,并对得到的loss进行反向传播
若计算得到的loss为一个向量,需要将其转化为标量,做法为:将所有loss求和取平均值(也可以只加和不求均值)。
将我们的模型构造为一个类(都要继承自module):
class LinearModel(torch.nn.Module): #从Module继承
#必须实现以下两个函数
#初始化
def __init__(self):
super(LinearModel, self).__init__() #调用父类的初始化
self.linear = torch.nn.Linear(1, 1) #构造一个对象,包含权重和偏置
#Linear的参数为,输入的维度(特征数量,不是样本数量)和输出的维度,以及是否有偏置(默认为True)
#前馈过程中进行的计算
def forward(self, x): #这里实际上是一个override
y_pred = self.linear(x) #在这里计算w * x + b 线性模型
return y_pred
#不需要自己写反馈
model = LinearModel() #这里的model是callable可调用的 调用方法为:model(x)
criterion = torch.nn.MSELoss(size_average=False) #是否要求均值
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
#优化器不会构建计算图, 在这里需要告诉优化器对那些Tensor进行梯度下降
#model.parameters()函数会检查模型中的成员变量,将成员变量里相应的权重加入训练的结果中
SGD的参数如下:
前馈算y’、损失、梯度归零、反向传播、自动更新
for epoch in range(100):
y_pred = model(x_data)
loss = criterion(y_pred, y_data)
print(epoch, loss)
optimizer.zero_grad() #梯度归零
loss.backward()
optimizer.step() #根据梯度和预先设置的学习率自动更新
#输出权重和偏置
print('w = ', model.linear.weight.item())
#weight是一个矩阵,需要显示数值用item()
print('b = ', model.linear.bias.item())
#测试
x_test =torch.Tensor([[4.0]]) #(1, 1)矩阵
y_test = model(x_test)
print('y_pred = ', y_test.data) #(1, 1)矩阵
注:将所有部分代码整合在一起即可运行
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。