梯度下降算法概述
DL 随便写写 搞笑
梯度下降算法概述
一、两个老方法及其弊端
观察法
已经是老古董了,再无话说。

分治法
分治法缺陷明显:可能错过最优点;一旦权重数量级完全变大,如AlexNet(500万级),会导致划分搜索失效。
二、DL所采用的——梯度下降算法
实际上是用梯度下降算法。
Gradient:
Update:
可以理解为是函数曲线求导数的正负号,当为负的时候,下降最猛。每次迭代就向着下降最快的地方狂奔。
算法设计思想:贪心。(梯度下降算法同贪心算法,得到的数据并非是全局最优)
(非凸函数的最优点只是局部最优,梯度下降算法基本求得的就是局部最优)
那么为什么DL/神经网络会采用求局部最优呢?实际上深度神经网络的目标函数内很难陷入局部最优点。只有在鞍点时,梯度为0,无局部最优点。在用梯度下降算法进行梯度优化时,如果到达平缓区域,将无法进行优化更新(陷入鞍点)
所以结合损失函数和梯度下降算法,如下Derivative:
其中 ,最后得到了机器学习中经典的梯度下降(Gradient Descent)更新公式:
三、具体代码实现
import numpy as npimport 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 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):###训练过程:100轮训练 cost_val = cost(x_data, y_data)###算平均成本 grad_val = gradient(x_data, y_data)###求梯度 w -= 0.01 * grad_val
epoch_list.append(epoch)###为了绘图写的 loss_list.append(cost_val)
print('Epoch:', epoch, 'w=', w, 'loss=', cost_val)print('Predict (after training)', 4, forward(4))
plt.plot(epoch_list, loss_list) ### x轴是轮数,y轴是损失值plt.ylabel('Cost') ### 加上引号,变成字符串plt.xlabel('Epoch') ### 加上引号,变成字符串plt.show()输出结果:
Predict (before training) 4 4.0Epoch: 0 w= 1.0933333333333333 loss= 4.666666666666667Epoch: 1 w= 1.1779555555555554 loss= 3.8362074074074086Epoch: 2 w= 1.2546797037037036 loss= 3.1535329869958857Epoch: 3 w= 1.3242429313580246 loss= 2.592344272332262Epoch: 4 w= 1.3873135910979424 loss= 2.1310222071581117......Epoch: 96 w= 1.9999254544053418 loss= 3.154680994333735e-08Epoch: 97 w= 1.9999324119941766 loss= 2.593287985380858e-08Epoch: 98 w= 1.9999387202080534 loss= 2.131797981222471e-08Epoch: 99 w= 1.9999444396553017 loss= 1.752432687141379e-08Predict (after training) 4 7.999777758621207但是以后的深度学习下降曲线难免是不稳定下降的(曲线刺刺的),所以可以来做个加权均值使曲线平滑。
如果学习率太大,也有可能梯度不降反升。
四、随机梯度下降算法
Stochastic Gradient Descent:
拿单个样本的损失对权重求导,由单个样本实现跨越鞍点前进。
以下是SGD代码,相较于批量梯度下降代码进行了更新:
x_data = [1.0, 2.0, 3.0]y_data = [2.0, 4.0, 6.0]
w = 1.0
def forward(x): return x * w
def loss(x, y):###以前是cost 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 = w - 0.01 * grad print("\tgrad: ", x, y, grad) l = loss(x, y)
print("progress:", epoch, "w=", w, "loss=", l)
print('Predict (after training)', 4, forward(4))注意:但是在真正的DL里,在计算梯度时,用批量梯度下降算法可并行,但是用SGD无法并行,时间效率低下。最后会取折中——Batch——批量的随机梯度下降。(正式称为Mini—Batch,但由于现在论文中Batch居多,于是都成为Batch了)
版权声明
本文采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处。




