梯度下降法快速教程 | 第三章:學習率衰減因子(decay)的原理與Python實現

邀請關注微信公眾號:人工智慧LeadAI(ID:atleadai)

歡迎訪問我們的官方主頁:www.leadai.org

正文共3017個字、11張圖、預計閱讀時間:8分鐘

前言

梯度下降法(Gradient Descent)是機器學習中最常用的優化方法之一,常用來求解目標函數的極值。

其基本原理非常簡單:沿著目標函數梯度下降的方向搜索極小值(也可以沿著梯度上升的方向搜索極大值)。

但是如何調整搜索的步長(也叫學習率,Learning Rate)、如何加快收斂速度以及如何防止搜索時發生震蕩卻是一門值得深究的學問。

上兩篇文章《梯度下降法快速教程 | 第一章:Python簡易實現以及對學習率的探討》與《梯度下降法快速教程 | 第二章:衝量(momentum)的原理與Python實現》分別介紹了學習率大小對搜索過程的影響以及「衝量」的原理以及如何用「衝量」來解決收斂速度慢與收斂時發生震蕩的問題。接下來本篇文章將介紹梯度下降法中的第三個超參數:decay。

PS:本系列文章全部源代碼可在本人的GitHub:monitor1379中下載。

學習率衰減因子:decay

首先先回顧一下不同學習率下梯度下降法的收斂過程(示例代碼在GitHub上可下載):

demo1_GD_lr運行結果

從上圖可看出,學習率較大時,容易在搜索過程中發生震蕩,而發生震蕩的根本原因無非就是搜索的步長邁的太大了。

回顧一下問題本身,在使用梯度下降法求解目標函數func(x) = x * x的極小值時,更新公式為x += v,其中每次x的更新量v為v = - dx * lr,dx為目標函數func(x)對x的一階導數。可以想到,如果能夠讓lr隨著迭代周期不斷衰減變小,那麼搜索時邁的步長就能不斷減少以減緩震蕩。學習率衰減因子由此誕生:

lr_i = lr_start * 1.0 / (1.0 + decay * i)

上面的公式即為學習率衰減公式,其中lr_i為第i次迭代時的學習率,lr_start為原始學習率,decay為一個介於[0.0, 1.0]的小數。

從公式上可看出:

  • decay越小,學習率衰減地越慢,當decay = 0時,學習率保持不變。
  • decay越大,學習率衰減地越快,當decay = 1時,學習率衰減最快。

使用decay的梯度下降法Python實現代碼如下:

import numpy as npimport matplotlib.pyplot as plt# 目標函數:y=x^2def func(x):n return np.square(x)# 目標函數一階導數:dy/dx=2*xdef dfunc(x):n return 2 * xdef GD_decay(x_start, df, epochs, lr, decay):n """n 帶有學習率衰減因子的梯度下降法。n :param x_start: x的起始點n :param df: 目標函數的一階導函數n :param epochs: 迭代周期n :param lr: 學習率n :param decay: 學習率衰減因子n :return: x在每次迭代後的位置(包括起始點),長度為epochs+1n """n xs = np.zeros(epochs+1)n x = x_startn xs[0] = xn v = 0n for i in range(epochs):n dx = df(x) # 學習率衰減n lr_i = lr * 1.0 / (1.0 + decay * i) # v表示x要改變的幅度n v = - dx * lr_in x += vn xs[i+1] = x return xsn

使用以下測試與繪圖代碼demo3_GD_decay來看一下當學習率依次為lr = [0.1, 0.3, 0.9, 0.99]與decay = [0.0, 0.01, 0.5, 0.9]時的效果如何:

def demo3_GD_decay(): nline_x = np.linspace(-5, 5, 100) nline_y = func(line_x) nplt.figure(Gradient Desent: Decay) nx_start = -5 nepochs = 10 nlr = [0.1, 0.3, 0.9, 0.99] ndecay = [0.0, 0.01, 0.5, 0.9] ncolor = [k, r, g, y] nrow = len(lr) ncol = len(decay) nsize = np.ones(epochs + 1) * 10 nsize[-1] = 70 n for i in range(row): nfor j in range(col): nx = GD_decay(x_start, dfunc, epochs, lr=lr[i], decay=decay[j]) nplt.subplot(row, col, i * col + j + 1) nplt.plot(line_x, line_y, c=b) nplt.plot(x, func(x), c=color[i], label=lr={}, de={}.format(lr[i], decay[j])) nplt.scatter(x, func(x), c=color[i], s=size) nplt.legend(loc=0)nplt.show()n

運行結果如下圖所示,其中每行圖片的學習率一樣、decay依次增加,每列圖片decay一樣,學習率依次增加:

demo3_GD_decay運行結果

簡單分析一下結果:

  • 在所有行中均可以看出,decay越大,學習率衰減地越快。
  • 在第三行與第四行可看到,decay確實能夠對震蕩起到減緩的作用。

那麼,不同decay下學習率的衰減速度到底有多大的區別呢?接下來設置起始學習率為1.0,decay依次為[0.0, 0.001, 0.1, 0.5, 0.9, 0.99],迭代周期為300時學習率衰減的情況,測試與繪圖代碼如下:

def demo4_how_to_chose_decay():n lr = 1.0n iterations = np.arange(300)nn decay = [0.0, 0.001, 0.1, 0.5, 0.9, 0.99] for i in range(len(decay)):n decay_lr = lr * (1.0 / (1.0 + decay[i] * iterations))n plt.plot(iterations, decay_lr, label=decay={}.format(decay[i]))nn plt.ylim([0, 1.1])n plt.legend(loc=best)n plt.show()n

運行結果如下圖所示。可以看到,當decay為0.1時,50次迭代後學習率已從1.0急劇降低到了0.2。如果decay設置得太大,則可能會收斂到一個不是極值的地方呢。看來調參真是任重而道遠:

demo4_how_to_chose_decay運行結果

後記

關於「梯度下降法」的三個超參數的原理、實現以及優缺點已經介紹完畢。對機器學習、深度學習與計算機視覺感興趣的童鞋可以關注本博主的簡書博客以及GitHub:monitor1379哦~後續將繼續上更多的硬幹貨,謝謝大家的支持。

原文鏈接:http://www.jianshu.com/p/d8222a84613c

查閱更為簡潔方便的分類文章以及最新的課程、產品信息,請移步至全新呈現的

leadai.org

關注人工智慧LeadAI公眾號,查看更多專業文章

weixin.qq.com/r/ZDnC2j- (二維碼自動識別)

大家都在看

LSTM模型在問答系統中的應用

基於TensorFlow的神經網路解決用戶流失概覽問題

最全常見演算法工程師面試題目整理(一)

最全常見演算法工程師面試題目整理(二)

TensorFlow從1到2 | 第三章 深度學習革命的開端:卷積神經網路

裝飾器 | Python高級編程

今天不如來複習下Python基礎


推薦閱讀:

為什麼梯度的負方向是局部下降最快的方向?
詳解softmax函數以及相關求導過程
為什麼梯度下降演算法(BGD批量梯度下降)用的是所有樣本點梯度的均值作為最終的梯度方向?
圖像處理中加權直方圖是什麼意思?
隨機梯度下降和正則項之間如何處理?

TAG:梯度下降 | Python |