日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人工智能 > pytorch >内容正文

pytorch

图解深度学习-梯度下降法优化器可视化(SGD, Momentum,Adam, Adagrad and RMSProp)

發布時間:2023/12/9 pytorch 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 图解深度学习-梯度下降法优化器可视化(SGD, Momentum,Adam, Adagrad and RMSProp) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

圖解深度學習-梯度下降法優化器可視化(SGD, Momentum,Adam, Adagrad and RMSProp

    • 前言
    • 定義了4個基本函數
    • 機器學習原理
    • 原始的梯度下降算法
    • 帶動量的梯度下降算法
    • 帶慣性的梯度下降算法
    • Adagrad 自適應調整的梯度下降
    • RMSProp
    • Adam

前言

主要用了Jupyter Notebook的插件ipywidgets,可以進行交互,可以自己調整參數來看結果,用于理解來說非常好,今后也會繼續用這些東西來做圖解深度學習,主要代碼來自鏈接,框架是他的,我主要做了點修改,更加方便理解和調試,可以動手改變學習率,訓練次數等一些參數,可視化非常友好,當然也可以自己改變咯。提供下修改后的jupyter的文件鏈接

%matplotlib inline import numpy as np import matplotlib.pyplot as plt from matplotlib import ticker, cm import seaborn as sns from ipywidgets import * import math#繪圖元素比例 比較小 sns.set_context('paper', font_scale=2) #設置顯示中文字體 font = {'family' : 'SimHei', # 'weight' : 'bold','size' : '15'} plt.rc('font', **font) # 步驟一(設置字體的更多屬性) plt.rc('axes', unicode_minus=False) # 步驟二(解決坐標軸負數的負號顯示問題)

定義了4個基本函數

  • f_2d(x1, x2) 定義了一個簡單的 2 維函數,f(x1,x2)=0.5x12+2x22f(x_1, x_2) = 0.5 x_1^2 + 2x_2^2f(x1?,x2?)=0.5x12?+2x22?. 我們的目標是使用這個函數測試各種梯度下降算法,尋找極小值點。
  • f_grad(x1, x2) 計算 f_2d() 沿兩個方向的梯度
  • train_2d() 函數使用給用的梯度下降算法,迭代N步,返回更新數據,即x1,x2的值
  • plot_2d() 函數畫出 f_2d 函數的等高圖以及N步更新軌跡
  • 學習率,迭代次數,變量初始值均可在空間中調試,方便觀察
  • def f_2d(x1, x2):'''優化的目標函數 有2個變量'''return 0.5 * x1 ** 2 + 2 * x2 ** 2def f_grad(x1, x2):'''x1和x2的梯度'''dfdx1 = x1dfdx2 = 4 * x2return dfdx1, dfdx2def train_2d(trainer, lr,epoch=50,init_x1=-4,init_x2=-4):"""自定義訓練器:trainerlr:學習率epoch:輪次init_x1:x1的初始值 便于觀察init_x2:x1的初始值"""x1, x2 = init_x1, init_x2s_x1, s_x2 = 0, 0res = [(x1, x2)]for i in range(epoch):x1, x2, s_x1, s_x2, lr = trainer(x1, x2, s_x1, s_x2, lr)res.append((x1, x2))return resdef plot_2d(res, figsize=(10, 8), title=None):x1_, x2_ = zip(*res)fig = plt.figure(figsize=figsize)plt.plot([0], [0], 'r*', ms=15)plt.text(0.0, 0.25, '最小值', color='k')plt.plot(x1_[0], x2_[0], 'ro', ms=10)plt.text(x1_[0]+0.2, x2_[0]-0.15, '起點', color='k')plt.plot(x1_, x2_, '-o', color='r')plt.plot(x1_[-1], x2_[-1], 'bo',ms=10)plt.text(x1_[-1]+0.1, x2_[-1]-0.4, '終點', color='k')x1 = np.linspace(-5,5, 100)x2 = np.linspace(-5,5, 100)x1, x2 = np.meshgrid(x1, x2)#畫出等高線區域,并用彩虹顏色填充,設置透明度cp=plt.contourf(x1, x2, f_2d(x1, x2),alpha=0.75, cmap=cm.rainbow)#畫出等高線C=plt.contour(x1, x2, f_2d(x1, x2),colors='black')plt.clabel(C,inline=True,fontsize=15)cbar = fig.colorbar(cp)cbar.set_label('損失值')plt.xlabel('x1')plt.ylabel('x2')plt.title(title)plt.show()x1,x2=res[-1]loss=f_2d(x1,x2)print('最小損失值:',loss,'x1:',x1,' x2:',x2)

    機器學習原理

    機器學習是一種新的編程模式。這種模式先假設任何輸入 x 與輸出 y 之間存在連續幾何變換,
    其函數形式可用 y=f(x,θ)y= f(x, \theta)y=f(x,θ) 表示。其中 θ\thetaθ 是函數參數,初始化為隨機數。
    注意,初始化過程并不任意,這里有一篇很好的文章講參數初始化
    deeplearning.ai。

    機器學習通過逐步微調函數參數 θ\thetaθ的方式,試圖最小化模型預言 y^\hat{y}y^? 與真實標簽 yyy的差別。
    此差別最簡單的數學表達式是 MAE 或者 MSE,即
    L(θ)=∣y^?y∣L(\theta) = |\hat{y} - y|L(θ)=y^??y

    L(θ)=∣y^?y∣2L(\theta) = |\hat{y} - y|^2L(θ)=y^??y2

    為了最小化誤差 L(θ)L(\theta)L(θ), 我們只需要計算誤差對參數 θ\thetaθ 的梯度,通過鏈式規則,
    將誤差反向傳遞到 θ\thetaθ, 并使用梯度下降,更新θ\thetaθ 即可。

    如果增加 θ\thetaθ, 損失函數 L(θ)L(\theta)L(θ) 增大,那么損失函數對參數θ\thetaθ的梯度為正數, 即 ?θL(θ)>0\nabla_{\theta} L(\theta) > 0?θ?L(θ)>0,
    只要將 θ\thetaθ 減去一個正數 η??θL(θ)\eta \cdot \nabla_{\theta} L(\theta)η??θ?L(θ) 即可使損失函數減小。
    其中 η\etaη 是學習率 (Learning Rate, 簡寫為 lr),為一個很小的正數。

    如果增加 θ\thetaθ, 損失函數 L(θ)L(\theta)L(θ) 變小,那么 ?θL(θ)&lt;0\nabla_{\theta} L(\theta) &lt; 0?θ?L(θ)<0,
    θ\thetaθ 減去一個負數 η??θL\eta \cdot \nabla_{\theta} Lη??θ?L 同樣可使損失函數減小。
    你發現無論梯度是正是負,只要將參數減去學習率乘以梯度,總可以將損失降低。

    這就是梯度下降的原理!

    接下來會以交互式可視化的方式,展示幾種最常用的梯度下降算法。

    原始的梯度下降算法

    θ=θ?η??θL(θ)\theta = \theta - \eta \cdot \nabla_{\theta} L(\theta)θ=θ?η??θ?L(θ)

    #最原始的梯度下降法 def sgd(x1, x2, s1, s2, lr):dfdx1, dfdx2 = f_grad(x1, x2)return (x1 - lr * dfdx1, x2 - lr * dfdx2, 0, 0, lr)#定義了4個變量控件,可以隨時調節,查看效果 (最小值,最大值,步長) @interact(lr=(0, 1, 0.001),epoch=(0,100,1),init_x1=(-5,5,0.1),init_x2=(-5,5,0.1),continuous_update=False) def visualize_gradient_descent(lr=0.05,epoch=50,init_x1=-4,init_x2=-2.4):res = train_2d(sgd, lr,epoch,init_x1,init_x2)plot_2d(res,(12,8), title='原始SGD')

    帶動量的梯度下降算法

    vt=γvt?1+η??θL(θ)v_t = \gamma v_{t-1} + \eta \cdot \nabla_{\theta} L(\theta)vt?=γvt?1?+η??θ?L(θ)
    θ=θ?vt\theta = \theta - v_tθ=θ?vt?

    可見下圖。對以前的梯度做了指數加權平均,不會像原始的那樣直接折線那么厲害,因為有之前速度影響,所以瞬間就折,而是會再向原來那個方向前進一段距離,也可以理解為對原始梯度做了一個平滑,然后再用來做梯度下降

    @interact(lr=(0, 0.99, 0.001), gamma=(0, 0.99, 0.001),continuous_update=False,epoch=(0,100,1),init_x1=(-5,5,0.1),init_x2=(-5,5,0.1)) def visualize_sgd_momentum(lr=0.1, gamma=0.1,epoch=10,init_x1=-4,init_x2=-2.4):'''lr: learning rategamma: parameter for momentum sgd每次都會根據上一次的動量來進行更新'''def momentum(x1, x2, v1, v2, lr):dfdx1, dfdx2 = f_grad(x1, x2)v1 = gamma * v1 + lr * dfdx1v2 = gamma * v2 + lr * dfdx2x1 = x1 - v1x2 = x2 - v2return (x1, x2, v1, v2, lr)res = train_2d(momentum, lr,epoch,init_x1,init_x2)plot_2d(res, title='momentum')

    帶慣性的梯度下降算法

    vt=γvt?1+(1?γ)??θL(θ)v_t = \gamma v_{t-1} + (1 - \gamma) \cdot \nabla_{\theta} L(\theta)vt?=γvt?1?+(1?γ)??θ?L(θ)
    θ=θ?ηvt\theta = \theta - \eta v_tθ=θ?ηvt?

    @interact(lr=(0, 0.99, 0.01), gamma=(0, 0.99, 0.01),continuous_update=False,epoch=(0,100,1),init_x1=(-5,5,0.1),init_x2=(-5,5,0.1)) def visualize_sgd_inertia(lr=0.1, gamma=0.1,epoch=10,init_x1=-4,init_x2=-2.4):'''lr: learning rategamma: parameter for inertia sgd'''def inertia(x1, x2, v1, v2, lr):dfdx1, dfdx2 = f_grad(x1, x2)v1 = gamma * v1 + (1 - gamma) * dfdx1v2 = gamma * v2 + (1 - gamma) * dfdx2x1 = x1 - lr * v1x2 = x2 - lr * v2return (x1, x2, v1, v2, lr)res = train_2d(inertia, lr,epoch,init_x1,init_x2)plot_2d(res, title='inertia')

    Adagrad 自適應調整的梯度下降

    gt=?θL(θ)g_t = \nabla_{\theta} L(\theta)gt?=?θ?L(θ)

    G=∑tgt2G = \sum_{t} g_t^2G=t?gt2?

    θ=θ?ηG+??gt\theta = \theta - \frac{\eta}{\sqrt{G + \epsilon}} \cdot g_tθ=θ?G+??η??gt?

    可以自動調節學習率,但是下降的太快,學習率很小,可能導致后期學不到東西了
    此方法也經常用于參數未標準化時,提供不通的學習率,以便于快速到達最小點

    @interact(lr=(0, 4, 0.01),continuous_update=False,epoch=(0,100,1),init_x1=(-5,5,0.1),init_x2=(-5,5,0.1)) def visualize_adagrad(lr=0.1,epoch=10,init_x1=-4,init_x2=-2.4):'''lr: learning rate'''def adagrad_2d(x1, x2, s1, s2, lr):g1, g2 = f_grad(x1, x2)eps = 1e-6s1 += g1 ** 2s2 += g2 ** 2x1 -= lr / math.sqrt(s1 + eps) * g1x2 -= lr / math.sqrt(s2 + eps) * g2return x1, x2, s1, s2, lrres = train_2d(adagrad_2d, lr,epoch,init_x1,init_x2)plot_2d(res, title='Adagrad')

    RMSProp

    g=?θL(θ)g = \nabla_{\theta} L(\theta) g=?θ?L(θ)

    E[g2]=γE[g2]+(1?γ)g2E\left[g^2\right] = \gamma E\left[g^2\right] + (1-\gamma) g^2 E[g2]=γE[g2]+(1?γ)g2

    θ=θ?ηE[g2]+??g\theta = \theta - \frac{\eta}{\sqrt{E\left[g^2\right] + \epsilon}} \cdot gθ=θ?E[g2]+??η??g

    對Adagrad做了相應修改,讓學習率不會下降了太快導致后期學不到東西,相當于做了歸一化,調整不同參數的步長,加快收斂速度

    @interact(lr=(0, 4, 0.001), gamma=(0, 0.99, 0.001),continuous_update=False,epoch=(0,100,1),init_x1=(-5,5,0.1),init_x2=(-5,5,0.1)) def visualize_rmsprop(lr=0.1, gamma=0.9,epoch=50,init_x1=-4,init_x2=-4):'''lr: learning rate, gamma: momentum''' def rmsprop_2d(x1, x2, s1, s2, lr):eps = 1e-6g1, g2 = f_grad(x1, x2)s1 = gamma * s1 + (1 - gamma) * g1 ** 2s2 = gamma * s2 + (1 - gamma) * g2 ** 2x1 -= lr / math.sqrt(s1 + eps) * g1x2 -= lr / math.sqrt(s2 + eps) * g2return x1, x2, s1, s2, lrres = train_2d(rmsprop_2d, lr,epoch,init_x1,init_x2)plot_2d(res, title='RMSProp')

    Adam

    g=?θL(θ)g = \nabla_{\theta} L(\theta) g=?θ?L(θ)

    m=β1m+(1?β1)gm = \beta_1 m + (1 - \beta_1) g m=β1?m+(1?β1?)g

    n=β2n+(1?β2)g2n = \beta_2 n + (1 - \beta_2) g^2 n=β2?n+(1?β2?)g2

    m^=m(1?β1t)\hat{m} = \frac{m}{(1 - \beta_1^t)} m^=(1?β1t?)m?

    n^=n(1?β2t)\hat{n} = \frac{n}{(1 - \beta_2^t)} n^=(1?β2t?)n?

    θ=θ?ηn^+?m^\theta = \theta - \frac{\eta}{\sqrt{\hat{n}} + \epsilon} \hat{m}θ=θ?n^?+?η?m^

    結合Momentum和RMSProp的2個特征,即做指數加權平均,又做歸一化

    @interact(lr=(0, 1, 0.001), beta1=(0, 0.999, 0.001),beta2=(0, 0.999, 0.001),continuous_update=False,epoch=(0,100,1),init_x1=(-5,5,0.1),init_x2=(-5,5,0.1)) def visualize_adam(lr=0.1, beta1=0.9, beta2=0.999,epoch=10,init_x1=-4,init_x2=-2.4):'''lr: learning ratebeta1: parameter for E(g)beta2: parameter for E(g^2)''' def Deltax(m, n, g, t):eps = 1.0E-6m = beta1 * m + (1 - beta1) * gn = beta2 * n + (1 - beta2) * g*gm_hat = m / (1 - beta1**t)n_hat = n / (1 - beta2**t)dx = lr * m_hat / (math.sqrt(n_hat) + eps)return m, n, dxdef adam_2d(x1, x2, m1, n1, m2, n2, lr, t):'''m1, m2: E(g1), E(g2)n1, n2: E(g1^2), E(g2^2) where E() is expectationlr: learning ratet: time step'''eps = 1e-6g1, g2 = f_grad(x1, x2)m1, n1, dx1 = Deltax(m1, n1, g1, t)m2, n2, dx2 = Deltax(m2, n2, g2, t) x1 -= dx1x2 -= dx2return x1, x2, m1, n1, m2, n2, lrdef train_adam(trainer, lr,epoch=10,init_x1=-4,init_x2=-4):"""Train a 2d object function with a customized trainer"""x1, x2 = init_x1,init_x2m1, n1, m2, n2 = 0, 0, 0, 0res = [(x1, x2)]for i in range(epoch):x1, x2, m1, n1, m2, n2, lr = trainer(x1, x2, m1, n1, m2, n2, lr, i+1)res.append((x1, x2))return resres = train_adam(adam_2d, lr,epoch,init_x1,init_x2)plot_2d(res, title='adam')

    好了,今天就到這里了,希望對學習理解有幫助,大神看見勿噴,僅為自己的學習理解,能力有限,請多包涵。

    總結

    以上是生活随笔為你收集整理的图解深度学习-梯度下降法优化器可视化(SGD, Momentum,Adam, Adagrad and RMSProp)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。