PyTorch深度学习——重建线性模型

一、建立线性模型过程

<1> Prepare dataset

构造一个简单的神经网络,准备Tensor类型的数据集。写成矩阵的形式,有利于后面forward()函数时用广播机制对数据的维度进行扩充。此处共有三条数据,每条数据只有一个特征,[1.0]表示第一行,[2.0]表示第二行,[3.0]表示第三行。

x_data = torch.Tensor([[1.0],[2.0],[3.0]]) 
y_data = torch.Tensor([[2.0],[4.0],[6.0]])

<2> Design model

  • 使用nn.Module类来自定义模型,PyTorch里面的自定义操作基本上都是继承nn.Modulel这个父类来实现的。自定义的时候必须重新实现__init__以构造函数并重写forward()函数。

    class Module(object):
    	# 1.构造函数
        def __init__(self):
        	...
        # 2.前向传播函数,计算y_hat(预测值)
        def forward(self, *input):
        	···
    
  • 通常会在__init__函数里定义各个层,而在forward()函数里定义各层之间的连接关系。例如下面的单层神经网络和三层神经网络:

    单层:

    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) #中间到输出(outputs)的关系
            return y_pred
    

    三层:

    class Model(torch.nn.Module):
        def __init__(self):
            super(Model, self).__init__()
            self.linear1 = torch.nn.Linear(9, 6) #三层神经网络,逐渐空间降维
            self.linear2 = torch.nn.Linear(6, 4)
            self.linear3 = torch.nn.Linear(4, 1)
            self.sigmoid = torch.nn.Sigmoid() #构造非线性变换函数   
        def forward(self, x):
        	#为了避免传错参数,统一用x来覆盖计算出来的值
            x = self.sigmoid(self.linear1(x)) #输入(inputs)与一层的关系
            x = self.sigmoid(self.linear2(x)) #一层与二层的关系
            x = self.sigmoid(self.linear3(x)) #二层与三层(outputs)的关系
            return x
    

    参考文章:pytorch教程之nn.Module类详解——使用Module类来自定义模型

<3> Construct loss and optimizer

  • 在PyTorch中,经常使用nn.MSELoss来作为损失函数,通常使用步骤如下:

    #1.构造损失函数
    criterion = torch.nn.MSELoss(size_average = True, reduce = True, reduction = 'sum'/'mean'/'None') #MSE类,会构造计算图,继承Module类
    
    #2.调用损失函数,传入参数为(y的预测值, y的原始值)
    loss = criterion(y_pred, y_data) #求损失loss
    
    #3.输出loss
    print(loss.item()) #如果reduction = 'None',输出的是向量
    print(loss) #如果reduction = 'sum'/'mean',输出的是标量
    
    #4.反向传播
    loss.backward() #因为MSELoss继承自nn.Module,所以会构造计算图
    

    其他损失函数参考文章: MSE、BCE、BCEWithLogits、NLLLoss、CrossEntropyLoss的用法

  • torch.optim是一个实现了各种优化算法的库,为了使用优化器,必须先构造一个optimizer对象,此处使用的是梯度下降算法,调用的PyTorch API是torch.optim.SGD,如下所示:

    optimizer = torch.optim.SGD(model.parameters(), lr = 0.01, momentum = 0.9) #不会构造计算图
    #model.parameters()会检查构建的神经网络中所有待更新的参数,如w,b
    

<4> Training cycle

  • 每一次epoch训练过程包括:
    1、求出y_pred,y_pred = model(x_data)
    2、根据y_predy_data求出损失loss;1,2两步相当于前向传播,并且构造计算图,存储子节点梯度
    3、每轮的反向传播前应该将梯度清零,避免梯度的累积optimizer.zero_grad()
    4、反向传播,求出所需梯度,loss.backward()
    5、参数更新,optimizer.step()
    for epoch in range(1000):
        y_pred = model(x_data) #使用了实例model,调用了前馈forward
        loss = criterion(y_pred, y_data) #求损失loss
        print(epoch, loss.item())
        
        optimizer.zero_grad() #梯度归零
        loss.backward() #反向传播
        optimizer.step() #更新
    
  • 关于魔法函数__call__()的作用
    1、如果在类中实现了 __call__ 方法,那么实例对象也将成为一个可调用对象(callable),例如本文中PyTorch在nn.Module中,实现了__call__方法,并且在__call__中调用了forward函数,所以实例model可以直接被调用:model(x_data)
    2、 例子:对象初始化为10后再通过调用函数a(5)给对象加5
    class A():
       def __init__(self, init_num):
           #构造函数,类实例化的时候要赋予一些基本的参数值
           super().__init__()
           print('----old number is ', init_num)
           self.num = init_num #赋值
       
       def __call__(self, add_num):
           #call函数里面调用forward()
           print('2> call函数被调用!')
           return self.forward(add_num)
       
       def forward(self, input):
           print('3> forward函数被调用!')
           print('4> input is:', input)
           return input + self.num
       
    a = A(10) #此时对类A进行实例化
    print('1> 初始化结束!') 
    output = a(5) #此时会直接调用call函数,call函数调用      
    print("----new number is ", output)
    
    In [1]:
    ----old number is  10
    1> 初始化结束!
    2> call函数被调用!
    3> forward函数被调用!
    4> input is: 5
    ----new number is  15
    
    参考文章:python class 中 的__call__方法

二、代码运行测试

完整代码:

import torch
import matplotlib.pyplot as plt

#1.Prepare training set
x_data = torch.Tensor([[1.0],[2.0],[3.0]])  #数据集是tensor,且写成矩阵的形式
y_data = torch.Tensor([[2.0],[4.0],[6.0]])

#2.Design model 构建计算图(使用线性模型)
class LinearModel(torch.nn.Module):
    def __init__(self):
        super(LinearModel, self).__init__()
        self.linear = torch.nn.Linear(1, 1)  #(in_features, out_features, bias = True)    
    def forward(self, x):
        y_pred = self.linear(x)  #self.linear是callable的,是可调用的对象
        return y_pred
    
model = LinearModel()   #创建类的实例
    
#3.Construct Loss and OPtimizer
criterion = torch.nn.MSELoss(size_average = False) #MSE损失类,会构造计算图,继承Module类
optimizer = torch.optim.SGD(model.parameters(), lr = 0.01) #优化器,不会构造计算图,检查module的所有参数

#4.Training Cycle 训练并更新
for epoch in range(1000):
    y_pred = model(x_data) #使用了实例model,调用了前馈forward
    loss = criterion(y_pred, y_data) #求损失loss
    print(epoch, loss.item())
    
    optimizer.zero_grad() #梯度归零??
    loss.backward() #反向传播
    optimizer.step() #更新
    
#5.Output weight and bias
print('w = ', model.linear.weight.item())
print('b = ', model.linear.bias.item())

#6.Test Model
x_test = torch.Tensor([[4.0]])
y_test = model(x_test)
print('y_pred = ', y_test.data) # 取tensor数值

运行结果:
Alt

各种优化器的迭代结果对比:

optimizer1 = torch.optim.SGD(model.parameters(), lr = 0.01) 
optimizer2 = torch.optim.Adam(model.parameters(), lr = 0.01) 
optimizer3 = torch.optim.Adamax(model.parameters(), lr = 0.01) 
optimizer4 = torch.optim.ASGD(model.parameters(), lr = 0.01) 
optimizer5 = torch.optim.RMSprop(model.parameters(), lr = 0.01) 
optimizer6 = torch.optim.Adagrad(model.parameters(), lr = 0.01)
optimizer7 = torch.optim.Rprop(model.parameters(), lr = 0.01)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
掉包构建线性回归预测模型是指使用现有的Python库或者工具包来构建线性回归模型,而不需要手动编写算法代码。在Python中,有很多强大的数据科学库可以用来构建线性回归模型,比如NumPy、Pandas和Scikit-learn等。 下面是使用Scikit-learn库来构建线性回归预测模型的步骤: 1. 导入所需的库: ```python import numpy as np import pandas as pd from sklearn.linear_model import LinearRegression from sklearn.model_selection import train_test_split ``` 2. 准备数据: 首先,你需要准备好用于训练和测试的数据集。通常,你需要将数据集分为特征(自变量)和目标变量(因变量)两部分。特征是用来预测目标变量的属性或特征,而目标变量是你要预测的值。 3. 划分训练集和测试集: 将数据集划分为训练集和测试集,以便评估模型的性能。可以使用`train_test_split`函数来实现: ```python X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) ``` 其中,`X`是特征数据,`y`是目标变量。 4. 构建线性回归模型: ```python model = LinearRegression() model.fit(X_train, y_train) ``` 这里使用`LinearRegression`类来构建线性回归模型,并使用训练集数据进行拟合。 5. 进行预测: ```python y_pred = model.predict(X_test) ``` 使用训练好的模型对测试集进行预测,得到预测结果。 6. 评估模型: 可以使用各种评估指标来评估模型的性能,比如均方误差(Mean Squared Error)和决定系数(R-squared)等。 以上是使用Scikit-learn库进行线性回归预测模型构建的基本步骤。当然,还有其他库和方法可以用来构建线性回归模型,具体选择取决于你的需求和偏好。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值