7.2 梯度下降和隨機(jī)梯度下降
在本節(jié)中塔嬉,我們將介紹梯度下降(gradient descent)的工作原理。雖然梯度下降在深度學(xué)習(xí)中很少被直接使用,但理解梯度的意義以及沿著梯度反方向更新自變量可能降低目標(biāo)函數(shù)值的原因是學(xué)習(xí)后續(xù)優(yōu)化算法的基礎(chǔ)谋右。隨后,我們將引出隨機(jī)梯度下降(stochastic gradient descent)豹爹。
7.2.1 一維梯度下降
image.png
%matplotlib inline
import numpy as np
import torch
import math
import sys
sys.path.append("..")
import d2lzh_pytorch as d2l
image.png
def gd(eta):
x = 10
results = [x]
for i in range(10):
x -= eta * 2 * x # f(x) = x * x的導(dǎo)數(shù)為f'(x) = 2 * x
results.append(x)
print('epoch 10, x:', x)
return results
res = gd(0.2)
輸出:
epoch 10, x: 0.06046617599999997
image.png
def show_trace(res):
n = max(abs(min(res)), abs(max(res)), 10)
f_line = np.arange(-n, n, 0.1)
d2l.set_figsize()
d2l.plt.plot(f_line, [x * x for x in f_line])
d2l.plt.plot(res, [x * x for x in res], '-o')
d2l.plt.xlabel('x')
d2l.plt.ylabel('f(x)')
show_trace(res)
image.png
7.2.2 學(xué)習(xí)率
image.png
show_trace(gd(0.05))
輸出:
epoch 10, x: 3.4867844009999995
image.png
image.png
show_trace(gd(1.1))
輸出:
epoch 10, x: 61.917364224000096
image.png
7.2.3 多維梯度下降
image.png
image.png
def train_2d(trainer): # 本函數(shù)將保存在d2lzh_pytorch包中方便以后使用
x1, x2, s1, s2 = -5, -2, 0, 0 # s1和s2是自變量狀態(tài)赘艳,本章后續(xù)幾節(jié)會使用
results = [(x1, x2)]
for i in range(20):
x1, x2, s1, s2 = trainer(x1, x2, s1, s2)
results.append((x1, x2))
print('epoch %d, x1 %f, x2 %f' % (i + 1, x1, x2))
return results
def show_trace_2d(f, results): # 本函數(shù)將保存在d2lzh_pytorch包中方便以后使用
d2l.plt.plot(*zip(*results), '-o', color='#ff7f0e')
x1, x2 = np.meshgrid(np.arange(-5.5, 1.0, 0.1), np.arange(-3.0, 1.0, 0.1))
d2l.plt.contour(x1, x2, f(x1, x2), colors='#1f77b4')
d2l.plt.xlabel('x1')
d2l.plt.ylabel('x2')
image.png
eta = 0.1
def f_2d(x1, x2): # 目標(biāo)函數(shù)
return x1 ** 2 + 2 * x2 ** 2
def gd_2d(x1, x2, s1, s2):
return (x1 - eta * 2 * x1, x2 - eta * 4 * x2, 0, 0)
show_trace_2d(f_2d, train_2d(gd_2d))
輸出:
epoch 20, x1 -0.057646, x2 -0.000073
image.png
7.2.4 隨機(jī)梯度下降
image.png
def sgd_2d(x1, x2, s1, s2):
return (x1 - eta * (2 * x1 + np.random.normal(0.1)),
x2 - eta * (4 * x2 + np.random.normal(0.1)), 0, 0)
show_trace_2d(f_2d, train_2d(sgd_2d))
輸出:
epoch 20, x1 -0.047150, x2 -0.075628
image.png
可以看到,隨機(jī)梯度下降中自變量的迭代軌跡相對于梯度下降中的來說更為曲折吼拥。這是由于實(shí)驗所添加的噪聲使模擬的隨機(jī)梯度的準(zhǔn)確度下降。在實(shí)際中线衫,這些噪聲通常指訓(xùn)練數(shù)據(jù)集中的無意義的干擾凿可。
小結(jié)
- 使用適當(dāng)?shù)膶W(xué)習(xí)率,沿著梯度反方向更新自變量可能降低目標(biāo)函數(shù)值授账。梯度下降重復(fù)這一更新過程直到得到滿足要求的解枯跑。
- 學(xué)習(xí)率過大或過小都有問題。一個合適的學(xué)習(xí)率通常是需要通過多次實(shí)驗找到的白热。
- 當(dāng)訓(xùn)練數(shù)據(jù)集的樣本較多時敛助,梯度下降每次迭代的計算開銷較大,因而隨機(jī)梯度下降通常更受青睞屋确。
參考文獻(xiàn)
[1] Stewart, J. (2010). Calculus: early transcendentals. 7th ed. Cengage Learning.
注:本節(jié)與原書基本相同纳击,原書傳送門