You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

rmsprop.py 6.1 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. # -*- coding: utf-8 -*-
  2. # ---
  3. # jupyter:
  4. # jupytext_format_version: '1.2'
  5. # kernelspec:
  6. # display_name: Python 3
  7. # language: python
  8. # name: python3
  9. # language_info:
  10. # codemirror_mode:
  11. # name: ipython
  12. # version: 3
  13. # file_extension: .py
  14. # mimetype: text/x-python
  15. # name: python
  16. # nbconvert_exporter: python
  17. # pygments_lexer: ipython3
  18. # version: 3.5.2
  19. # ---
  20. # # RMSProp
  21. # RMSprop 是由 Geoff Hinton 在他 Coursera 课程中提出的一种适应性学习率方法,至今仍未被公开发表。前面我们提到了 Adagrad 算法有一个问题,就是学习率分母上的变量 s 不断被累加增大,最后会导致学习率除以一个比较大的数之后变得非常小,这不利于我们找到最后的最优解,所以 RMSProp 的提出就是为了解决这个问题。
  22. #
  23. # ## RMSProp 算法
  24. # RMSProp 仍然会使用梯度的平方量,不同于 Adagrad,其会使用一个指数加权移动平均来计算这个 s,也就是
  25. #
  26. # $$
  27. # s_i = \alpha s_{i-1} + (1 - \alpha) \ g^2
  28. # $$
  29. #
  30. # 这里 g 表示当前求出的参数梯度,然后最终更新和 Adagrad 是一样的,学习率变成了
  31. #
  32. # $$
  33. # \frac{\eta}{\sqrt{s + \epsilon}}
  34. # $$
  35. #
  36. # 这里 $\alpha$ 是一个移动平均的系数,也是因为这个系数,导致了 RMSProp 和 Adagrad 不同的地方,这个系数使得 RMSProp 更新到后期累加的梯度平方较小,从而保证 s 不会太大,也就使得模型后期依然能够找到比较优的结果
  37. #
  38. # 实现上和 Adagrad 非常像
  39. def rmsprop(parameters, sqrs, lr, alpha):
  40. eps = 1e-10
  41. for param, sqr in zip(parameters, sqrs):
  42. sqr[:] = alpha * sqr + (1 - alpha) * param.grad.data ** 2
  43. div = lr / torch.sqrt(sqr + eps) * param.grad.data
  44. param.data = param.data - div
  45. # +
  46. import numpy as np
  47. import torch
  48. from torchvision.datasets import MNIST # 导入 pytorch 内置的 mnist 数据
  49. from torch.utils.data import DataLoader
  50. from torch import nn
  51. from torch.autograd import Variable
  52. import time
  53. import matplotlib.pyplot as plt
  54. # %matplotlib inline
  55. def data_tf(x):
  56. x = np.array(x, dtype='float32') / 255
  57. x = (x - 0.5) / 0.5 # 标准化,这个技巧之后会讲到
  58. x = x.reshape((-1,)) # 拉平
  59. x = torch.from_numpy(x)
  60. return x
  61. train_set = MNIST('./data', train=True, transform=data_tf, download=True) # 载入数据集,申明定义的数据变换
  62. test_set = MNIST('./data', train=False, transform=data_tf, download=True)
  63. # 定义 loss 函数
  64. criterion = nn.CrossEntropyLoss()
  65. # +
  66. train_data = DataLoader(train_set, batch_size=64, shuffle=True)
  67. # 使用 Sequential 定义 3 层神经网络
  68. net = nn.Sequential(
  69. nn.Linear(784, 200),
  70. nn.ReLU(),
  71. nn.Linear(200, 10),
  72. )
  73. # 初始化梯度平方项
  74. sqrs = []
  75. for param in net.parameters():
  76. sqrs.append(torch.zeros_like(param.data))
  77. # 开始训练
  78. losses = []
  79. idx = 0
  80. start = time.time() # 记时开始
  81. for e in range(5):
  82. train_loss = 0
  83. for im, label in train_data:
  84. im = Variable(im)
  85. label = Variable(label)
  86. # 前向传播
  87. out = net(im)
  88. loss = criterion(out, label)
  89. # 反向传播
  90. net.zero_grad()
  91. loss.backward()
  92. rmsprop(net.parameters(), sqrs, 1e-3, 0.9) # 学习率设为 0.001,alpha 设为 0.9
  93. # 记录误差
  94. train_loss += loss.data[0]
  95. if idx % 30 == 0:
  96. losses.append(loss.data[0])
  97. idx += 1
  98. print('epoch: {}, Train Loss: {:.6f}'
  99. .format(e, train_loss / len(train_data)))
  100. end = time.time() # 计时结束
  101. print('使用时间: {:.5f} s'.format(end - start))
  102. # -
  103. x_axis = np.linspace(0, 5, len(losses), endpoint=True)
  104. plt.semilogy(x_axis, losses, label='alpha=0.9')
  105. plt.legend(loc='best')
  106. # +
  107. train_data = DataLoader(train_set, batch_size=64, shuffle=True)
  108. # 使用 Sequential 定义 3 层神经网络
  109. net = nn.Sequential(
  110. nn.Linear(784, 200),
  111. nn.ReLU(),
  112. nn.Linear(200, 10),
  113. )
  114. # 初始化梯度平方项
  115. sqrs = []
  116. for param in net.parameters():
  117. sqrs.append(torch.zeros_like(param.data))
  118. # 开始训练
  119. losses = []
  120. idx = 0
  121. start = time.time() # 记时开始
  122. for e in range(5):
  123. train_loss = 0
  124. for im, label in train_data:
  125. im = Variable(im)
  126. label = Variable(label)
  127. # 前向传播
  128. out = net(im)
  129. loss = criterion(out, label)
  130. # 反向传播
  131. net.zero_grad()
  132. loss.backward()
  133. rmsprop(net.parameters(), sqrs, 1e-3, 0.999) # 学习率设为 0.001,alpha 设为 0.999
  134. # 记录误差
  135. train_loss += loss.data[0]
  136. if idx % 30 == 0:
  137. losses.append(loss.data[0])
  138. idx += 1
  139. print('epoch: {}, Train Loss: {:.6f}'
  140. .format(e, train_loss / len(train_data)))
  141. end = time.time() # 计时结束
  142. print('使用时间: {:.5f} s'.format(end - start))
  143. # -
  144. x_axis = np.linspace(0, 5, len(losses), endpoint=True)
  145. plt.semilogy(x_axis, losses, label='alpha=0.999')
  146. plt.legend(loc='best')
  147. # **小练习:可以看到使用了不同的 alpha 会使得 loss 在下降过程中的震荡程度不同,想想为什么**
  148. # 当然 pytorch 也内置了 rmsprop 的方法,非常简单,只需要调用 `torch.optim.RMSprop()` 就可以了,下面是例子
  149. # +
  150. train_data = DataLoader(train_set, batch_size=64, shuffle=True)
  151. # 使用 Sequential 定义 3 层神经网络
  152. net = nn.Sequential(
  153. nn.Linear(784, 200),
  154. nn.ReLU(),
  155. nn.Linear(200, 10),
  156. )
  157. optimizer = torch.optim.RMSprop(net.parameters(), lr=1e-3, alpha=0.9)
  158. # 开始训练
  159. start = time.time() # 记时开始
  160. for e in range(5):
  161. train_loss = 0
  162. for im, label in train_data:
  163. im = Variable(im)
  164. label = Variable(label)
  165. # 前向传播
  166. out = net(im)
  167. loss = criterion(out, label)
  168. # 反向传播
  169. optimizer.zero_grad()
  170. loss.backward()
  171. optimizer.step()
  172. # 记录误差
  173. train_loss += loss.data[0]
  174. print('epoch: {}, Train Loss: {:.6f}'
  175. .format(e, train_loss / len(train_data)))
  176. end = time.time() # 计时结束
  177. print('使用时间: {:.5f} s'.format(end - start))

机器学习越来越多应用到飞行器、机器人等领域,其目的是利用计算机实现类似人类的智能,从而实现装备的智能化与无人化。本课程旨在引导学生掌握机器学习的基本知识、典型方法与技术,通过具体的应用案例激发学生对该学科的兴趣,鼓励学生能够从人工智能的角度来分析、解决飞行器、机器人所面临的问题和挑战。本课程主要内容包括Python编程基础,机器学习模型,无监督学习、监督学习、深度学习基础知识与实现,并学习如何利用机器学习解决实际问题,从而全面提升自我的《综合能力》。