用Pytorch实现一个线性回归
文章目录
- 问题描述
- 代码与注释
- 总结
- 参考资料
问题描述
假设学生在期末考试中,如果他们花x个小时在一门课程上,他们将得到y分。
x (hours) | y (points) |
---|---|
1 | 2 |
2 | 4 |
3 | 6 |
4 | ? |
问题是在这门课上花费4个小时时,得到的分数是多少?
很显然这是一个回归的问题。
下面结局这个问题的方法,是机器学习训练任务的基本方法论,可以基于此构建出更为复杂的模型去处理更为复杂的任务。
代码与注释
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): #将模型构建成一个类,并且继承自Moudle
def __init__(self): #构造函数
super(LinearModel, self).__init__() #调用父类的构造,固定写法,这一步必须要有
self.linear = torch.nn.Linear(1, 1) #Linear是一个类,类后面加括号意思是构建了一个对象,括号里面是的参数是权重和偏置
def forward(self, x): #前向传播函数
y_pred = self.linear(x) #在一个对象的后面加括号,实现了一个可调用的对象,x送入Linear对象,执行w * x + b
return y_pred
model = LinearModel()
# 损失函数,将向量里的损失进行求和,得到一个标量的损失值,MSELoss也继承自nn.Moudle
criterion = torch.nn.MSELoss(size_average=False)
# 优化器,不继承自Moudle,不会构建计算图,构建出的优化器知道要对哪些参数做优化,并且知道学习率
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
# 训练
for epoch in range(100):
y_pred = model(x_data) #先计算y_hat
loss = criterion(y_pred, y_data) #计算损失
print(epoch, loss) #loss是一个标量,一个对象,会自动调用__str__()函数,不会产生计算图,是安全的
optimizer.zero_grad() #梯度归0
loss.backward() #反向传播
optimizer.step() #step()用来做更新,根据预先设置的参数以及包含的梯度和学习率自动进行更新
# 输出 weight 和 bias
print('w = ', model.linear.weight.item()) #weight是一个矩阵,加上.item()让其只显示数值
print('b = ', model.linear.bias.item())
# Test Model
x_test = torch.Tensor([[4.0]])
y_test = model(x_test)
print('y_pred = ', y_test.data)
训练结果:
可以看到,通过不断的迭代,参数中的weight趋近于2,b趋近于0,最终的预测值趋近于8。
上面用的nn.Linear
是一个线性模型,如下图所示:
总结
对于一个模型,都要将其构建成一个类,并且继承自Module,至少定义两个方法,一个是构造函数__init__(self)
,另一个是forward()
。而backward会由Module里自动根据计算图计算。
对于整个训练搭建和训练的的步骤,总结为以下四步:
- Prepare dataset
- Design model using Class
- Construct loss and optimizer
- Training cycle
然后就是不断的前馈—反馈—更新----前馈—反馈—更新最后使Loss收敛。
参考资料
[1] https://www.bilibili.com/video/BV1Y7411d7Ys?p=5