6.9 Adadelta算法
“長(zhǎng)江后浪推前浪,一浪更比一浪高”。RMSProp算法對(duì)Adagrad算法在學(xué)習(xí)率上進(jìn)行了改進(jìn)。同時(shí)期,其他的研究者還提出了不同的改進(jìn)算法。其中比較典型的就是Adadelta算法啦。在優(yōu)化算法的發(fā)展史上留下了值得炫耀的一筆,本節(jié)咱們就來(lái)介紹下。
6.9.1?基本原理
從時(shí)間線上來(lái)看,Adagrad算法是由John Duchi、Eliza Singer和Yoshua Bengio在2011年提出的。RMSProp算法是由Geoffrey Hinton在2012年提出的。Adadelta算法是由Matthew D. Zeiler在2012年提出的。基本上是腳前腳后,同一個(gè)時(shí)期。
Adadelta是一種自適應(yīng)學(xué)習(xí)率的方法,用于神經(jīng)網(wǎng)絡(luò)的訓(xùn)練過(guò)程中。它的基本思想是避免使用手動(dòng)調(diào)整學(xué)習(xí)率的方法來(lái)控制訓(xùn)練過(guò)程,而是自動(dòng)調(diào)整學(xué)習(xí)率,使得訓(xùn)練過(guò)程更加順暢。
Adadelta算法主要由兩部分組成:梯度積分和更新規(guī)則。
梯度積分:在每一個(gè)時(shí)刻,我們可以計(jì)算出每一層的梯度。梯度積分即是對(duì)這些梯度進(jìn)行累加,并記錄下來(lái)。
更新規(guī)則:我們通過(guò)使用梯度積分來(lái)更新每一層的權(quán)重。我們使用如下公式來(lái)計(jì)算權(quán)重的更新量:

我們使用這個(gè)公式來(lái)計(jì)算權(quán)重的更新量,并更新權(quán)重。這樣,我們就實(shí)現(xiàn)了使用自適應(yīng)學(xué)習(xí)率來(lái)訓(xùn)練神經(jīng)網(wǎng)絡(luò)的目的。
6.9.2?優(yōu)缺點(diǎn)
從優(yōu)點(diǎn)來(lái)說(shuō),Adadelta算法自動(dòng)調(diào)整學(xué)習(xí)率,使得訓(xùn)練過(guò)程更加順暢。它不需要手動(dòng)調(diào)整學(xué)習(xí)率,可以省去調(diào)參的時(shí)間,而且能夠在訓(xùn)練過(guò)程中避免出現(xiàn)“飽和”現(xiàn)象,使得訓(xùn)練更加穩(wěn)定。
從缺點(diǎn)來(lái)看,它可能會(huì)收斂得比較慢,因?yàn)樗粫?huì)顯式地調(diào)整學(xué)習(xí)率。此外,它需要維護(hù)梯度和權(quán)重更新量的積分,可能會(huì)增加空間復(fù)雜度。
6.9.3?代碼示例
在下面這個(gè)例子中,我們將演示用一個(gè)簡(jiǎn)單的神經(jīng)網(wǎng)絡(luò)來(lái)擬合y=x^2這個(gè)函數(shù),選取均方誤差作為損失函數(shù),使用Adadelta算法來(lái)優(yōu)化權(quán)重。
import?torch
import?torch.nn?as?nn
import?matplotlib.pyplot?as?plt
#?定義一個(gè)簡(jiǎn)單的網(wǎng)絡(luò)
class?Net(nn.Module):
????def?__init__(self):
????????super(Net,?self).__init__()
????????self.fc1?=?nn.Linear(1,?10)
????????self.fc2?=?nn.Linear(10,?1)
????
????def?forward(self, x):
????????x?=?self.fc1(x)
????????x?=?self.fc2(x)
????????return?x
#?隨機(jī)生成訓(xùn)練數(shù)據(jù)
x?=?torch.randn(100,?1)
y?=?x.pow(2)?+?0.1?*?torch.randn(100,?1)
#?實(shí)例化網(wǎng)絡(luò)
net?=?Net()
#?定義損失函數(shù)和優(yōu)化器
criterion?=?nn.MSELoss()
optimizer?=?torch.optim.Adadelta(net.parameters())
#?記錄訓(xùn)練損失
losses?=?[]
#?開始訓(xùn)練
for?epoch?in?range(100):
????#?前向傳播?+?反向傳播?+?優(yōu)化
????output?=?net(x)
????loss?=?criterion(output, y)
????optimizer.zero_grad()
????loss.backward()
????optimizer.step()
????#?記錄損失
????losses.append(loss.item())
#?繪制訓(xùn)練損失圖
plt.plot(losses)
plt.show()

在訓(xùn)練過(guò)程中,每隔一個(gè)epoch記錄一次損失,最后繪制損失的變化圖??梢钥吹诫S著訓(xùn)練的進(jìn)行,損失逐漸減少。這說(shuō)明網(wǎng)絡(luò)的權(quán)重在逐漸擬合訓(xùn)練數(shù)據(jù)。
梗直哥提示:這個(gè)例子只是為了給出一個(gè)大致的框架,幫助你理解如何使用Adadelta算法來(lái)訓(xùn)練一個(gè)網(wǎng)絡(luò)。你可以根據(jù)自己的需要來(lái)修改代碼,例如調(diào)整網(wǎng)絡(luò)的結(jié)構(gòu)、使用不同的數(shù)據(jù)集等。
?同步更新:
公眾號(hào):梗直哥