Pytorch 线性回归

矫情吗;* 2023-07-24 05:46 105阅读 0赞

日萌社" class="reference-link">20191009191333910.png日萌社

人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新)


Pytorch完成线性回归

目标

  1. 知道如何手动完成线性回归

1. 线性回归实现

下面,我们使用一个自定义的数据,来使用torch实现一个简单的线性回归

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

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

    import torch
    import numpy as np
    from matplotlib import pyplot as plt

  1. #1. 准备数据 y = 3x+0.8,准备参数
  2. x = torch.rand([50])
  3. y = 3*x + 0.8
  4. w = torch.rand(1,requires_grad=True)
  5. b = torch.rand(1,requires_grad=True)
  6. def loss_fn(y,y_predict):
  7. loss = (y_predict-y).pow(2).mean()
  8. for i in [w,b]:
  9. #每次反向传播前把梯度置为0
  10. if i.grad is not None:
  11. i.grad.data.zero_()
  12. # [i.grad.data.zero_() for i in [w,b] if i.grad is not None]
  13. loss.backward()
  14. return loss.data
  15. def optimize(learning_rate):
  16. # print(w.grad.data,w.data,b.data)
  17. w.data -= learning_rate* w.grad.data
  18. b.data -= learning_rate* b.grad.data
  19. for i in range(3000):
  20. #2. 计算预测值
  21. y_predict = x*w + b
  22. #3.计算损失,把参数的梯度置为0,进行反向传播
  23. loss = loss_fn(y,y_predict)
  24. if i%500 == 0:
  25. print(i,loss)
  26. #4. 更新参数w和b
  27. optimize(0.01)
  28. # 绘制图形,观察训练结束的预测值和真实值
  29. predict = x*w + b #使用训练后的w和b计算预测值
  30. plt.scatter(x.data.numpy(), y.data.numpy(),c = "r")
  31. plt.plot(x.data.numpy(), predict.data.numpy())
  32. plt.show()
  33. print("w",w)
  34. print("b",b)

图形效果如下:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3ppbWlhbzU1MjE0NzU3Mg_size_16_color_FFFFFF_t_70

打印w和b,可有

  1. w tensor([2.9280], requires_grad=True)
  2. b tensor([0.8372], requires_grad=True)

可知,w和b已经非常接近原来的预设的3和0.8


Pytorch基础模型

目标

  1. 知道如何使用pytorch模型组件构建模型
  2. 知道如何在GPU上运行代码
  3. 能够说出常见的优化器及其原理

1 使用pytorch模型组件把线性回归完整代码

构建模型,最重要的有两个步骤:

  1. 找到合适的计算关系,随即初始化参数来拟合输入和输出的关系(前向计算,从输入得到输出)
  2. 选取合适的损失函数和优化器来减小损失(反向传播,得到合适的参数)

    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

    2 .定义模型

    class Lr(nn.Module):

    1. def __init__(self):
    2. super(Lr,self).__init__()
    3. self.linear = nn.Linear(1,1)
    4. def forward(self, x):
    5. out = self.linear(x)
    6. return out

    2. 实例化模型,loss,和优化器

    model = Lr()
    criterion = nn.MSELoss()
    optimizer = optim.SGD(model.parameters(), lr=1e-3)

    3. 训练模型

    for i in range(30000):

    1. out = model(x) #3.1 获取预测值
    2. loss = criterion(y,out) #3.2 计算损失
    3. optimizer.zero_grad() #3.3 梯度归零
    4. loss.backward() #3.4 计算梯度
    5. optimizer.step() # 3.5 更新梯度
    6. if (i+1) % 20 == 0:
    7. print('Epoch[{}/{}], loss: {:.6f}'.format(i,30000,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()

输出如下:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3ppbWlhbzU1MjE0NzU3Mg_size_16_color_FFFFFF_t_70 1

注意:

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

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

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

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

2. 在GPU上运行代码

当模型太大,或者参数太多的情况下,为了加快训练速度,经常会使用GPU来进行训练

此时我们的代码需要稍作调整:

  1. 判断GPU是否可用torch.cuda.is_available()

    1. torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    2. >>device(type='cuda', index=0) #使用gpu
    3. >>device(type='cpu') #使用cpu
  2. 把模型参数和input数据转化为cuda的支持类型

    1. model.to(device)
    2. x_true.to(device)
  3. 在GPU上计算结果也为cuda的数据类型,需要转化为numpy或者torch的cpu的tensor类型

    1. predict = predict.cpu().detach().numpy()

    detach()的效果和data的相似,但是detach()是深拷贝,data是取值,是浅拷贝

修改之后的代码如下:

  1. import torch
  2. from torch import nn
  3. from torch import optim
  4. import numpy as np
  5. from matplotlib import pyplot as plt
  6. import time
  7. # 1. 定义数据
  8. x = torch.rand([50,1])
  9. y = x*3 + 0.8
  10. #2 .定义模型
  11. class Lr(nn.Module):
  12. def __init__(self):
  13. super(Lr,self).__init__()
  14. self.linear = nn.Linear(1,1)
  15. def forward(self, x):
  16. out = self.linear(x)
  17. return out
  18. # 2. 实例化模型,loss,和优化器
  19. device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
  20. x,y = x.to(device),y.to(device)
  21. model = Lr().to(device)
  22. criterion = nn.MSELoss()
  23. optimizer = optim.SGD(model.parameters(), lr=1e-3)
  24. #3. 训练模型
  25. for i in range(300):
  26. out = model(x)
  27. loss = criterion(y,out)
  28. optimizer.zero_grad()
  29. loss.backward()
  30. optimizer.step()
  31. if (i+1) % 20 == 0:
  32. print('Epoch[{}/{}], loss: {:.6f}'.format(i,30000,loss.data))
  33. #4. 模型评估
  34. model.eval() #
  35. predict = model(x)
  36. predict = predict.cpu().detach().numpy() #转化为numpy数组
  37. plt.scatter(x.cpu().data.numpy(),y.cpu().data.numpy(),c="r")
  38. plt.plot(x.cpu().data.numpy(),predict,)
  39. plt.show()

发表评论

表情:
评论列表 (有 0 条评论,105人围观)

还没有评论,来说两句吧...

相关阅读

    相关 pytorch-线性回归

    线性回归 主要内容包括: 1. 线性回归的基本要素 2. 线性回归模型从零开始的实现 3. 线性回归模型使用pytorch的简洁实现 线性回归的基本要素