使用Pytorch实现线性回归
基本步骤:
- 准备数据集
- 设计模型
- 构造损失函数和优化器
- 模型训练
forward
计算损失backward
计算梯度update
更新参数
准备数据集
[ y p r e d ( 1 ) y p r e d ( 2 ) y p r e d ( 3 ) ] = ω [ x ( 1 ) x ( 2 ) x ( 3 ) ] + b \begin {bmatrix}y_{pred}^{(1)} \\ y_{pred}^{(2)} \\ y_{pred}^{(3)} \end{bmatrix} =\omega \begin {bmatrix}x^{(1)} \\ x^{(2)} \\ x^{(3)} \end{bmatrix} + b ypred(1)ypred(2)ypred(3) =ω x(1)x(2)x(3) +b
python
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 z = wx + b z=wx+b
需要确定的是 w w w 和 b b b 的维度大小,即要通过输入和输出的维度来确定权重的维度
必须注意的是 l o s s loss loss一定要是一个标量
一般而言,会把模型设计成类
python
class LinearModel(torch.nn.Module): #继承自Module
def __init__(self): #构造函数
super(LinearModel, self).__init__() # 调用负类的构造
self.linear = torch.nn.Linear(1, 1) # 构造Linear对象 包含权重和偏置
def forward(self, x):
y_pred = self.linear(x)
return y_pred
model = LinearModel() # 实例化LinearModel()对象
torch.nn.Linear(in_features, out_features, bias=True)
参数:
in_features
输入的每一个样本的维度out_features
输出的每一个样本的维度bias
是否需要添加偏置,默认为True
forward()
方法中y_pred = self.linear(x)
调用的是了python中的__call__
函数。在Pytorch的Module.__call__()
中有一个重要的语句就是forward()
,也就是说,在这里我们必须写forward()
来去覆盖
定义损失函数和优化器
损失函数
损失函数使用MSE
python
criterion = torch.nn.MSELoss(size_average=False)
参数设置:
size_average
,是否对损失求平均,默认为True
reduce
,用来确定是否要把损失求和降维(特征降维)
一般而言,只考虑size_average
优化器
使用梯度下降
python
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
参数设置:
params
,传入模型需要优化的权重lr
,学习率
模型训练
训练100次,主要是三个步骤
- 前馈计算
- 反向传播
- 梯度更新
注意不要忘记梯度清零
python
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() # 参数更新
## 损失数据可视化
plt.plot(np.arange(100), loss_history)
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()
## 打印训练后的参数
print("w = ", model.linear.weight.item())
print("b = ", model.linear.bias.item())
模型测试
python
x_test = torch.tensor([[4.0]])
y_test = model(x_test)
print("y_pred = ", y_test.item())
测试结果如下
整体代码
python
import torch
import matplotlib.pyplot as plt
import numpy as np
## 注意x和y的值必须是矩阵
x_data = torch.tensor([[1.0], [2.0], [3.0]])
y_data = torch.tensor([[2.0], [4.0], [6.0]])
loss_history = []
########## 模型的定义 ##########
class LinearModel(torch.nn.Module): #继承自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() # 实例化Linear()对象
########## 定义损失函数和优化器 ##########
## 损失函数
criterion = torch.nn.MSELoss(size_average=False)
## 优化器
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
########## 模型训练 ##########
for epoch in range(100):
y_pred = model(x_data) # 前馈计算
loss = criterion(y_pred, y_data) # 计算损失
print(epoch, loss)
loss_history.append(loss.item())
optimizer.zero_grad() # 梯度清零
loss.backward() # 反向传播
optimizer.step() # 参数更新
## 损失数据可视化
plt.plot(np.arange(100), loss_history)
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()
## 打印训练后的参数
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.item())