從零開始:教你如何訓練神經網路

機器之心發表於2019-02-16

選自TowardsDataScience

作者:Vitaly Bushaev

機器之心編譯

作者從神經網路簡單的數學定義開始,沿著損失函式、啟用函式和反向傳播等方法進一步描述基本的優化演算法。在理解這些基礎後,本文詳細描述了動量法等當前十分流行的學習演算法。此外,本系列將在後面介紹 Adam 和遺傳演算法等其它重要的神經網路訓練方法。

I. 簡介

本文是作者關於如何「訓練」神經網路的一部分經驗與見解,處理神經網路的基礎概念外,這篇文章還描述了梯度下降(GD)及其部分變體。此外,該系列文章將在在後面一部分介紹了當前比較流行的學習演算法,例如:

  • 動量隨機梯度下降法(SGD)
  • RMSprop 演算法
  • Adam 演算法(自適應矩估計)
  • 遺傳演算法

作者在第一部分以非常簡單的神經網路介紹開始,簡單到僅僅足夠讓人理解我們所談論的概念。作者會解釋什麼是損失函式,以及「訓練」神經網路或者任何其他的機器學習模型到底意味著什麼。作者的解釋並不是一個關於神經網路全面而深度的介紹,事實上,作者希望我們讀者已經對這些相關的概念早已瞭然於心。如果讀者想更好地理解神經網路具體是如何執行的,讀者可以閱讀《深度學習》等相關書籍,或參閱文末提供的相關學習資源列表。

本文作者以幾年前在 kaggle 上進行的貓狗鑑別競賽(https://www.kaggle.com/c/dogs-vs-cats)為例來解釋所有的東西。在這個比賽中我們面臨的任務是,給定一張圖片,判斷圖中的動物是貓還是狗。

II. 定義神經網路

人工神經網路(ANN)的產生受到了人腦工作機制的啟發。儘管這種模擬是很不嚴格的,但是 ANN 確實和它們生物意義上的創造者有幾個相似之處。它們由一定數量的神經元組成。所那麼,我們來看一下一個單獨的神經元吧。

從零開始:教你如何訓練神經網路

單個神經元

我們接下來要談論的神經元是一個與 Frank Rosenblatt 在 1957 年提出的最簡單的被稱作「感知機,perception」的神經元稍微有所不同的版本。我所做的所有修改都是為了簡化,因為我在這篇文章中不會涉及神經網路的深入解釋。我僅僅試著給讀者給出一個關於神經網路如何工作的直覺認識。

什麼是神經元呢?它是一個數學函式,並以一定量的數值作為輸入(隨便你想要多少作為輸入),我在上圖畫出的神經元有兩個輸入。我們將每個輸入記為 x_k,這裡 k 是輸入的索引。對於每一個輸入 x_k,神經元會給它分配另一個數 w_k,由這些引數 w_k 組成的向量叫做權重向量。正是這些權值才使得每個神經元都是獨一無二的。在測試的過程中,權值是不會變化的,但是在訓練的過程中,我們要去改變這些權值以「調節」我們的網路。我會在後面的文章中討論這個內容。正如前面提到的,一個神經元就是一個數學函式。但是它是哪種函式呢?它是權值和輸入的一種線性組合,還有基於這種組合的某種非線性函式。我會繼續做進一步解釋。讓我們來看一下首先的線性組合部分。

從零開始:教你如何訓練神經網路

輸入和權值的線性組合。

上面的公式就是我提到的線性組合。我們要將輸入和對應的權值相乘,然後對所有的結果求和。結果就會一個數字。最後一部分—就是給這個數字應用某種非線性函式。今天最常用的非線性函式即一種被稱作 ReLU(rectified linear unit) 的分段線性函式,其公式如下:

從零開始:教你如何訓練神經網路

線性整流單元的表示式。

如果我們的數字大於 0,我們就會使用這個數字,如果它小於 0,我們就會用 0 去代替它。這個被用線上性神經元上的非線性函式被稱作啟用函式。我們必須使用某種非線性函式的原因在後面會變得很明顯。總結一下,神經元使用固定數目的輸入和(標量),並輸出一個標量的啟用值。前面畫出的神經元可以概括成一個公式,如下所示:

從零開始:教你如何訓練神經網路

將我要寫的內容稍微提前一下,如果我們以貓狗鑑別的任務為例,我們會把圖片作為神經元的輸入。也許你會疑問:當神經元被定義為函式的時候,如何向它傳遞圖片。你應該記住,我們將圖片儲存在計算機中的方式是將它拿一個陣列代表的,陣列中的每一個數字代表一個畫素的亮度。所以,將圖片傳遞到神經元的方式就是將 2 維(或者 3 維的彩色圖片)陣列展開,得到一個一維陣列,然後將這些數字傳遞到神經元。不幸的是,這會導致我們的神經網路會依賴於輸入圖片的大小,我們只能處理由神經網路定義的某個固定大小的圖片。現代神經網路已經發現瞭解決這個問題的方法,但是我們在這裡還是在這個限制下設計神經網路。

現在我們定義一下神經網路。神經網路也是一個數學函式,它就是很多相互連線的神經元,這裡的連線指的是一個神經元的輸出被用為另一個神經元的輸入。下圖是一個簡單的神經網路,希望用這張圖能夠將這個定義解釋得更加清楚。

從零開始:教你如何訓練神經網路

一個簡單的神經網路。

上圖定義的神經網路具有 5 個神經元。正如你所看到的,這個神經網路由 3 個全連線層堆疊而成,即每一層的每個神經元都連線到了下一層的每一個神經元。你的神經網路有多少層、每一層有多少個神經元、神經元之間是怎麼連結的,這這些因素共同定義了一個神經網路的架構。第一層叫做輸入層,包含兩個神經元。這一層的神經元並不是我之前所說的神經元,從某種意義而言,它並不執行任何計算。它們在這裡僅僅代表神經網路的輸入。而神經網路對非線性的需求源於以下兩個事實:1)我們的神經元是連在一起的;2)基於線性函式的函式還是線性的。所以,如果不對每個神經元應用一個非線性函式,神經網路也會是一個線性函式而已,那麼它並不比單個神經元強大。最後一點需要強調的是:我們通常是想讓一個神經網路的輸出大小在 0 到 1 之間,所以我們會將它按照概率對待。例如,在貓狗鑑別的例子中,我們可以把接近於 0 的輸出視為貓,將接近於 1 的輸出視為狗。為了完成這個目標,我們會在最後一個神經元上應用一個不同的啟用函式。我們會使用 sigmoid 啟用函式。關於這個啟用函式,你目前只需要知道它地返回值是一個介於 0 到 1 的數字,這正好是我們想要的。解釋完這些之後,我們可以定義一個和上圖對應的神經網路了。

從零開始:教你如何訓練神經網路

定義一個神經網路的函式。w 的上標代表神經元的索引,下標代表輸入的索引。

最後,我們得到了某種函式,它以幾個數作為輸入,輸出另一個介於 0 到 1 之間的數。實際上,這個函式怎樣表達並不重要,重要的是我們通過一些權重將一個非線性函式引數化了,我們可以通過改變這些權重來改變這個非線性函式。

III. 損失函式

在開始討論神經網路的訓練之前,最後一個需要定義的就是損失函式了。損失函式是一個可以告訴我們,神經網路在某個特定的任務上表現有多好的函式。做這件事的最直覺的辦法就是,對每一個訓練樣本,都沿著神經網路傳遞得到一個數字,然後將這個數字與我們想要得到的實際數字做差再求平方,這樣計算出來的就是預測值與真實值之間的距離,而訓練神經網路就是希望將這個距離或損失函式減小。

從零開始:教你如何訓練神經網路

上式中的 y 代表我們想要從神經網路得到的數字,y hat 指的一個樣本通過神經網路得到的實際結果,i 是我們的訓練樣本的索引。我們還是以貓狗鑑別為例。我們有一個資料集,由貓和狗的圖片組成,如果圖片是狗,對應的標籤是 1,如果圖片是貓,對應的標籤是 0。這個標籤就是對應的 y,在向神經網路傳遞一張圖片的時候我們想通過神經網路的得到的結果。為了計算損失函式,我們必須遍歷資料集中的每一張圖片,為每一個樣本計算 y,然後按照上面的定義計算損失函式。如果損失函式比較大,那麼說明我們的神經網路效能並不是很好,我們想要損失函式儘可能的小。為了更深入地瞭解損失函式和神經網路之間的聯絡,我們可以重寫這個公式,將 y 換成網路的實際函式。

IV. 訓練

在開始訓練神經網路的時候,要對權值進行隨機初始化。顯然,初始化的引數並不會得到很好的結果。在訓練的過程中,我們想以一個很糟糕的神經網路開始,得到一個具有高準確率的網路。此外,我們還希望在訓練結束的時候,損失函式的函式值變得特別小。提升網路是有可能的,因為我們可以通過調節權值去改變函式。我們希望找到一個比初始化的模型效能好很多的函式。

問題在於,訓練的過程相當於最小化損失函式。為什麼是最小化損失而不是最大化呢?結果證明損失是比較容易優化的函式。

有很多用於函式優化的演算法。這些演算法可以是基於梯度的,也可以不是基於梯度的,因為它們既可以使用函式提供的資訊,還可以使用函式梯度提供的資訊。最簡單的基於梯度的演算法之一叫做隨機梯度下降(SGD),這也是我在這篇文章中要介紹的演算法。讓我們來看一下它是如何執行的吧。

首先,我們要記住關於某個變數的導數是什麼。我們拿比較簡單的函式 f(x) = x 為例。如果還記得高中時候學過的微積分法則,我們就會知道,這個函式在每個 x 處的導數都是 1。那麼導數能夠告訴我們哪些資訊呢?導數描述的是:當我麼讓自變數朝正方向變化無限小的步長時,函式值變化有多快的速率。它可以寫成下面的數學形式:

它的意思是:函式值的變化量(方程的左邊)近似等於函式在對應的某個變數 x 處的導數與 x 的增量的乘積。回到我們剛才所舉的最簡單的例子 f(x) = x,導數處處是 1,這意味著如果我們將 x 朝正方向變化一小步ε,函式輸出的變化等於 1 和ε的乘積,剛好是ε本身。檢查這個規則是比較容易的。實際上這個並不是近似值,它是精確的。為什麼呢?因為我們的導數對於每一個 x 都是相同的。但是這並不適用於絕大多數函式。讓我們來看一個稍微複雜一點的函式 f(x) = x^2。

從零開始:教你如何訓練神經網路

通過微積分知識我們可以知道,這個函式的導數是 2*x。現在如果我們從某個 x 開始移動某個步長的ε,很容易能夠發現對應的函式增量並不精確地等於上面的公式中的計算結果。

現在,梯度是由偏導陣列成的向量,這個向量的元素是這個函式所依賴的某些變數對應的導數。對於我們目前所考慮的簡單函式來說,這個向量只有一個元素,因為我們所用的函式只有一個輸入。對於更加複雜的函式(例如我們的損失函式)而言,梯度會包含函式對應的每個變數的導數。

為了最小化某個損失函式,我們可以怎麼使用這個由導數提供的資訊呢?還是回到函式 f(x) = x^2。顯然,這個函式在 x=0 的點取得最小值,但是計算機如何知道呢?假設我們開始的時候得到的 x 的隨機初始值為 2,此時函式的導數等於 4。這意味著如果 x 朝著正方向改變,函式的增量會是 x 增量的 4 倍,因此函式值反而會增加。相反,我們希望最小化我們的函式,所以我們可以朝著相反的方向改變 x,也就是負方向,為了確保函式值降低,我們只改變一小步。但是我們一步可以改變多大呢? 我們的導數只保證當 x 朝負方向改變無限小的時候函式值才會減小。因此,我們希望用一些超引數來控制一次能夠改變多大。這些超引數叫做學習率,我們後面會談到。我們現在看一下,如果我們從-2 這個點開始,會發生什麼。這裡的導數是-4,這意味著如果朝著正方向改變 x,函式值會變小,這正是我們想要的結果。

注意到這裡的規律了嗎?當 x>0 的時候,我們導數值也大於 0,我們需要朝著負方向改變,當 x<0 的時候,我們導數值小於 0,我們需要朝著正方向改變,我們總需要朝著導數的反方向改變 x。讓我們對梯度也引用同樣的思路。梯度是指向空間某個方向的向量,實際上它指向的是函式值增加最劇烈的方向。由於我們要最小化我們的函式,所以我們會朝著與梯度相反的方向改變自變數。現在在我們應用這個思想。在神經網路中,我們將輸入 x 和輸出 y 視為固定的數。我們要對其求導數的變數是權值 w,因為我們可以通過改變這些權值類提升神經網路。如果我們對損失函式計算權值對應的梯度,然後朝著與梯度相反的方向改變權值,我們的損失函式也會隨之減小,直至收斂到某一個區域性極小值。這個演算法就叫做梯度下降。在每一次迭代中更新權重的演算法如下所示:

從零開始:教你如何訓練神經網路

每一個權重值都要減去它對應的導數和學習率的乘積。

上式中的 Lr 代表的是學習率,它就是控制每次迭代中步長大小的變數。這是我們在訓練神經網路的時候要調節的重要超引數。如果我麼選擇的學習率太大,會導致步進太大,以至於跳過最小值,這意味著你的演算法會發散。如果你選擇的學習率太小,收斂到一個區域性極小值可能會花費太多時間。人們開發出了一些很好的技術來尋找一個最佳的學習率,然而這個內容超出本文所涉及的範圍了。

不幸的是,我們不能應用這個演算法來訓練神經網路,原因在於損失函式的公式。

正如你可以在我之前的定義中看到的一樣,我們損失函式的公式是和的平均值。從微積分原理中我們可以知道,微分的和就是和的微分。所以,為了計算損失函式的梯度,我們需要遍歷我們的資料集中的每一個樣本。在每一次迭代中進行梯度下降是非常低效的,因為演算法的每次迭代僅僅以很小的步進提升了損失函式。為了解決這個問題,還有另外一個小批量梯度下降演算法。該演算法更新權值的方法是不變的,但是我們不會去計算精確的梯度。相反,我們會在資料集的一個小批量上近似計算梯度,然後使用這個梯度去更新權值。Mini-batch 並不能保證朝著最佳的方向改變權值。事實上,它通常都不會。在使用梯度下降演算法的時候,如果所選擇的學習率足夠小的話,能夠保證你的損失函式在每一次迭代中都會減小。但是使用 Mini-batch 的時候並不是這樣。你的損失函式會隨著時間減小,但是它會有波動,也會具有更多的「噪聲」。

用來估計梯度的 batch 大小是你必須選擇的另一個超引數。通常,我們希望儘可能地選擇能處理的較大 batch。但是我很少見到別人使用比 100 還大的 batch size。

mini-batch 梯度下降的極端情況就是 batch size 等於 1,這種形式的梯度下降叫做隨機梯度下降(SGD)。通常在很多文獻中,當人們說隨機梯度下降的時候,實際上他們指的就是 mini-batch 隨機梯度下降。大多數深度學習框架都會讓你選擇隨機梯度下降的 batch size。

以上是梯度下降和它變體的基本概念。但近來越來越多的人在使用更高階的演算法,其中大多數都是基於梯度的,作者下一部分就主要介紹這些最優化方法。

VII. 反向傳播(BP)

關於基於梯度的演算法,剩下的唯一一件事就是如何計算梯度了。最快速的方法就是解析地給出每一個神經元架構的導數。我想,當梯度遇到神經網路的時候,我不應該說這是一個瘋狂的想法。我們在前面定義的一個很簡單的神經網路就已經相當艱難了,而它只有區區 6 個引數。而現代神經網路的引數動輒就是數百萬。

第二種方法就是使用我們從微積分中學到的下面的這個公式去近似計算梯度,事實上這也是最簡單的方法。

從零開始:教你如何訓練神經網路

儘管這個方法是非常容易實現的,但是它卻是非常耗計算資源的。

最後一種計算梯度的方法,是對解析難度和計算成本的折中,這個方法被稱作反向傳小節。反向傳播不在本文的討論範圍,如果你想了解更多的話,可以檢視 Goodfellow《深度學習》第六章第五小節,該章節對反向傳播演算法有非常詳盡的介紹。

VI. 它為什麼會起作用?

當我初次瞭解神經網路以及它是如何工作的時候,我理解所有的方程,但是我不是十分確定它們為啥會起作用。這個想法對我而言有些怪誕:用幾個函式,求一些導數,最終會得到一個能夠認出圖片中是貓還是狗。為什麼我不能給你們一個很好的關於為啥神經網路會如此好的奏效的直覺知識呢?請注意以下兩個方面。

1. 我們想要用神經網路解決的問題必須被以數學的形式表達出來。例如,對於對於貓狗鑑別:我們需要找到一個函式,它能夠把一副圖片中的所有畫素作為輸入,然後輸出圖片中的內容是狗的概率。你可以用這種方法去定義任何一個分類問題。

2. 或許並不是很清楚,為什麼會有一個能夠從一副圖片中把貓和狗區分開來的函式。這裡的思想是:只要你有一些具有輸入和標籤的資料集,總會存在一個能夠在一個給定資料集上效能良好的函式。問題在於這個函式會相當複雜。這時候神經網路就能夠有所幫助了。有一個「泛逼近性原理,universal approximation theorem」,指的是具有一個隱藏層的神經網路可以近似任何一個你想要的的函式,你想要它近似得多好,就能有多好。

動量隨機梯度下降演算法

-這是關於訓練神經網路和機器學習模型優化演算法系列的第二部分,第一部分是關於隨機梯度下降的。在這一部分,假定讀者對神經網路和梯度下降演算法已有基本瞭解。如果讀者對神經網路一無所知,或者不知道神經網路是如何訓練的,可以在閱讀這部分之前閱讀第一部分。

在本節中,除了經典的 SGD 演算法外,我們還會對動量法進行討論,這種演算法一般比隨機梯度下降演算法更好更快。動量法 [1] 或具有動量的 SGD 是一種方法,這種方法有助於加速向量向著正確的方向梯度下降,從而使其收斂速度更快。這是最流行的優化演算法之一,許多各方向上最先進的模型都是用這種方法進行訓練的。在講高階的演算法相關方程之前,我們先來看一些有關動量的基礎數學知識。

指數加權平均

指數加權平均用於處理數字序列。假設我們有一些嘈雜的序列 S。在這個例子中,我繪製了餘弦函式並新增了一些高斯噪聲。如下圖所示:

從零開始:教你如何訓練神經網路

注意,儘管這些點看起來非常接近,但它們的 x 座標是不同的。也就是說,對每個點而言,其 x 座標是唯一的標識,因此這也是定義序列 S 中每個點的索引。

我們需要處理這些資料,而非直接使用它們。我們需要某種「移動」的平均值,這個平均值會使資料「去噪」從而使其更接近原始函式。指數加權平均值可以產生如下所示的圖片:

從零開始:教你如何訓練神經網路

動量——來自指數加權平均的資料

如我們所見,這是一個相當不錯的結果。與噪聲很大的資料相比,我們得到了更平滑的曲線,這意味著與初始資料相比,我們得到了與原始函式更接近的結果。指數加權平均值用下面的公式定義了新的序列 V:

從零開始:教你如何訓練神經網路

序列 V 是上面的散點圖中的黃色部分。Beta 是取值為 0 到 1 的另一個超引數。在上述例子中,取 Beta = 0.9。0.9 是一個很好的值,經常用於具有動量的 SGD 方法。我們可以這樣對 Beta 進行直觀理解:我們對序列後面的 1 /(1- beta)的點進行近似平均。讓我們看看 beta 的選擇會對新序列 V 產生怎樣的影響。

從零開始:教你如何訓練神經網路

Beta 取值不同時的指數加權平均結果。

如我們所見,Beta 取值越小,序列 V 波動越大。因為我們平均的例子更少,因此結果與噪聲資料更「接近」。隨著 Beta 值越大,比如當 Beta = 0.98 時,我們得到的曲線會更加圓滑,但是該曲線有點向右偏移,因為我們取平均值的範圍變得更大(beta = 0.98 時取值約為 50)。Beta = 0.9 時,在這兩個極端間取得了很好的平衡。

數學部分

這個部分對你在專案中使用動量而言不是必要的,所以可以跳過。但這部分更直觀地解釋了動量是如何工作的。

讓我們對指數加權平均新序列 V 的三個連續元素的定義進行擴充套件。

從零開始:教你如何訓練神經網路

V——新序列。S——原始序列。

將其進行合併,我們可以得到:

從零開始:教你如何訓練神經網路

再對其進行簡化,可得:

從零開始:教你如何訓練神經網路

從這個等式中可以看出,新序列的第 T 個值取決於原始序列 S 的所有先前的數值 1…t。來自 S 的所有數值被賦了一定的權重。這個權重是序列 S 的第(t-i)個值乘以(1- beta)得到的權重。因為 Beta 小於 1,所以當我們對某個正數的冪取 beta 時,值會變得更小。所以序列 S 的原始值的權重會小得多,也因此序列 S 對序列 V 產生的點積影響較小。從某些角度來說,該權重小到我們幾乎可以說我們「忘記」了這個值,因為其影響小到幾乎無法注意到。使用這個近似值的好處在於當權重小於 1 / e 時,更大的 beta 值會要求更多小於 1 / e 的權值。這就是為什麼 beta 值越大,我們就要對更多的點積進行平均。下面的圖表顯示的是與 threshold = 1 / e 相比,隨著序列 S 初始值變化,權重變小的速度,在此我們「忘記」了初始值。

從零開始:教你如何訓練神經網路

最後要注意的是,第一次迭代得到的平均值會很差,因為我們沒有足夠的值進行平均。我們可以通過使用序列 V 的偏差修正版而不是直接使用序列 V 來解決這一問題。

從零開始:教你如何訓練神經網路

式中 b = beta。當 t 值變大時,b 的 t 次冪與零無法進行區分,因此不會改變 V 值。但是當 t 取值較小時,這個方程會產生較好的結果。但是因為動量的存在使得機器學習過程穩定得很快,因此人們通常會懶得應用這一部分。

動量 SGD 法

我們已經定義了一種方法來獲得一些序列的「移動」平均值,該值會與資料一起變化。我們該如何將其應用於神經網路的訓練中呢?它可以平均我們的梯度。我將在下文中解釋它是如何在動量中完成的這一工作,並將繼續解釋為什麼它可能會得到更好的效果。

我將提供兩個定義來定義具有動量的 SGD 方法,這幾乎就是用兩種不同的方式表達同一個方程。首先,是吳恩達在 Coursera 深度學習專業化(https://www.deeplearning.ai/)的課程中提出的定義。他解釋的方式是,我們定義一個動量,這是我們梯度的移動平均值。然後我們用它來更新網路的權重。如下所示:

從零開始:教你如何訓練神經網路

式中 L 是損失函式,三角形符號是梯度 w.r.t 權重,α 是學習率。另一種最流行的表達動量更新規則的方式不那麼直觀,只是省略了(1 – beta)項。

從零開始:教你如何訓練神經網路

這與第一組方程式非常相似,唯一的區別是需要通過(1 – β)項來調整學習率。

Nesterov 加速漸變

Nesterov 動量是一個版本略有不同的動量更新,最近越來越受歡迎。在這個版本中,首先會得到一個當前動量指向的點,然後從這個點計算梯度。如下圖所示:

從零開始:教你如何訓練神經網路

Nesterov 動量可用下式定義:

從零開始:教你如何訓練神經網路

動量工作原理

在這裡我會解釋為什麼在絕大多數情況下動量法會比經典 SGD 法更好用。

使用隨機梯度下降的方法,我們不會計算損失函式的確切導數。相反,我們是對一小批資料進行估算的。這意味著我們並不總是朝著最佳的方向前進,因為我們得到的結果是「嘈雜的」。正如我在上文中列出的圖表。所以,指數的加權平均可以提供一個更好的估計值,該估計值比通過嘈雜計算得到的結果更接近實際值的導數。這就是動量法可能比傳統 SGD 更好的原因之一。

另一個原因在於溝谷(ravine)。溝谷是一個區域,在其中,曲線在一個維度比另一個維度陡得多。在深度學習中,溝谷區可近似視為區域性最低點,而這一特性無法用 SGD 方法得到。SGD 傾向於在狹窄的溝谷上擺動,因為負梯度將沿著陡峭的一側下降,而非沿著溝谷向最優點前進。動量有助於加速梯度向正確的方向前進。如下圖所示:

從零開始:教你如何訓練神經網路

左圖——沒有動量的 SGD,右圖——有動量的 SGD(來源:https://www.willamette.edu/~gorr/classes/cs449/momrate.html

結論

希望本節會提供一些關於具有動量的 SGD 方法是如何起作用以及為什麼會有用的想法。實際上它是深度學習中最流行的優化演算法之一,與更高階的演算法相比,這種方法通常被人們更頻繁地使用。

參考資源

  • fast.ai(http://fast.ai/) :它針對程式設計師提供了兩個很不錯的關於深度學習的課程,以及一個關於可計算線性代數的課程。是開始編寫神經網路程式碼的好地方,隨著課程深度的延伸,當你學到更多理論的時候,你可以儘快用程式碼實現。
  • http://neuralnetworksanddeeplearning.comhttp://neuralnetworksanddeeplearning.com/chap1.html):一本關於基本知識的很好的線上書籍。關於神經網路背後的理論。作者以一種很好的方式解釋了你需要知道的數學知識。它也提供並解釋了一些不使用任何深度學習框架從零開始編寫神經網路架構的程式碼。
  • Andrew Ng 的深度學習課程(https://www.coursera.org/specializations/deep-learning):coursera 上的課程,也是有關學習神經網路的。以非常簡單的神經網路例子開始,逐步到卷積神經網路以及更多。
  • 3Blue1Brown(https://www.youtube.com/channel/UCYO_jab_esuFRV4b17AJtAw):YouTube 上也有一些能夠幫助你理解神經網路和線性代數的很好的視訊。它們展示了很棒的視覺化形式,以及以非常直覺的方式去理解數學和神經網路。
  • Stanford CS231 課程(http://cs231n.stanford.edu/):這是關於用於視覺識別的卷積神經網路的課堂,可以學到很多關於深度學習和卷積神經網路的具體內容。

參考文獻

[1] Ning Qian. On the momentum term in gradient descent learning algorithms . Neural networks : the official journal of the International Neural Network Society, 12(1):145–151, 1999

[2] Distill, Why Momentum really works(https://distill.pub/2017/momentum/

[3] deeplearning.ai

[4] Ruder(2016). An overview of gradient descent optimization algorithms. arXiv preprint arXiv:1609.04747

[5] Ruder (2017) Optimization for Deep Learning Highlights in 2017.(http://ruder.io/deep-learning-optimization-2017/index.html

[6] Stanford CS231n lecture notes.(http://cs231n.github.io/neural-networks-3/)(http://cs231n.github.io/neural-networks-3/%EF%BC%89)

[7] fast.ai(http://www.fast.ai/

原文連結:

第一部分:https://towardsdatascience.com/how-do-we-train-neural-networks-edd985562b73

第二部分 :Stochastic Gradient Descent with momentum (https://quip.com/tJ7sAxbyrwZg)

https://towardsdatascience.com/stochastic-gradient-descent-with-momentum-a84097641a5d

本文為機器之心編譯,轉載請聯絡本公眾號獲得授權。

相關文章