回顾
PyTorch Fashion
- Prepare dataset:准备数据
- 设计模型:计算forward的y hat(预测值)
- 建立损失函数和优化器:计算loss是为了进行反向传播,optimizer是为了更新梯度。
- 训练
Prepare dataset
x_data = torch.tensor([[1.0], [2.0], [3.0]])
y_data = torch.tensor([[2.0], [4.0], [6.0]])
当X,Y的维度确定后,权重w的维度也就是已知的。tensors和numpy一样,具有广播机制。
Design Model
class LinearModel(torch.nn.Module):
def __init__(self):
super(LinearModel, self).__init__()
self.linear = torch.nn.Linear(1, 1)
def forward(self, x):
y_pred = self.linear(x)
return y_pred
model = LinearModel()
代码说明:
- torch.nn.Module 父类,LinearModel子类。
- super() 是pyhton 中调用父类(超类)的一种方法,在子类中可以通过super()方法来调用父类的方法。这里时调用torch.nn.Module的LinearModel方法。
- (1,1)是指输入x和输出y的特征维度,这里数据集中的x和y的特征都是1维的
- Module实现了魔法函数call(),call()里面有一条语句是要调用forward()。因此新写的类中需要重写forward()覆盖掉父类中的forward()。call函数的另一个作用是可以直接在对象后面加(),例如实例化的model对象,和实例化的linear对象
- 本算法的forward体现是通过以下语句实现的:
y_pred = model(x_data)
由于魔法函数call的实现,model(x_data)将会调用model.forward(x_data)函数,model.forward(x_data)函数中的
y_pred = self.linear(x)
self.linear(x)也由于魔法函数call的实现将会调用torch.nn.Linear类中的forward,至此完成封装,也就是说forward最终是在torch.nn.Linear类中实现的,具体怎么实现,可以不用关心,大概就是y= wx + b。
Construct Loss and Optimizer
torch.nn.MSELoss也跟torch.nn.Module有关,参与计算图的构建,torch.optim.SGD与torch.nn.Module无关,不参与构建计算图
本实例是批量数据处理,不要被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。
criterion = torch.nn.MSELoss(reduction = 'sum')
optimizer = torch.optim.SGD(model.parameters(), lr = 0.01) # model.parameters()自动完成参数的初始化操作
Training Cycle
# 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() # 自动更新参数,即更新w和b的值
Test Model
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)
总结
import torch
# 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]])
#design model using class
"""
our model class should be inherit from nn.Module, which is base class for all neural network modules.
member methods __init__() and forward() have to be implemented
class nn.linear contain two member Tensors: weight and bias
class nn.Linear has implemented the magic method __call__(),which enable the instance of the class can
be called just like a function.Normally the forward() will be called
"""
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()
# 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()自动完成参数的初始化操作
# 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)
作业
import torch
x_data = torch.Tensor([[1.0],[2.0],[3.0]])
y_data = torch.Tensor([[2.0],[4.0],[6.0]])
class LinearModel(torch.nn.Module):
def __init__(self):#构造函数
super(LinearModel,self).__init__()
self.linear = torch.nn.Linear(1,1)#构造对象,并说明输入输出的维数,第三个参数默认为true,表示用到b
def forward(self, x):
y_pred = self.linear(x)#可调用对象,计算y=wx+b
return y_pred
model = LinearModel()#实例化模型
criterion = torch.nn.MSELoss(size_average=False)
#model.parameters()会扫描module中的所有成员,如果成员中有相应权重,那么都会将结果加到要训练的参数集合上
optimizer = torch.optim.Adagrad(model.parameters(),lr=0.01)#lr为学习率
loss_sum = []
for epoch in range(1000):
y_pred = model(x_data)
loss = criterion(y_pred,y_data)
print(epoch,loss.item())
loss_sum.append(loss.item())
optimizer.zero_grad()
loss.backward()
optimizer.step()
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)
import matplotlib.pyplot as plt
import numpy as np
plt.plot(np.arange(1000),loss_sum)
plt.ylabel('Loss')
plt.xlabel('epoch')
plt.title('Adagrad')
plt.show()
ps:只写了第一个作业~
参考
PyTorch 深度学习实践 第5讲_错错莫的博客-CSDN博客
PyTorch学习(四)--用PyTorch实现线性回归_陈同学爱吃方便面的博客-CSDN博客
深度学习05——线性回归模型_Top Secret的博客-CSDN博客
python 类中 super ()方法的使用 - 赏孤舟蓑笠 - 博客园 (cnblogs.com)
pytorch 之 call, init,forward
pytorch系列nn.Modlue中call的进一步解释