PyTorch学习笔记6 - 理解更多神经网络优化方法

本篇笔记的完整代码:https://github.com/ChenWentai/PyTorch/blob/master/task6.py

1. 优化器(Optimizer)简介

在backprop更新权重时,一般采用SGD(Stochastic Gradient Descent)作为优化器。其实除了SGD以外,还有很多其他的优化器可供选择。

1.1 BGD (Batch Gradient Descent)和 SGD

在每一轮的训练过程中,BDG算法用整个训练集的数据计算cost fuction的梯度,并用该梯度对模型参数进行更新。这样在cost function为凸函数的情况下,可以收敛到全局最优。但是由于每轮迭代都需要在整个数据集上计算一次,所以批量梯度下降可能非常慢解。
W = W -\lambda \frac{dE(W;x,y)}{dW} \tag{1.1.1}
相比之下,SGD每次只采用一个样本来计算cost function,大大节省了计算空间,提升了效率。
W = W -\lambda \frac{dE(W;x_{i},y_{i})}{dW} \tag{1.1.2}
在BGD和SGD之间还有一种折中的方法:Mini-batch Gradient Descent,即每次只是用一部分样本来计算cost function对W的梯度。
W = W -\lambda \frac{dE(W;x_{i:i+n},y_{i:i+n})}{dW} \tag{1.1.3}

1.2 SGD with momentum

SGD方法的一个缺点是其更新方向完全依赖于当前batch计算出的梯度,若batch选取不具有代表性,则结果会十分不稳定。而Momentum机制会观察历史梯度v_{t-1},若当前梯度的方向与历史梯度一致(表明当前样本不太可能为异常点),则会增强这个方向的梯度,若当前梯度与历史梯方向不一致,则梯度会衰减,如公式(1.2)和图1所示
\begin{equation}\begin{split} v_{t} = \gamma v_{t-1} + \lambda \frac{dE(W)}{dW}\\ W = W - v_{t}\:\:\:\:\:\:\:\:\:\:\:\\ \end{split}\end{equation} \tag{1.2}

图1 Momentum

1.3 Nesterov Momentum

Nesterov Momentum通过将一部分梯度更新加入到现有的求梯度公式中,在Momentum的基础上减小了误差,如式(1.3)和图2所示:
\begin{equation}\begin{split} v_{t} = \gamma v_{t-1} + \lambda \frac{dE(W-\gamma v_{t-1})}{dW}\\ W = W - v_{t}\:\:\:\:\:\:\:\:\:\:\:\\ \end{split}\end{equation} \tag{1.2}

图2 Nesterov Momentum

1.4 Adagrad

Adagrad的思想是根据现有的学习率(learning rate)来更新权重,能够在学习的过程中自适应地对学习率进行调整,可以看做是learning rate schedular的一个类型。
\begin{equation}\begin{split} G_{i}^{t-1} = \sum_{T=0}^{t-1}(\frac{dE(W_{i}^{T} )}{dW})^{2}\:\:\:\:\:\\ W_{i}^{t} = W_{i}^{t} - \frac{\lambda}{\sqrt{G_{i}^{t-1} + \epsilon}} \frac{dE(W_{i}^{t-1} )}{dW} \end{split}\end{equation} \tag{1.4}
Adagrad的缺点是在训练的中后期,分母上梯度平方的累加将会越来越大,从而梯度趋近于0,使得训练提前结束。

1.5 RMSprop

RMSprop也是一种学习率调整的算法。Adagrad会累加之前所有的梯度平方,而RMSprop仅仅是计算对应的平均值,因此可缓解Adagrad算法学习率下降较快的问题。RMSprop其更新公式如下:
\begin{equation}\begin{split} G_{i}^{t} = \gamma G_{i}^{t-1} + (1-\gamma)(\frac{dE(W_{i}^{t-1} )}{dW})^{2}\\ W_{i}^{t} = W_{i}^{t} - \frac{\lambda}{\sqrt{G_{i}^{t-1} + \epsilon}} \frac{dE(W_{i}^{t-1} )}{dW}\: \end{split}\end{equation} \tag{1.5}

1.6 Adam

Adam的思想是在RMSprop的基础上加入Momentum, 利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。
\begin{equation}\begin{split} m_{i}^{t} = \beta_{1} m_{i}^{t-1} + (1-\beta_{1})\frac{dE(W_i^{t-1})}{dW}\:\: \\ v_{i}^{t} = \beta_{2} v_{i}^{t-1} + (1-\beta_{2})(\frac{dE(W_i^{t-1})}{dW})^2\\ W_{i}^{t} = W_{i}^{t} - \frac{\lambda}{\sqrt{v_{i}^{t} + \epsilon}}m_{i}^t\:\:\:\:\:\:\:\:\:\:\ \end{split}\end{equation} \tag{1.6}

2 使用numpy模拟不同的优化器

#构造数据:J为损失函数,J_prime为损失函数的导数
import numpy as np
import matplotlib.pyplot as plot
J = lambda w1, w2: w1**2+10*w2**2
J_prime1 = lambda w1: 2*w1
J_prime2 = lambda w2: 2*w2
w1 = 1
w2 = -1
epoch = 200
lr = 0.1

#SGD
Loss_sgd = []
W1_sgd = []
W2_sgd = []
for i in range(epoch):
    w1 -= lr*J_prime1(w1)
    w2 -= lr*J_prime2(w2)
    W1_sgd.append(w1)
    W2_sgd.append(w2)
    Loss_sgd.append(J(w1, w2))

# Momentum
gamma = 0.5
v1 = 0
v2 = 0
s = 0
Loss_moment = []
W1_moment = []
W2_moment = []
for i in range(epoch):
    v1 = gamma*v1 + lr*J_prime1(w1)
    w1 -= v1
    v2 = gamma*v2 + lr*J_prime2(w2)
    w2 -= v2    
    W1_moment.append(w1)
    W2_moment.append(w2)
    Loss_moment.append(J(w1, w2))

#Adagrad
v = 0
s = 0
Loss_ada = []
W1_ada = []
W2_ada = []
s1=s2=0
for i in range(epoch):
    s1 += J_prime1(w1)**2
    w1 -= lr*(J_prime1(w1)/np.sqrt(s1))
    s2 += J_prime2(w2)**2
    w2 -= lr*(J_prime2(w2)/np.sqrt(s2))
    W1_ada.append(w1)
    W2_ada.append(w2)
    Loss_ada.append(J(w1, w2))

    #RMSprop
epoch = 200
lambda0 = 0.01
gamma = 0.5
v = 0
s = 0
Loss_RMS = []
W1_RMS = []
W2_RMS = []
s1=s2=0
for i in range(epoch):
    s1 = gamma*s1 + (1-gamma)*(J_prime1(w1)**2)
    w1 -= lambda0*(J_prime1(w1)/np.sqrt(s1))
    s2 = gamma*s2 + (1-gamma)*(J_prime2(w2)**2)
    w2 -= lambda0*(J_prime2(w2)/np.sqrt(s2))
    W1_RMS.append(w1)
    W2_RMS.append(w2)
    Loss_RMS.append(J(w1, w2))

#画出loss和weight的曲线
LOSS = [Loss_sgd, Loss_moment, Loss_ada, Loss_RMS]
labels = ['SGD', 'Momentum','Adagrad','RMSprop']
for i, loss in enumerate(LOSS):
    plt.plot(loss, label=labels[i])
plt.legend()
plt.xlabel('epoch')
plt.ylabel('loss')
plt.title('Loss')
plt.savefig('./task6/Loss.jpg', dpi=500)
plt.show()

W1 = [W1_sgd, W1_moment, W1_ada, W1_RMS]
for i, w1 in enumerate(W1):
    plt.plot(w1, label=labels[i])
plt.legend()
plt.xlabel('epoch')
plt.ylabel('W1')
plt.title('W1')
plt.savefig('./task6/W1.jpg', dpi=500)
plt.show()

W2 = [W2_sgd, W2_moment, W2_ada, W2_RMS]
for i, w2 in enumerate(W2):
    plt.plot(w2, label=labels[i])
plt.legend()
plt.xlabel('epoch')
plt.ylabel('W2')
plt.title('W2')
plt.savefig('./task6/W2.jpg', dpi=500)
plt.show()

作出不同优化器loss和权值更新曲线:

图3. 不同优化器的Loss

图4. 不同优化器的W1更新

图5. 不同优化器的W2更新

由图3-图5可以看到,对于loss函数,SGD有着最快的收敛速度和最陡峭的下降曲线;排在后面的依次是Adagrad, Momentum 和RMSprop[1].

[1] 按照优化器理论,SGD不应该是收敛最快的。可能是因为模拟的损失函数J_{0}过于简单,其他优化器方法减慢收敛速度。具体原因有待进一步探究。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容