课程链接PyTorch深度学习实践第五节课程。
go go go~!
首先回忆一下深度学习熟悉的配方,老四样:
1、prepare dataset
2、design model using Class # 目的是为了前向传播forward,即计算y_pred(预测值)
3、Construct loss and optimizer (using PyTorch API) 其中,计算loss是为了进行反向传播,optimizer是为了更新梯度。
4、Training cycle (forward,backward,update)
所以见下面代码亦如此
import torch
# 1、prepare dataset
# x,y是矩阵,3行1列 也就是说总共有3个数据,每个数据只有1个特征
x_data = torch.Tensor([[1.0], [2.0], [3.0]])
y_data = torch.Tensor([[2.0], [4.0], [6.0]])
# 2、design model using class
"""
our model class inherits from nn.Module, (torch.nn.Linear类来自torch.nn.Module组件)which is base class for all neural network modules.
member methods __init__() and forward() have been implemented.
class nn.linear contains two member Tensors: weight and bias 构造了一个Linear Unit单元模块
class nn.Linear has implemented the magic method __call__(), which enable the instance of the class can be called just like a function.
"""
class LinearModel(torch.nn.Module):
def __init__(self):
super(LinearModel, self).__init__()
# (1,1)是指输入x和输出y的特征维度,这里数据集中的x和y的特征都是1维的
# 该线性层需要学习的参数是w和b 获取w/b的方式分别是~linear.weight/linear.bias
self.linear = torch.nn.Linear(1, 1)
def forward(self, x):
y_pred = self.linear(x)
return y_pred
model = LinearModel()
# 3、construct loss and optimizer
# criterion = torch.nn.MSELoss(size_average = False)
criterion = torch.nn.MSELoss(reduction = 'sum')
optimizer = torch.optim.SGD(model.parameters(), lr = 0.01) # model.parameters()自动完成参数的初始化操作
# 4、training cycle forward, backward, update
for epoch in range(100):
y_pred = model(x_data) # forward:predict
loss = criterion(y_pred, y_data) # forward: loss
print(epoch, loss.item())
optimizer.zero_grad() # the grad computer by .backward() will be accumulated. so before backward, remember set the grad to zero
loss.backward() # backward: autograd,自动计算梯度
optimizer.step() # update 参数,即更新w和b的值
print('w = ', model.linear.weight.item())
print('b = ', model.linear.bias.item())
x_test = torch.Tensor([[4.0]])
y_test = model(x_test)
print('y_pred = ', y_test.data)
w = 1.9610201120376587
b = 0.08861050754785538
y_pred = tensor([[7.9327]])
1、魔法函数_call_ :要想让一个class类 能够像函数一样被调用(实例化),需要在class中加_call_。"class LinearModel(torch.nn.Module): " 实现了魔法函数_call_(),_call()_里面有一条语句是要调用forward()。因此新写的类中需要重写forward()覆盖掉父类中的forward()。
2、_call_函数的另一个作用是可以直接在对象后面加(),例如实例化的model对象,实例化的linear对象。
3、本算法的forward体现是通过以下语句实现的:
y_pred = model(x_data)
由于魔法函数_call_的实现,model(x_data)将会调用model.forward(x_data)函数,model.forward(x_data)函数中的
y_pred = self.linear(x)
将会调用torch.nn.Linear类中的forward,至此完成封装,也就是说forward最终是在torch.nn.Linear类中实现的,具体怎么实现,可以不用关心,大概就是y= wx + b。
self.linear = torch.nn.Linear(1, 1)
(1,1)是指输入x和输出y的特征维度,这里数据集中的x和y的特征都是1维的,以后的练习中都要注意数据维度,这很重要。(第七讲)
4、本算法的反向传播,计算梯度是通过以下语句实现的:
loss.backward() # 反向传播,计算梯度
5、本算法的参数(w,b)更新,是通过以下语句实现的:
optimizer.step() # update 参数,即更新w和b的值 不用再像前面两节课自己更新w.data了。
6、 本实例是批量数据处理,小伙伴们不要被optimizer = torch.optim.SGD(model.parameters(), lr = 0.01)误导了,以为见了SGD就是随机梯度下降,要看传进来的数据是单个的还是批量的。这里的x_data是3个数据,是所有训练样本作为一个batch,调用的PyTorch API 是torch.optim.SGD,但这里的SGD不是随机梯度下降,而是批量梯度下降。梯度下降算法使用的是随机梯度下降,还是批量梯度下降,还是mini-batch梯度下降,用的API都是torch.optim.SGD。
每一步都需要使用模型和当前的一组内部参数对一些样本进行预测,将预测与实际预期结果进行比较,计算误差,并使用误差更新内部模型参数。该更新过程对于不同的算法是不同的,但是在人工神经网络的情况下,使用反向传播更新算法。
7、每一次epoch的训练过程,总结就是
①前向传播,求y_pred (输入的预测值)
②根据y_pred和y_data计算loss
③反向传播 loss.backward() (计算梯度)
④根据梯度,更新参数optimizer.step()
by 小李
如果你坚持到这里了,请一定不要停,山顶的景色更迷人!好戏还在后面呢。加油!
欢迎交流学习和批评指正,你的点赞和留言将会是我更新的动力!谢谢