Pytorch深度学习(二)-手动实现线性回归

秒速五厘米 2022-11-11 15:58 1222阅读 0赞

上一讲中我们介绍了梯度下降,下面我们用PyTorch中的Autograd自动求导实现线性回归。

归纳而言,这篇会相对简单,主要包含以下几点:

  • PyTorch Autograd 概念介绍
  • 利用 Autograd 替代手动求解导数
  • 实现 Autograd 方式的线性回归模型

一、PyTorch Autograd 概念介绍

具体查看官网:https://pytorch.org/tutorials/beginner/blitz/autograd_tutorial.html

原理虽然简单,但其中有不少细节需要注意:

首先需要这个函数链是可导的
1.一个 backward 对应一个 grad计算值,所以重复 backward 以及中间环节执行 backward 都会导致 grad 值变化
2.一个 grad 使用完之后,需要记得 设置为 0 ,再次 backward 才能得到正确的值

二、重点代码介绍

1.利用 Autograd 替代手动求解导数

  1. # 设置 requires_grad=True ,告诉PyTorch需要记录params上所有的操作
  2. params = torch.tensor([1.0, 0.0], requires_grad=True)
  3. # 目前为止 params.grad is None
  4. # 执行 backward 后, params.grad 就保存了微分值
  5. loss = loss_fn(model(t_u, *params), t_c)
  6. loss.backward()
  7. # grad 使用完之后,需要记得 设置为 0
  8. if params.grad is not None:
  9. params.grad.zero_()

2.实现 Autograd 方式的线性回归模型

  1. def training_loop(n_epochs, learning_rate, params, t_u, t_c):
  2. for epoch in range(1, n_epochs + 1):
  3. if params.grad is not None:
  4. params.grad.zero_()
  5. t_p = model(t_u, *params)
  6. loss = loss_fn(t_p, t_c)
  7. loss.backward()
  8. params = (params - learning_rate * params.grad).detach().requires_grad_()
  9. # print('Epoch %d, Loss %f' % (epoch, float(loss)))
  10. # print('Params', params)
  11. if epoch % 500 == 0:
  12. print('Epoch %d, Loss %f' % (epoch, float(loss)))
  13. return params

需要着重解释的是 detach().requires_grad_()
这里的作用就是使 params 脱离之前的函数链,PyTorch重新记录新的函数链

三、完整代码

  1. """
  2. PyTorch 基础入门二: PyTorch 自动求导线性模型实现
  3. 线性回归参数估计
  4. 问题: 华氏温度转换
  5. """
  6. import torch
  7. # 定义输入数据
  8. t_c = [0.5, 14.0, 15.0, 28.0, 11.0, 8.0, 3.0, -4.0, 6.0, 13.0, 21.0]
  9. t_u = [35.7, 55.9, 58.2, 81.9, 56.3, 48.9, 33.9, 21.8, 48.4, 60.4, 68.4]
  10. t_c = torch.tensor(t_c)
  11. t_u = torch.tensor(t_u)
  12. # 对应的线性模型为
  13. # t_c = w * t_u + b
  14. def model(t_u, w, b):
  15. return w*t_u + b
  16. # 定义损失函数
  17. # t_p 为模型估计值
  18. # t_c 为实验数据
  19. def loss_fn(t_p, t_c):
  20. squared_diffs = (t_p - t_c)**2
  21. return squared_diffs.mean()
  22. # 以上跟第一篇保持一致
  23. #########################################################################
  24. # 设置 requires_grad=True ,告诉PyTorch需要记录params上所有的操作
  25. params = torch.tensor([1.0, 0.0], requires_grad=True)
  26. # 目前为止 params.grad is None
  27. # 执行 backward 后, params.grad 就保存了微分值
  28. # loss = loss_fn(model(t_u, *params), t_c)
  29. # loss.backward()
  30. if params.grad is not None:
  31. params.grad.zero_()
  32. def training_loop(n_epochs, learning_rate, params, t_u, t_c):
  33. for epoch in range(1, n_epochs + 1):
  34. if params.grad is not None:
  35. params.grad.zero_()
  36. t_p = model(t_u, *params)
  37. loss = loss_fn(t_p, t_c)
  38. loss.backward()
  39. #
  40. params = (params - learning_rate * params.grad).detach().requires_grad_()
  41. # print('Epoch %d, Loss %f' % (epoch, float(loss)))
  42. # print('Params', params)
  43. if epoch % 500 == 0:
  44. print('Epoch %d, Loss %f' % (epoch, float(loss)))
  45. return params
  46. # 特征缩放处理
  47. t_un = 0.1 * t_u
  48. params = training_loop(
  49. n_epochs = 5000,
  50. learning_rate = 1e-2,
  51. params = torch.tensor([1.0, 0.0], requires_grad=True),
  52. t_u = t_un,
  53. t_c = t_c)
  54. # 画出图示
  55. import matplotlib.pyplot as plt
  56. t_p = model(t_un, *params)
  57. fig = plt.figure()
  58. plt.title(u"PyTorch linear model")
  59. plt.xlabel("Fahrenheit")
  60. plt.ylabel("Celsius")
  61. plt.plot(t_u.numpy(), t_p.detach().numpy())
  62. plt.plot(t_u.numpy(), t_c.numpy(), 'o')
  63. plt.show()

四、结果展示
20200511143712

发表评论

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

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

相关阅读

    相关 pytorch-线性回归

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