• pytorch学习---实现线性回归初体验


    假设我们的基础模型就是y = wx + b,其中w和b均为参数,我们使用y = 3x+0.8来构造数据x、y,所以最后通过模型应该能够得出w和b应该分别接近3和0.8。

    步骤如下:

    1. 准备数据
    2. 计算预测值
    3. 计算损失,把参数的梯度置为0,进行反向传播
    4. 更新参数

    方式一

    该方式没有用pytorch的模型api,手动实现

    import torch,numpy
    import matplotlib.pyplot as plt
    
    # 1、准备数据
    learning_rate = 0.01
    #y=3x + 0.8
    x = torch.rand([500,1])
    y_true= x*3 + 0.8
    
    
    # 2、通过模型计算y_predict
    w = torch.rand([1,1],requires_grad=True)
    b = torch.tensor(0,requires_grad=True,dtype=torch.float32)
    
    # 3、通过循环,反向传播,更新参数
    for i in range(500):
        # 4、计算loss
        y_predict = torch.matmul(x,w) + b
        loss = (y_true-y_predict).pow(2).mean()
        # 每次循环判断是否存在梯度,防止累加
        if w.grad is not None:
            w.grad.data.zero_()
        if b.grad is not None:
            b.grad.data.zero_()
        # 反向传播
        loss.backward()
        w.data = w.data - learning_rate*w.grad
        b.data = b.data - learning_rate*b.grad
        # 每50次输出一下结果
        if i%50==0:
            print("w,b,loss",w.item(),b.item(),loss.item())
    
    #可视化显示
    plt.figure(figsize=(20,8))
    plt.scatter(x.numpy().reshape(-1),y_true.numpy().reshape(-1))
    y_predict = torch.matmul(x,w) + b
    plt.plot(x.numpy().reshape(-1),y_predict.detach().numpy().reshape(-1),c="r")
    plt.show()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    循环500次的效果
    在这里插入图片描述
    循环2000次的结果
    在这里插入图片描述

    方式二

    方式一的方式虽然已经购简便了,但是还是有些许繁琐,所以我们可以采用pytorchapi来实现。
    nn.Moduletorch.nn提供的一个类,是pytorch中我们自定义网络的一个基类,在这个类中定义了很多有用的方法,让我们在继承这个类定义网络的时候非常简单。
    当我们自定义网络的时候,有两个方法需要特别注意:
    1.__init__需要调用super方法,继承父类的属性和方法
    2. forward方法必须实现,用来定义我们的网络的向前计算的过程用前面的y = wx+b的模型举例如下:

    #定义模型
    from torch import nn
    class Lr(nn.Module): #继承nn.Module
        def __init__(self):
            super(Lr, self).__init__()
            self.linear = nn.Linear(1,1)
    
        def forward(self,x):
            out = self.linear(x)
            return out
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    全部代码如下:

    #!/usr/bin/env python 
    # -*- coding:utf-8 -*-
    import torch
    from torch import nn
    from torch import optim
    import numpy as np
    from matplotlib import pyplot as plt
    
    #1、定义数据
    x = torch.rand([50,1])
    y = x*3 + 0.8
    
    #定义模型
    class Lr(nn.Module): #继承nn.Module
        def __init__(self):
            super(Lr, self).__init__()
            self.linear = nn.Linear(1,1)
    
        def forward(self,x):
            out = self.linear(x)
            return out
    #2、实例化模型、loss函数以及优化器
    model = Lr()
    criterion = nn.MSELoss()   #损失函数
    optimizer = optim.SGD(model.parameters(),lr=1e-3) #优化器
    
    #3、训练模型
    for i in range(3000):
        out = model(x)# 获取预测值
        loss = criterion(y,out) #计算损失
        optimizer.zero_grad() #梯度归零
        loss.backward() #计算梯度
        optimizer.step() #更新梯度
    
        if(i+1) % 20 ==0:
            print('Epoch[{}/{}],loss:{:.6f}'.format(i,500,loss.data))
    
    
    #4、模型评估
    model.eval() #设置模型为评估模式,即预测模式
    predict = model(x)
    predict = predict.data.numpy()
    plt.scatter(x.data.numpy(),y.data.numpy(),c="r")
    plt.plot(x.data.numpy(),predict)
    plt.show()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    注意:

    model.eval()表示设置模型为评估模式,即预测模式

    model.train(mode=True) 表示设置模型为训练模式

    在当前的线性回归中,上述并无区别

    但是在其他的一些模型中,训练的参数和预测的参数会不相同,到时候就需要具体告诉程序我们是在进行训练还是预测,比如模型中存在DropoutBatchNorm的时候

    循环2000次的结果:
    在这里插入图片描述
    循环30000次的结果:
    在这里插入图片描述

  • 相关阅读:
    自动打包机如何精准捆扎
    webpack依赖包是同一个仓库,也要进行安装
    C++基础
    『现学现忘』Git基础 — 18、Git对象的总结
    病毒消灭战-第13届蓝桥杯Scratch选拔赛真题精选
    WPF项目实战布局--通用固件下载 C#
    【配置环境】VS Code怎么使用JavaScript的Mocha测试框架和Chai断言库
    Vue3 - Fragment 片段(详细教程)
    超越OpenCV速度的MorphologyEx函数实现(特别是对于二值图,速度是CV的4倍左右)。
    C++面向对象编程题 第13题
  • 原文地址:https://blog.csdn.net/niulinbiao/article/details/133045516