1. 程式人生 > >【深度學習】神經網路的優化方法

【深度學習】神經網路的優化方法

前言

\quad\quad 我們都知道,神經網路的學習目的是找到使損失函式的值儘可能小的引數,這是一個尋找最優引數的問題,解決這個問題的過程可以稱為最優化,但由於引數空間非常複雜,無法輕易找到最優解,而且在深度學習中,引數的數量非常大,導致最優化問題更加複雜。

\quad\quad

在這之前,我們是將引數的梯度(導數)作為線索,使引數沿著梯度方向更新,並重復執行多次,從而逐漸靠近最優引數,這個過程稱為隨機梯度下降法(SGD)

SGD是一個簡單的方法,但是比起胡亂地搜尋引數空間,也算是“聰明”的方法
但是,針對不同的問題,SGD並不一定是最好的,SGD也存在自身的缺陷

下面我們介紹幾種常用的最優化方法,並python實現

SGD

  • 數學表示式
    W
    W η L
    W
    W \leftarrow W - \eta \frac{\partial L}{\partial W}

W W 為權重引數, η \eta 為學習率, L W \frac{\partial L}{\partial W} 表示損失函式關於 W W 的梯度
一般 η \eta 取 0.01 或 0.001

  • python實現
class SGD:
    """隨機梯度下降法"""
    def __init__(self, lr=0.01):
        self.lr = lr  # 學習率
        
    # params,grads是字典型資料,比如params['W1'],grads['W1']   
    # 儲存了權重引數和他們的梯度
    def update(self, params, grads):  
        for key in params.keys():
        	# 根據SGD公式
            params[key] -= self.lr * grads[key] 
  • 神經網路中如何使用
# 構建網路
network = TwoLayerNet(...)
# 選擇最優化方法(如果需要其他方法,可以改用其他的方法)
optimizer = SGD()
# 學習
for i in range(10000):
	# 批資料
	x_batch, t_batch = get_mini_batch(...)
	# 求梯度
	grads = network.gradient(x_batch, t_batch)
	# 權重引數
	params = network.params
	# 優化,更新權重引數
	optimizer.update(params, grads)

上面程式碼是進行神經網路引數更新的一般步驟,其中optimizer 就是進行引數最優化的物件

  • 如果我們有了新的最優化方法,就可以建立一個和SGD類似的類,裡面也包括update方法,這樣只需要將上面程式碼中的optimizer = SGD()換成自己定義的類
  • SGD的缺點

在這裡插入圖片描述

如果,梯度方向不指向最小值的方向,就會以相對低效的路徑更新,出現如圖的“之”型
容易收斂到區域性最優,並且容易被困在鞍點
為了改正SGD的缺陷,出現了Momentum、AdaGrad、Adam等方法

Momentum

  • 數學表示式
    v α v η L W v \leftarrow \alpha v - \eta \frac{\partial L}{\partial W}
    W W + v W \leftarrow W + v

這裡出現了一個新變數 v v ,對應物理上的速度
式中, α v \alpha v 這一項表示在物體不受任何力時,該項承擔物體逐漸減速的任務( α \alpha 設定為0.9之類)

在這裡插入圖片描述

一開始,梯度為負,小球加速向下執行(梯度可以表示為加速度),並且加速度減小
當梯度為0(加速度為0),由於 v α v v \leftarrow \alpha v ,速度逐漸減小,也就是小球還會往右邊運動,這樣避免陷入區域性最小值

  • python實現
class Momentum:

    """Momentum SGD"""

    def __init__(self, lr=0.01, momentum=0.9):
        self.lr = lr  # 學習率
        self.momentum = momentum  #動量
        self.v = None  # 什麼都不儲存,第一次呼叫update時,會以字典形式儲存與引數結構相同的資料
        
    def update(self, params, grads):
        if self.v is None:
            self.v = {}
            for key, val in params.items():                                
                self.v[key] = np.zeros_like(val)
                
        for key in params.keys():
            self.v[key] = self.momentum*self.v[key] - self.lr*grads[key] 
            params[key] += self.v[key]
  • 評價

和SGD相比,Momentum可以更快地朝最小值靠近,減弱“之”字型的變動程度

AdaGrad

在神經網路學習中,學習率的值很重要。學習率過小,會導致學習花費過多時間;學習率過大,會導致學習發散而不能正確進行

  • 學習率衰減

在這裡插入圖片描述

隨著學習的進行,是學習率逐漸減小,一開始“多”學,然後逐漸“少”學

上面學習率衰減是針對所有引數的,而AdaGrad是針對“每個”引數,賦予其“定製”的值,也就是每個引數的學習率不同;AdaGrad會為每個元素適當的調整學習率

  • 數學表示式
    h h + L W L W h \leftarrow h + \frac{\partial L}{\partial W} \odot \frac{\partial L}{\partial W}
    W W η 1 h L W W \leftarrow W - \eta \frac{1}{\sqrt h}\frac{\partial L}{\partial W}

\odot 表示對應矩陣元素相乘,在更新引數時,通過更改 1 h \frac{1}{\sqrt h} 就可以調整學習的尺度
這意味著,引數的元素中變化較大的元素的學習率將變小,這樣就可以按引數的元素進行學習率衰減,使變動大的引數的學習率逐漸減小

  • python實現
class AdaGrad:

    """AdaGrad"""

    def __init__(self, lr=0.01):
        self.lr = lr
        self.h = None
        
    def update(self, params, grads):
        if self.h is None:
            self.h = {}
            for key, val in params.items():
                self.h[key] = np.zeros_like(val)
            
        for key in params.keys():
            self.h[key] += grads[key] * grads[key]
            params[key] -= self.lr * grads[key] / (np.sqrt(self.h[key]) + 1e-7)  # 加上1e-7為了避免有0

Adam

Adam的理論有些複雜,直觀上,就是上面兩種方法的結合。

  • 數學表示式
    m t = β 1 m t 1 + ( 1 β 1 ) L W m_t = \beta_1m_{t-1} + (1-\beta_1)\frac{\partial L}{\partial W}
    v t = β 2 v t 1 + ( 1 β 2 ) L W L W v_t = \beta_2v_{t-1} + (1-\beta_2)\frac{\partial L}{\partial W} \odot \frac{\partial L}{\partial W}
    m t ^ = m t 1 β 1 t \hat{m_t} = \frac{m_t}{1-\beta_1^t}
    v t ^ = v t 1 β 2 t \hat{v_t} = \frac{v_t}{1-\beta_2^t}

    相關推薦

    深度學習神經網路優化方法

    前言 \quad\quad 我們都知道,神經網路的學習目的是找到使損失函式的值儘可能小的引數,這是一個尋找最優引數的

    深度學習神經網路學習過程

    神經網路的學習 \quad\quad 線上性可分的與非門、或門的感知機模型中,我們可以根據真值表人工設定引數來實現,

    深度學習神經網路

    原址:http://tieba.baidu.com/p/3013551686?pid=49703036815&see_lz=1# 我們先從迴歸(Regression)問題說起,要讓機器學會觀察並總結規律的言論。具體地說,要讓機器觀察什麼是圓的,什麼是方的,區分各種顏

    深度學習深入理解優化器Optimizer演算法(BGD、SGD、MBGD、Momentum、NAG、Adagrad、Adadelta、RMSprop、Adam)

    1.http://doc.okbase.net/guoyaohua/archive/284335.html 2.https://www.cnblogs.com/guoyaohua/p/8780548.html   原文地址(英文論文):https://www.cnblogs.c

    機器學習神經網路DNN的正則化

    和普通的機器學習演算法一樣,DNN也會遇到過擬合的問題,需要考慮泛化,之前在【Keras】MLP多層感知機中提到了過擬合、欠擬合等處理方法的問題,正則化是常用的手段之一,這裡我們就對DNN的正則化方法做一個總結。 1. DNN的L1&L2正則化 想到正則化,我們首先想到的就是L1正則化和L2正則化

    深度學習Alexnet網路分析及程式碼實現

    簡介 Alexnet是2012年ImageNet比賽的冠軍Hinton及其學生Alex Krizhevsky提出,並以其姓名命名的網路。Alexnet的提出也正式掀起了深度學習的熱潮,激發了研究者對深度學習的熱情。雖然後面出現了更為優秀的VGGNet、GooLeNet、Re

    深度學習網路——悄然興起的深度學習新浪潮

    【深度學習】圖網路——悄然興起的深度學習新浪潮     https://mp.weixin.qq.com/s/mOZDN9u7YCdtYs6DbUml0Q     現實世界中的大量問題都可以抽象成圖模型(Graph Model),

    機器學習神經網路(一)——多類分類問題

    一、問題引入 早在監督學習中我們已經使用Logistic迴歸很好地解決二類分類問題。但現實生活中,更多的是多類分類問題(比如識別10個手寫數字)。本文引入神經網路模型解決多類分類問題。 二、神經網路模型介紹 神經網路模型是一個非常強大的模型,起源於嘗試讓機

    深度學習ResNeXt網路解讀

    1. 網路結構 ResNeXt與resnet基本一致,唯一改動的地方在於resnet三層卷積的layer。它將layer從原來的多個filter卷積核拆分為多個個數少的filter卷積核,這些個數少的filter卷積核結構相同,目的是為了簡化網路設計。在原文中,拆分後的結構

    機器學習神經網路及BP推導

    1 前向傳播 這裡的推導都用矩陣和向量的形式,計算單個變數寫起來太麻煩。矩陣、向量求導可參見上面參考的部落格,個人覺得解釋得很直接很好。 前向傳播每一層的計算如下: z(l+1)=W(l,l+1)a(l)+b(l,l+1)(1.1) a(l+

    機器學習--神經網路(NN)

    簡單介紹:      神經網路主要是預設人類腦結構進行的一種程式碼程式結構的表現,同時是RNN,CNN,DNN的基礎。結構上大體上分為三個部分(輸入,含隱,輸出),各層都有個的講究,其中,輸入層主要是特徵處理後的入口,含隱層用來訓練相應函式,節點越多,訓練出的函式就越複雜,

    火爐煉AI深度學習001-神經網路的基本單元-感知器

    【火爐煉AI】深度學習001-神經網路的基本單元-感知器 (本文所使用的Python庫和版本號: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 ) 在人工智慧領域,深度學習已經脫穎而出,越來越成為大型複雜問題的首選解決方案。深度學習相對

    深度學習Tensorflow——CNN 卷積神經網路 2

    轉自https://morvanzhou.github.io/tutorials/machine-learning/tensorflow/5-05-CNN3/ 目錄 圖片處理  建立卷積層  建立全連線層  選優化方法  完整程式碼

    深度學習Tensorflow——CNN 卷積神經網路 1

    轉自https://morvanzhou.github.io/tutorials/machine-learning/tensorflow/5-04-CNN2/ 這一次我們會說道 CNN 程式碼中怎麼定義 Convolutional 的層和怎樣進行 pooling. 基於上一次卷積神經網路的介

    深度學習卷積神經網路

    講卷積神經網路之前說說為什麼能夠進行分類識別?按照傳統的SIFT,HOG演算法都是先進行特徵的提取過程,那麼卷積神經網路怎麼進行特徵的提取呢?   下面,我們就開始吧! 先提一個小問題:“你是通過什麼瞭解這個世界的?” 當一輛汽車從你身邊疾馳而過,你是通過哪些資訊知道那是一

    深度學習卷積神經網路的卷積層和池化層計算

    一、簡介 \quad\quad 卷積神經網路(Convolutional neural network, CNN),

    深度學習Python實現2層神經網路的誤差反向傳播法學習

    前言 基於計算圖的反向傳播詳解一篇中,我們通過計算圖的形式詳細介紹了構建神經網路需要的層,我們可以將其視為元件,接下來我們只需要將這些元件組合起來就可以實現誤差反向傳播法。 首先我們回顧下神經網路的學習步驟如下: 從訓練資料中隨機選擇一部分資料(mini-batch)

    深度學習Python實現基於數值微分的神經網路學習

    回顧 \quad\quad 在之前的神經網路的學習過程一篇中,我們介紹瞭如何獲取批量資料、損失函式、梯度以及梯度下降

    2014.10神經網路中的深度學習綜述

    本綜述的主要內容包括: 神經網路中的深度學習簡介 神經網路中面向事件的啟用擴充套件表示法 信貸分配路徑(CAPs)的深度及其相關問題 深度學習的研究主題 有監督神經網路/來自無監督神經網路的幫助 FNN與RNN中用於強化學習RL