目录
4. Stochastic Gradient Descent
5. Different of Gradient method
学习内容来自:b站的刘二大人----《PyTorch深度学习实践》
1.Assignment
假设我们的Training set 是
x | y(hat) |
1 | 2 |
2 | 4 |
3 | 6 |
建立一个model ,预测输入x = 4的时候,y是多少
2. Algorithm
之前的穷举法虽然简单,但是有很多的问题。穷举顾名思义就是通过暴力手段找到所有的情况,然后找出最优解。但是如果训练的模型更加复杂,例如函数不仅仅有斜率,还有更多的w1,w2...等等,那么穷举出的范围将会特别多
这里也可以用一些别的算法进行优化,比如分治法
分治法:将大的问题划分为小的问题,然后着重解决小的问题,逐个击破,最终解决大的问题
例如:函数有两个参数w1,w2。假设通过分析,两个最好的范围是1-100,那么如果根据穷举会有100*100的范围。而分治法的思想是,先取其中几个点,假设w1取10、80,w2取10,80,在这四个点找到最优的解(假设是w1=10,w2=80),然后在这个最优的点在划分,直到找到这个问题的解
但是这个算法有个问题,就是如果全局范围的最优解是w1=50,w2=50。而我们根据第一次的划分,去w1=10,w2=80的附近去找了。那么,最后找的的解是10,80附近一小块的最优解,从而导致我们的解会陷入局部最优(Local optimal)的问题。
还可以尝试另一种算法,贪心算法
贪心算法:求解问题,不去考虑全局的解。只考虑当前情况最好的选择,不从整体考虑,关注局部最优解
而本章的梯度下降就是根据贪心算法
3. Gradient Descent(Batch)
Gradient Descent(Batch)
简单理解梯度,梯度是个矢量,函数在这个点的方向导数沿着梯度方向取最大值(方向导数是个数),也就是说函数沿着梯度方向变化最快。
在一元函数中,梯度就是函数的导数,所以函数沿着斜率变化的最快
在多元函数中,代表偏导数的意思
那么根据MSE均方差定义的Cost函数,w更新的方向为:
1. 因为我们是要用梯度下降找到最好的w值,也就是最好的函数。所以应该根据梯度更新w的值,因为cost 成本函数沿着梯度下降的最快
2. 因为梯度是增加的方向,而我们需要将cost函数的值降低,从而使 模型的预测值和 数据的真实值 误差足够下。所以这里更新的是 负梯度的方向
3. α 是学习率 learning rate ,代表一次梯度下降走的步长。学习率过大,会发散
那么根据链式法则chain rule 可知,cost对w的导数为:
也就是:
Code
import matplotlib.pyplot as plt
x_data =[1.0,2.0,3.0]
y_data = [2.0,4.0,6.0]
w = 1.0
epoch_list = []
cost_list = []
def forward (x):
return x *w
def cost(xs, ys):
cost = 0
for x, y in zip(xs,ys):
y_pred = forward(x)
cost += (y_pred - y)**2
return cost / len(xs)
def gradient(xs,ys):
grad = 0
for x, y in zip(xs,ys):
grad += 2*x*(x* w - y)
return grad / len(xs)
print ('Predict (before training)',4, forward(4))
for epoch in range(100):
cost_val = cost(x_data,y_data)
grad_val = gradient(x_data,y_data)
w-= 0.01* grad_val
epoch_list.append(epoch)
cost_list.append(cost_val)
print(' Epoch:', epoch,'w=',w, 'loss=', cost_val)
print(' Predict (after training)',4,forward(4))
plt.plot(epoch_list,cost_list)
plt.xlabel('w')
plt.ylabel('Cost')
plt.show()
代码部分输出为:
Predict (before training) 4 4.0
Epoch: 0 w= 1.0933333333333333 loss= 4.666666666666667
Epoch: 1 w= 1.1779555555555554 loss= 3.8362074074074086
....
Epoch: 36 w= 1.9733582330705144 loss= 0.004029373553099482
Epoch: 37 w= 1.975844797983933 loss= 0.0033123241439168096
Epoch: 38 w= 1.9780992835054327 loss= 0.0027228776607060357
.....
Epoch: 61 w= 1.9976998600690001 loss= 3.0034471708953996e-05
Epoch: 62 w= 1.9979145397958935 loss= 2.4689670610172655e-05
Epoch: 63 w= 1.9981091827482769 loss= 2.0296006560253656e-05
Epoch: 64 w= 1.9982856590251044 loss= 1.6684219437262796e-05
....
Epoch: 97 w= 1.9999324119941766 loss= 2.593287985380858e-08
Epoch: 98 w= 1.9999387202080534 loss= 2.131797981222471e-08
Epoch: 99 w= 1.9999444396553017 loss= 1.752432687141379e-08
Predict (after training) 4 7.999777758621207
图像结果:
4. Stochastic Gradient Descent
Stochastic Gradient Descent
随机梯度下降意思是随机找一个样本进行梯度下降
而上面的Gradient Descent 梯度下降法 是对整个样本,也就是整个训练集 Cost 进行下降
区别就是:
- 假设Cost 函数进入了一个学习高原区(梯度几乎消失的区域),那么因为偏导数为0,就会导致w不进行更新。而SGD是随机选择一个样本,通常来说,单个样本会有噪声,可能会推动梯度下降
- 整个训练集的梯度下降,将所有的样本求和,计算量大,时间复杂度小
- SGD针对于单个样本,计算量小,但是时间复杂度会大
二者的区别大概如图:
所以,梯度下降是对cost所有样本,SGD是对Loss单个样本
Code
import matplotlib.pyplot as plt
x_data =[1.0,2.0,3.0]
y_data = [2.0,4.0,6.0]
w = 1.0
epoch_list = []
loss_list = []
def forward (x):
return x *w
def loss(x, y):
y_pred = forward(x)
return (y_pred - y)**2
def gradient(x,y):
return 2*x*(x*w-y)
print ('Predict (before training)',4, forward(4))
for epoch in range(100):
for x,y in zip(x_data,y_data):
grad = gradient(x,y)
w -= 0.01 * grad
print('\tgrad:',x,y,grad)
l = loss(x,y)
print('Progress:', epoch, 'w=', w, 'loss=', l)
loss_list.append(l)
epoch_list.append(epoch)
print('Predict (after training)',4,forward(4))
plt.plot(epoch_list,loss_list)
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()
代码输出:
Predict (before training) 4 4.0
grad: 1.0 2.0 -2.0
grad: 2.0 4.0 -7.84
grad: 3.0 6.0 -16.2288
Progress: 0 w= 1.260688 loss= 4.919240100095999
grad: 1.0 2.0 -1.478624
grad: 2.0 4.0 -5.796206079999999
grad: 3.0 6.0 -11.998146585599997
Progress: 1 w= 1.453417766656 loss= 2.688769240265834
grad: 1.0 2.0 -1.093164466688
grad: 2.0 4.0 -4.285204709416961
grad: 3.0 6.0 -8.87037374849311
Progress: 2 w= 1.5959051959019805 loss= 1.4696334962911515
grad: 1.0 2.0 -0.8081896081960389
grad: 2.0 4.0 -3.1681032641284723
grad: 3.0 6.0 -6.557973756745939
.....
Progress: 22 w= 1.9990383027488265 loss= 8.323754426231206e-06
grad: 1.0 2.0 -0.001923394502346909
grad: 2.0 4.0 -0.007539706449199102
grad: 3.0 6.0 -0.01560719234984198
Progress: 23 w= 1.9992890056818404 loss= 4.549616284094891e-06
grad: 1.0 2.0 -0.0014219886363191492
grad: 2.0 4.0 -0.005574195454370212
grad: 3.0 6.0 -0.011538584590544687
....
Progress: 72 w= 1.999999999734279 loss= 6.354692062078993e-19
grad: 1.0 2.0 -5.314420015167798e-10
grad: 2.0 4.0 -2.0832526814729135e-09
grad: 3.0 6.0 -4.31233715403323e-09
Progress: 73 w= 1.9999999998035491 loss= 3.4733644793346653e-19
grad: 1.0 2.0 -3.92901711165905e-10
grad: 2.0 4.0 -1.5401742103904326e-09
grad: 3.0 6.0 -3.188159070077745e-09
Progress: 74 w= 1.9999999998547615 loss= 1.8984796531526204e-19
grad: 1.0 2.0 -2.9047697580608656e-10
grad: 2.0 4.0 -1.1386696030513122e-09
grad: 3.0 6.0 -2.3570478902001923e-09
.....
Progress: 97 w= 1.9999999999998603 loss= 1.757455879087579e-25
grad: 1.0 2.0 -2.793321129956894e-13
grad: 2.0 4.0 -1.0942358130705543e-12
grad: 3.0 6.0 -2.2648549702353193e-12
Progress: 98 w= 1.9999999999998967 loss= 9.608404711682446e-26
grad: 1.0 2.0 -2.0650148258027912e-13
grad: 2.0 4.0 -8.100187187665142e-13
grad: 3.0 6.0 -1.6786572132332367e-12
Progress: 99 w= 1.9999999999999236 loss= 5.250973729513143e-26
Predict (after training) 4 7.9999999999996945
输出图像:
5. Different of Gradient method
梯度下降大概可以分为三类:
- Batch Gradient Descent:针对于所有样本 cost 函数的,batch是 ‘批、捆’ 的意思,一般来说针对于所有的样本的梯度下降,就简称Gradient Descent
- Stochastic Gradient Descent:针对于单个样本的,即针对loss函数的为随机梯度下降
- mini-Batch Gradient Descent:二者折中,会有个size的概念,就是将整个样本分成多少分,每个里面的个数就是size
epoch : 代表将所有的batch ,也就是整个训练集 训练完是一个epoch
update:将单个batch 训练完,叫做一个更新,更新 权重w
所以,当size = 整个样本的时候,就是 Batch Gradient Descent
当size = 1 的时候,就是Stochastic Gradient Descent
关于其他的补充:
梯度下降法:计算量很大,但是时间复杂度小
随机梯度下降法:计算量小,但是时间复杂度会很大。而且没有使用向量化加速
小批量梯度下降法:二者折中,应用比较普遍