無需深度學習框架,如何從零開始用Python構建神經網絡

  • Python
  • 程序設計
  • 人工智能
董亞微·長江大學
2018-11-07
閱讀數3349

這是一份用于理解深度學習內部運作方式的初學者指南。作者根據自己從零開始學習用 Python 構建神經網絡的經驗,編寫了一份攻略。內容涵蓋神經網絡定義、損失函數、前向傳播、反向傳播、梯度下降算法,對于想要了解深度學習運作原理的各位來說,內容精彩不可錯過。

 

動機:為了深入了解深度學習,我決定從零開始構建神經網絡,并且不使用類似 Tensorflow 的深度學習庫。我相信,對于任何有理想的數據科學家而言,理解神經網絡內部的運作方式都非常重要。

本文涵蓋了我學到的所有東西,希望你也能從中獲益!

 

什么是神經網絡?

 

許多有關神經網絡的介紹資料會將神經網絡與大腦進行類比。但我發現,將神經網絡簡單地描述為一個從輸入映射到輸出的數學函數理解起來更容易。

 

神經網絡由以下部分組成:

  • 一個輸入層,x

  • 任意數量的隱藏層

  • 一個輸出層,

  • 每兩層之間都有一組權重和偏置,W 和 b

  • 每個隱藏層都要選擇一個激活函數 。在本文中,我們選用 Sigmoid 激活函數。

 

下圖展示了 2 層神經網絡的結構(請注意,在計算神經網絡層數的時候,通常不計入輸入層)。

二層神經網絡的結構

 

利用 Python 建立神經網絡非常容易。

 

訓練神經網絡

 

一個簡單 2 層神經網絡的輸出  可以表示為:

你可能注意到,在上面的等式當中,權重 W 和偏置 b 是影響輸出  的唯一變量。

自然,權重和偏差的正確值決定了預測的強度。根據輸入數據微調權重和偏置的過程稱為神經網絡訓練。

 

訓練過程的每一次迭代包含以下步驟:

  • 計算預測的輸出 ,稱為前向傳播

  • 更新權重和偏置,稱為反向傳播

 

以下流程圖說明了這個過程:

 

前向傳播

 

正如我們在上圖中所看到的,前向傳播只是一個簡單的計算。對于一個基本的 2 層神經網絡,神經網絡的輸出計算如下:

我們可以在 Python 代碼中添加一個前向傳播函數來做到這一點。簡單起見,我們假設偏置為 0。

 

 

然而,我們仍然需要一種方法來評估我們的預測的「優秀程度」(即,我們的預測與真實值相差多少?)這就需要用到損失函數了。

 

損失函數

 

損失函數有很多種,而我們問題的性質會決定我們使用哪種損失函數。在本文中,我們將采用簡單的誤差平方和。

誤差平方和,即每個預測值和真實值之間差值的平均值。這個差值是取了平方項的,所以我們測量的是差值的絕對值。

在訓練過程中,我們的目標是找到一組最佳的權重和偏置,使損失函數最小化。

 

反向傳播

 

現在,我們已經找到了預測誤差的方法(損失函數),那么我們需要一種方法將錯誤「傳播」回去,從而更新權重和偏置。

為了確定權重和偏置調整的適當值,我們需要知道損失函數對權重和偏置的偏導數。

從微積分的角度來看,函數的偏導數也就是函數的斜率。

梯度下降算法

 

如果我們知道了偏導數,我們可以通過簡單增加或減少偏導數(如上圖所示)的方式來更新權重和偏置。這就是所謂的梯度下降。

然而,由于損失函數的方程不包含權重和偏置,所以我們不能直接計算損失函數對權重和偏置的偏導數。因此,我們需要鏈式法則來幫助計算。

以上是用于計算損失函數對權重偏導數的鏈式法則。簡單起見,我們只展示了一層神經網絡的偏導數。

唷!這看起來不大好看,但這能讓我們獲得所需——損失函數對權重的偏導數(斜率),以便相應調整權重。

既然我們已經有了鏈式法則公式,接下來我們把反向傳播函數添加到 Python 代碼中。

 

 

為了更深入地理解微積分和鏈式法則在反向傳播中的應用,我強烈推薦 3Blue1Brown 的視頻教程。

 

整合

 

既然我們已經有了做前向傳播和反向傳播的完整 Python 代碼,我們可以將神經網絡應用到一個示例中,看看它的效果。

我們的神經網絡應該能夠習得理想的權重集合以表示這個函數。請注意,對于我們來說,僅通過檢查來計算權重并非一件小事。

如果我們將神經網絡進行 1500 次迭代,看看會發生什么。下圖展示了每次迭代的損失函數值,我們可以清晰地發現損失函數單調下降到最小值。這與我們前面討論的梯度下降算法是一致的。

讓我們看看神經網絡在進行 1500 次迭代后的最終預測(輸出):

 

進行 1500 次迭代后的預測值

 

我們成功了!我們的前向傳播和反向傳播算法成功訓練了神經網絡,且預測值收斂到了真實值。

請注意,預測值和真實值之間還是有一些輕微差異的。這是可取的,因為它防止了過度擬合,并且使得神經網絡具有更強的泛化能力。

 

下一步

 

幸運的是,我們的探索還沒有結束。關于神經網絡和深度學習還有很多需要學習的地方。例如:

  • 除了 Sigmoid 函數之外,我們還可以使用哪些激活函數?

  • 在訓練神經網絡時使用學習率

  • 使用卷積進行圖像分類任務

 

最后一點想法

 

在撰寫此文的過程中,我已經學到了很多,希望本文也能對你有所幫助。

在沒有完全了解神經網絡內部工作原理的情況下,雖然使用諸如 TensorFlow 和 Keras 之類的深度學習庫可以讓我們很容易地建立深度網絡,但我認為對于有抱負的數據科學家而言,深入理解神經網絡還是大有裨益的。
 


 

微信掃碼,回復“python”,領取免費資料包

 

1. Python基礎教程.pdf

2. Python源碼剖析(完整版).pdf

3. Python源碼剖析 [文字版].pdf

4. Python基礎教程(第2版)高清版PDF.pdf

5. Python核心編程(第3版)PDF高清晰完整中文版.pdf

 

收藏
分享
別默默的看了,快來和大家聊聊吧,登錄后發表評論~ 登錄 立即注冊
打賞
董亞微
打賞金額(金額:¥0)
給Ta留言
賞金已入袋,多謝!(*^__^*)
溫馨提示

非常抱歉!本站不支持舊版本IE瀏覽器~~建議使用IE10/IE11/Chrome/Firefox/Safari等高級瀏覽器瀏覽。

溫馨提示
溫馨提示
幫助與反饋

熱門問題

菠菜菠菜网大全 句容市| 平顺县| 交城县| 海晏县| 龙州县| 邳州市| 油尖旺区| 旬邑县| 龙山县| 隆化县| 资中县| 航空| 南部县| 沙河市| 永川市| 卢龙县| 澎湖县| 南漳县| 泰顺县| 深州市| 梅州市| 望奎县| 西平县| 嵊泗县| 清流县| 峨边| 涟水县| 杭锦旗| 新闻| 肃南| 上犹县| 晋城| 宣城市| 凤庆县| 凤冈县| 新疆| 新源县| 措勤县| 华容县| 德格县| 繁昌县| 外汇| 隆化县| 南溪县| 右玉县| 嵊泗县| 鞍山市| 临泉县| 陈巴尔虎旗| 福鼎市| 南平市| 青冈县| 离岛区| 芜湖市| 灌南县| 太原市| 虞城县| 东港市| SHOW| 正蓝旗| 航空| 集安市| 玛曲县| 陵水| 晋宁县| 万全县| 虹口区| 双峰县| 徐水县| 伊金霍洛旗| 东宁县| 南漳县| 洮南市| 卢龙县| 青河县| 桂阳县| 上蔡县| 信宜市| 乌兰县| 米易县| 高碑店市| 邵武市| 阿拉善盟| 文登市| 桓台县| 乡城县| 寿宁县| 闻喜县| 芦溪县| 金塔县| 谷城县| 皋兰县| 明溪县| 玉树县| 武清区| 阿尔山市| 民丰县| 泸西县| 三门县| 忻州市| 化州市| 云阳县| 闵行区| 黄梅县| 同德县| 尼玛县| 夏河县| 阳高县| 建湖县| 交城县| 临湘市| 资溪县| 伊川县| 常德市| 郯城县| 神池县| 新竹县| 昌都县| 隆安县| 汾阳市| 广德县| 那曲县| 科技| 宜州市| 分宜县| 鹤岗市| 抚顺市| 西华县| 大姚县| 新巴尔虎右旗| 崇文区| 阜康市| 咸阳市| 江永县| 阳山县| 儋州市| 龙山县|