05 Linear Regression

Design Model

基本过程

  1. 准备数据集
  2. 通过继承nn.Module来设计模型
  3. 构造损失函数和优化器
  4. 训练周期(这里设定1000个周期)
      a. 前馈计算\(\hat{y}\)
      b. 计算损失
      c. 反向传播
      d. 更新

代码实现

import torch

# 准备数据集
x_data = torch.Tensor([[1.0], [2.0], [3.0]])
y_data = torch.Tensor([[2.0], [4.0], [6.0]])

class LinearModule(torch.nn.Module):
    """
    首先要把模型定义为一个类, 定义的这个类都继承自Module父类
    这个类最少包含两个函数, 一个构造函数__init__()和一个forward()
    注意这里并没有单独做反馈的运算, 因为Module中会根据计算图自动实现Backward的过程
    """

    def __init__(self):
        # 构造函数, 初始化对象时默认调用的函数
        super(LinearModule, self).__init__() # 调用父类的构造函数, 必需
        self.linear = torch.nn.Linear(1, 1) # 类nn.Linear包含权重w和偏移b两个Tensor, 用这两个参数构造对象
        '''linear由Linear实例化'''


    def forward(self, x):
        # 在前馈过程中所需要进行的运算
        y_pred = self.linear(x) # 做w*x+b的运算
        return y_pred

model = LinearModule()

criterion = torch.nn.MSELoss(size_average=False) # 利用MSE(继承自nn.Module, 会构建计算图)构造损失函数, 这里设定不求均值
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
"""
构造优化器, 实例化SGD类.
参数一的parameter函数会检查model的所有成员, 如果成员中有相应的权重就将其找出来
参数二设定学习率
"""

for epoch in range(1000):
    y_pred = model(x_data) # 将x_data送入model计算$\hat{y}$
    loss = criterion(y_pred, y_data) # 计算损失
    print(epoch, loss) # loss是一个对象, print它时会自动调用__str__(), 不会产生计算图

    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.item())

观察使用SGD优化器时的变化过程

import torch
import matplotlib.pyplot as plt

# 准备数据集
x_data = torch.Tensor([[1.0], [2.0], [3.0]])
y_data = torch.Tensor([[2.0], [4.0], [6.0]])

class LinearModule(torch.nn.Module):
    """
    首先要把模型定义为一个类, 定义的这个类都继承自Module父类
    这个类最少包含两个函数, 一个构造函数__init__()和一个forward()
    注意这里并没有单独做反馈的运算, 因为Module中会根据计算图自动实现Backward的过程
    """

    def __init__(self):
        # 构造函数, 初始化对象时默认调用的函数
        super(LinearModule, self).__init__() # 调用父类的构造函数, 必需
        self.linear = torch.nn.Linear(1, 1) # 类nn.Linear包含权重w和偏移b两个Tensor, 用这两个参数构造对象
        '''linear由Linear实例化'''


    def forward(self, x):
        # 在前馈过程中所需要进行的运算
        y_pred = self.linear(x) # 做w*x+b的运算
        return y_pred

model = LinearModule()

criterion = torch.nn.MSELoss(size_average=False) # 利用MSE(继承自nn.Module, 会构建计算图)构造损失函数, 这里设定不求均值
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
"""
构造优化器, 实例化SGD类.
参数一的parameter函数会检查model的所有成员, 如果成员中有相应的权重就将其找出来
参数二设定学习率
"""

epoch_list = []
loss_list = []

for epoch in range(1001):
    y_pred = model(x_data) # 将x_data送入model计算$\hat{y}$
    loss = criterion(y_pred, y_data) # 计算损失
    print(epoch, loss.item()) # loss是一个对象, print它时会自动调用__str__(), 不会产生计算图

    optimizer.zero_grad() # 由于计算完梯度后, 其值会不断积累, 因此需要将梯度归零
    loss.backward() # 反向传播
    optimizer.step() # 根据梯度和设定的学习率更新权重
    
    loss_list.append(loss.item())
    epoch_list.append(epoch)
    plt.plot(epoch_list, loss_list, color="green")
    plt.xlabel("epoch")
    plt.ylabel("loss value")
    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())
SGD
  1. 输出

w= 1.999812126159668
b= 0.000427166058216244
y_pred= 7.999675750732422

  1. 过程展示
Adagrad
  1. 输出

w= 1.305970549583435
b= 0.8834596276283264
y_pred= 6.107341766357422

  1. 过程展示
Adam
  1. 输出

w= 1.6004431247711182
b= 0.8861054182052612
y_pred= 7.287878036499023

  1. 过程展示
Adamax
  1. 输出

w= 1.6762775182724
b= 0.7182608246803284
y_pred= 7.423370838165283

  1. 过程展示

Reference

[1] https://www.bilibili.com/video/BV1Y7411d7Ys?p=5

posted @ 2020-08-30 15:15  vict0r  阅读(113)  评论(0编辑  收藏  举报