代碼詳解:基於Python建立任意層數的深度神經網絡 - 讀芯術

2021-01-11 讀芯術

全文共6359字,預計學習時長20分鐘或更長

圖片來源:pexels.com/@divinetechygir

在這篇指南中,我們將建立起一個任意層數的深度神經網絡。這個神經網絡可以應用於二元分類的監督學習問題。

圖1 神經網絡構造的例子(符號說明:上標[l]表示與第l層;上標(i)表示第i個例子;下標i表示矢量第i項)

單層神經網絡

圖2 單層神經網絡示例

神經元模型是先計算一個線性函數(z=Wx+b),接著再計算一個激活函數。一般來說,神經元模型的輸出值是a=g(Wx+b),其中g是激活函數(sigmoid,tanh, ReLU, …)。

數據集

假設有一個很大的資料庫,裡面記錄了很多天氣數據,例如,氣溫、溼度、氣壓和降雨率。

問題陳述:

一組訓練數據m_train,下雨標記為(1),不下雨標記為(0)。

一個測試數據組m_test,標記是否下雨。

每一個天氣數據包含x1=氣溫,x2=溼度,x3=氣壓。

機器學習中一個常見的預處理步驟是將數據集居中並標準化,這意味著從每個示例中減去整個numpy數組的平均值,然後將每個示例除以整個numpy數組的標準偏差。

通用方法(建立部分算法)

使用深度學習來建造模型

1. 定義模型構造(例如,數據的輸入特徵)

2. 初始化參數並定義超參數

迭代次數

在神經網絡中的L層的層數

隱藏層大小

學習率α

3. 迭代循環

正向傳播(計算電流損耗)

計算成本函數

反向傳播(計算電流損耗)

升級參數(使用背景參數和梯度)

4. 使用訓練參數來預測標籤

初始化

更深層次的L-層神經網絡的初始化更為複雜,因為有更多的權重矩陣和偏置向量。下表展示了不同結構的各種層級。

表1 L層的權重矩陣w、偏置向量b和激活函數z

表2 示例架構中的神經網絡權重矩陣w、偏置向量b和激活函數z

表2幫助我們為圖1中的示例神經網絡架構的矩陣準備了正確的維度。

import numpy as np

import matplotlib.pyplot as plt

nn_architecture = [

{"layer_size": 4,"activation": "none"}, # input layer

{"layer_size": 5,"activation": "relu"},

{"layer_size": 4,"activation": "relu"},

{"layer_size": 3,"activation": "relu"},

{"layer_size": 1,"activation": "sigmoid"}

]

def initialize_parameters(nn_architecture, seed = 3):

np.random.seed(seed)

# python dictionary containingour parameters "W1", "b1", ..., "WL","bL"

parameters = {}

number_of_layers = len(nn_architecture)

for l in range(1,number_of_layers):

parameters['W' + str(l)] =np.random.randn(

nn_architecture[l]["layer_size"],

nn_architecture[l-1]["layer_size"]

) * 0.01

parameters['b' + str(l)] =np.zeros((nn_architecture[l]["layer_size"], 1))

return parameters

代碼段1 參數初始化

使用小隨機數初始化參數是一種簡單的方法,但同時也保證算法的起始值足夠好。

記住:

· 不同的初始化工具,例如Zero,Random, He or Xavier,都會導致不同的結果。

· 隨機初始化能夠確保不同的隱藏單元可以學習不同的東西(初始化所有權重為零會導致,所有層次的所有感知機都將學習相同的東西)。

· 不要初始化為太大的值。

激活函數

激活函數的作用是為了增加神經網絡的非線性。下例將使用sigmoid and ReLU。

Sigmoid輸出一個介於0和1之間的值,這使得它成為二進位分類的一個很好的選擇。如果輸出小於0.5,可以將其分類為0;如果輸出大於0.5,可以將其分類為1。

def sigmoid(Z):

S = 1 / (1 + np.exp(-Z))

return S

def relu(Z):

R = np.maximum(0, Z)

return R

def sigmoid_backward(dA, Z):

S = sigmoid(Z)

dS = S * (1 - S)

return dA * dS

def relu_backward(dA, Z):

dZ = np.array(dA, copy = True)

dZ[Z <= 0] = 0

return dZ

代碼段2 Sigmoid和ReLU激活函數,及其衍生物

在代碼段2中,可以看到激活函數及其派生的矢量化編程實現。該代碼將用於進一步的計算。

正向傳播

在正向傳播中,在層l的正向函數中,需要知道該層中的激活函數是哪一種(sigmoid、tanh、ReLU等)。前一層的輸出值為這一層的輸入值,先計算z,再用選定的激活函數計算。

圖3 神經網絡的正向傳播

線性正向模塊(對所有示例進行矢量化)計算以下方程式:

方程式1 線性正向函數

def L_model_forward(X, parameters, nn_architecture):

forward_cache = {}

A = X

number_of_layers =len(nn_architecture)

for l in range(1,number_of_layers):

A_prev = A

W = parameters['W' + str(l)]

b = parameters['b' + str(l)]

activation =nn_architecture[l]["activation"]

Z, A =linear_activation_forward(A_prev, W, b, activation)

forward_cache['Z' + str(l)] =Z

forward_cache['A' + str(l)] =A

AL = A

return AL, forward_cache

def linear_activation_forward(A_prev, W, b, activation):

if activation =="sigmoid":

Z = linear_forward(A_prev, W,b)

A = sigmoid(Z)

elif activation =="relu":

Z = linear_forward(A_prev, W,b)

A = relu(Z)

return Z, A

def linear_forward(A, W, b):

Z = np.dot(W, A) + b

return Z

代碼段3 正向傳播模型

使用「cache」(python字典包含為特定層所計算的a和z值)以在正向傳播至相應的反向傳播期間傳遞變量。它包含用於反向傳播計算導數的有用值。

損失函數

為了管程學習過程,需要計算代價函數的值。下面的公式用於計算成本。

方程式2 交叉熵成本

def compute_cost(AL, Y):

m = Y.shape[1]

# Compute loss from AL and y

logprobs =np.multiply(np.log(AL),Y) + np.multiply(1 - Y, np.log(1 - AL))

# cross-entropy cost

cost = - np.sum(logprobs) / m

cost = np.squeeze(cost)

return cost

代碼段4 代價函數的計算

反向傳播

反向傳播用於計算參數的損失函數梯度。該算法是由微分學中已知的「鏈規則」遞歸使用的。

反向傳播計算中使用的公式:

方程式3 反向傳播計算公式

鏈式法則是計算複合函數導數的公式。複合函數就是函數套函數。

方程式4 鏈規則示例

「鏈規則」在計算損失時十分重要(以方程式5為例)。

方程式5 損失函數(含替換數據)及其相對於第一權重的導數

神經網絡模型反向傳播的第一步是計算最後一層損失函數相對於z的導數。方程式6由兩部分組成:方程式2損失函數的導數(關於激活函數)和激活函數「sigmoid」關於最後一層Z的導數。

方程式6 從4層對z的損失函數導數

方程式6的結果可用於計算方程式3的導數。

方程式7 損失函數相對於3層的導數

在進一步計算中,使用了與第三層激活函數有關的損失函數的導數(方程式7)。

方程式8 第三層的導數

方程式7的結果和第三層活化函數「relu」的導數用於計算方程式8的導數(損失函數相對於z的導數)。然後,我們對方程式3進行了計算。

我們對方程9和10做了類似的計算。

方程式9 第二層的導數
方程式10 第一層的導數

總體思路

從第一層層對z的損失函數導數有助於計算(L-1)層(上一層)對損失函數的導數。結果將用於計算激活函數的導數。

圖4 神經網絡的反向傳播

def L_model_backward(AL, Y, parameters, forward_cache, nn_architecture):

grads = {}

number_of_layers =len(nn_architecture)

m = AL.shape[1]

Y = Y.reshape(AL.shape) # afterthis line, Y is the same shape as AL

# Initializing thebackpropagation

dAL = - (np.divide(Y, AL) -np.divide(1 - Y, 1 - AL))

dA_prev = dAL

for l in reversed(range(1,number_of_layers)):

dA_curr = dA_prev

activation =nn_architecture[l]["activation"]

W_curr = parameters['W' +str(l)]

Z_curr = forward_cache['Z' +str(l)]

A_prev = forward_cache['A' +str(l-1)]

dA_prev, dW_curr, db_curr =linear_activation_backward(dA_curr, Z_curr, A_prev, W_curr, activation)

grads["dW" +str(l)] = dW_curr

grads["db" +str(l)] = db_curr

return grads

def linear_activation_backward(dA, Z, A_prev, W, activation):

if activation =="relu":

dZ = relu_backward(dA, Z)

dA_prev, dW, db =linear_backward(dZ, A_prev, W)

elif activation =="sigmoid":

dZ = sigmoid_backward(dA, Z)

dA_prev, dW, db =linear_backward(dZ, A_prev, W)

return dA_prev, dW, db

def linear_backward(dZ, A_prev, W):

m = A_prev.shape[1]

dW = np.dot(dZ, A_prev.T) / m

db = np.sum(dZ, axis=1,keepdims=True) / m

dA_prev = np.dot(W.T, dZ)

return dA_prev, dW, db

代碼段5 反向傳播模塊

更新參數

該函數的目標是通過梯度優化來更新模型的參數。

def update_parameters(parameters, grads, learning_rate):

L = len(parameters)

for l in range(1, L):

parameters["W" +str(l)] = parameters["W" + str(l)] - learning_rate *grads["dW" + str(l)]

parameters["b" +str(l)] = parameters["b" + str(l)] - learning_rate *grads["db" + str(l)]

return parameters

代碼段6 使用梯度下降更新參數值

全模型

神經網絡模型的完整實現包括在片段中提供的方法。

def L_layer_model(X, Y, nn_architecture, learning_rate = 0.0075,num_iterations = 3000, print_cost=False):

np.random.seed(1)

# keep track of cost

costs = []

# Parameters initialization.

parameters =initialize_parameters(nn_architecture)

# Loop (gradient descent)

for i in range(0,num_iterations):

# Forward propagation:[LINEAR -> RELU]*(L-1) -> LINEAR -> SIGMOID.

AL, forward_cache =L_model_forward(X, parameters, nn_architecture)

# Compute cost.

cost = compute_cost(AL, Y)

# Backward propagation.

grads = L_model_backward(AL,Y, parameters, forward_cache, nn_architecture)

# Update parameters.

parameters =update_parameters(parameters, grads, learning_rate)

# Print the cost every 100training example

if print_cost and i % 100 ==0:

print("Cost afteriteration %i: %f" %(i, cost))

costs.append(cost)

# plot the cost

plt.plot(np.squeeze(costs))

plt.ylabel('cost')

plt.xlabel('iterations (pertens)')

plt.title("Learning rate=" + str(learning_rate))

plt.show()

return parameters

代碼段7 整個神經網絡模型

只需要將已知的權重和系列測試數據,應用於正向傳播模型,就能預測結果。

可以修改snippet1中的nn_架構,以構建具有不同層數和隱藏層大小的神經網絡。此外,準備正確實現激活函數及其派生函數(代碼段2)。所實現的函數可用於修改代碼段3中的線性正向激活方法和代碼段5中的線性反向激活方法。

進一步改進

如果訓練數據集不夠大,則可能面臨「過度擬合」問題。這意味著所學的網絡不會概括為它從未見過的新例子。可以使用正則化方法,如L2規範化(它包括適當地修改成本函數)或退出(它在每次迭代中隨機關閉一些感知機)。

我們使用梯度下降來更新參數和最小化成本。你可以學習更多高級優化方法,這些方法可以加快學習速度,甚至可以為成本函數提供更好的最終價值,例如:

· 小批量梯度下降

· 動力

· Adam優化器

留言 點讚 關注

我們一起分享AI學習與發展的乾貨

歡迎關注全平臺AI垂類自媒體 「讀芯術」

相關焦點

  • 如何用Python和深度神經網絡識別圖像?
    一個有用的規律是,隨著層數不斷向右推進,一般結果圖像(其實正規地說,應該叫做矩陣)會變得越來越小,但是層數會變得越來越多。只有這樣,我們才能把圖片中的規律信息抽取出來,並且儘量掌握足夠多的模式。如果你還是覺得不過癮,請訪問這個網站。它為你生動解析了卷積神經網絡中,各個層次上到底發生了什麼。
  • 神經網絡初學者指南:基於Scikit-Learn的Python模塊
    ,其最新版本現在已經內置支持神經網絡模型。前幾天最新版本(0.18)剛剛發布,現在已內置支持神經網絡模型。 對 Python 的基本理解對於弄明白這篇文章是必要的,有一些關於Sci-Kit Learn 的使用經驗也是十分有幫助的(但不是必要)。另外,作為一個快速附註,我寫了一篇詳解版的姐妹文章,不過是以 R 語言編寫的(可點擊此處查看)。
  • 一文詳解神經網絡 BP 算法原理及 Python 實現
    BP 算法執行的流程(前向傳遞和逆向更新) 在手工設定了神經網絡的層數,每層的神經元的個數,學習率 η(下面會提到)後,BP 算法會先隨機初始化每條連接線權重和偏置,然後對於訓練集中的每個輸入 x 和輸出 y,BP 算法都會先執行前向傳輸得到預測值,然後根據真實值與預測值之間的誤差執行逆向反饋更新神經網絡中每條連接線的權重和每層的偏好。
  • Python視頻教程網課編程零基礎入門數據分析網絡爬蟲全套Python...
    基於liunx系統的python教程,課程裡也有liunx操作的詳細教學,不用擔心學習時不會操作liunx系統。 25python網絡爬蟲 26機器學習入門篇 27機器學習入門篇2 28機器學習提升篇 29數據挖掘篇 30深度學習必備原理與實戰 31深度學習必備原理與實戰2 32深度學習必備原理與實戰3 33深度學習必備原理與實戰4 34深度學習項目實戰 35
  • 最全面的卷積神經網絡介紹(含代碼實戰詳解)
    點擊上方「CVer」,選擇加"星標"或「置頂」重磅乾貨,第一時間送達本文轉載自普通神經網絡的主要缺點是其忽略了輸入數據的結構。CNN的體系結構當使用普通神經網絡時,需要將輸入數據轉換為單個向量。該向量作為神經網絡的輸入,然後向量穿過神經網絡的各層。
  • 代碼詳解:使用NumPy,教你9步從頭搭建神經網絡
    Photo by Alina Grubnyak on Unsplash如果你是個對神經網絡有所了解的初級數據科學家,或是個對深度學習略有耳聞的機器學習愛好者,一定要讀一讀這篇文章。本文介紹了使用NumPy從頭搭建神經網絡的9個步驟,即從數據預處理到反向傳播這一「必經之路」。對機器學習、人工神經網絡、Python語法和編程邏輯有些基本理解最好,(但這也不是必需條件,你可以邊讀邊學)。1. 初始化導入NumPy。
  • 談一談逆勢而上的圖神經網絡
    (代碼已經公開)ICLR 2020 | 兼顧效率與質量—基於譜方法的高效多級圖嵌入框架NeurIPS2020 | 用於半監督學習的圖隨機神經網絡NeurIPS2020 | 顯著超越STGCN: 方法簡單-效果顯著自適應構圖的時空圖網絡硬核 | TKDE2020-時空數據挖掘深度學習技術全面綜述NeurIPS2020 | Google
  • 機器學習、深度學習算法原理與案例實踐暨Python大數據綜合應用...
    共4天8節,講解機器學習和深度學習的模型理論和代碼實踐,梳理機器學習、深度學習、計算機視覺的技術框架,從根本上解決如何使用模型、優化模型的問題;每次課中,首先闡述算法理論和少量公式推導,然後使用真實數據做數據挖掘、機器學習、深度學習的數據分析、特徵選擇、調參和結果比較。
  • 神經網絡理論基礎及Python實現
    一、多層前向神經網絡 多層前向神經網絡由三部分組成:輸出層、隱藏層、輸出層,每層由單元組成; 輸入層由訓練集的實例特徵向量傳入,經過連接結點的權重傳入下一層,前一層的輸出是下一層的輸入;隱藏層的個數是任意的,輸入層只有一層,輸出層也只有一層; 除去輸入層之外,隱藏層和輸出層的層數和為n,則該神經網絡稱為n層神經網絡
  • 圖神經網絡越深,表現就一定越好嗎?
    然而,日前帝國理工學院教授Michael Bronstein 發出了靈魂拷問:圖神經網絡的深度,真的會帶來優勢嗎?「深度圖神經網絡」是否被誤用了?或者說,我們是否應該重新審視以前認為「圖神經網絡越深,效果就會越好」的思路,說不定「深度」反而對基於圖的深度學習不利呢?眾所周知,深度圖神經網絡的訓練過程非常艱難。
  • 學習筆記,從NumPy到Scrapy,學習Python不能錯過這些庫
    在網絡上看到幾位前輩寫了關於python深度學習庫的文章,對於小小白來說,因為我剛開始學python,我得承認自己看完後依然覺得雲裡霧裡的,不知道這些庫到底對我有什麼用處。所以我到網絡上搜集補充關於這些庫的說明內容,感覺在這個整理資料的過程中,對於這些python程序庫了解了更多,以下是我整理的學習筆記。
  • 基於深度神經網絡的脫硫系統預測模型及應用
    本文還結合某 2×350MW 燃煤電廠提供的實際工數據,以石灰石供漿密度對系統脫硫性能的影響為例,詳細介紹了利用所建立的深度神經網絡模型測試溼法脫硫系統各參數指標對脫硫效果的影響,並結合化學機理和工業實際進行的診斷過程。
  • 深度學習預測比特幣價格;基於神經網絡的自動化前端開發 | Github...
    這些項目涉及自動化前端開發、中文近義詞處理以及火熱的比特幣等領域,詳細信息和具體代碼實現請閱讀下文。如果你對自己的 AI 項目有足夠的自信,同時也希望更多的開發者參與到你的項目中,歡迎將項目的 Github 連結發給雷鋒網 AI 研習社,說不定下一期推薦的就是你的項目。
  • 一篇文章教你用11行Python代碼實現神經網絡
    聲明:本文是根據英文教程 (用 11 行 Python 代碼實現的神經網絡)學習總結而來,關於更詳細的神經網絡的介紹可以參考我的另一篇博客:。A Neural Network in 11 lines of Python從感知機到人工神經網絡如果你讀懂了下面的文章,你會對神經網絡有更深刻的認識,有任何問題,請多指教。
  • 知深行遠:關於圖神經網絡層數加深的探索
    圖 (Graph) 由結點和連邊組成,我們把應用於圖上的神經網絡算法稱為圖神經網絡 (Graph Neural Network, 簡稱GNN)。對於圖像、視頻、音頻等數據,經典的神經網絡 (如CNN和RNN) 已經能夠較好地處理,並且目前也已經取得了不錯的效果,為什麼我們還會需要GNN呢?
  • 一文讀懂圖神經網絡
    小聲:今天老闆說深度學習必須學習python,於是:一、介紹什麼是圖神經網絡圖神經網絡(Graph Neural Networks, GNNs)是基於圖結構的深度學習方法,近期被廣泛應用到各類圖像比較常見的圖神經網絡算法主要有Graph Convolutional Network(GCN)和Graph Attention Network(GAT)等網絡及其變種,在本文第三部分會給出基於圖神經網絡框架
  • 深度學習:神經網絡算法的昨天、今天和明天
    之後的1994年,計算機科學家Yann LeCun在Geoffrey Hinton組內做博士後期間,結合神經認知機和反向傳播算法,提出了用於識別手寫郵政編碼的卷積神經網絡LeNet,獲得了99%的自動識別率,並且可以處理幾乎任意的手寫形式。這一算法在當時取得了巨大的成功,並被應用於美國郵政系統中。三、深度學習的爆發儘管如此,深度學習並沒有因此而熱門。
  • 一份完全解讀:是什麼使神經網絡變成圖神經網絡?
    這是一種有趣的方法,但在很多情況下它並不能全面的表示出一個人的面部特徵,因此可以通過卷積網絡從面部紋理中出捕捉到更多信息。相反,與2D標誌相比,基於人臉的3D網格的推理看起來更合理(Ranjan等人,ECCV,2018)。
  • 人工智慧黑盒揭秘:深度神經網絡可視化技術
    但深度神經網絡又被稱為「黑盒」模型,多層隱藏結構,數據 / 特徵矢量化,海量決策關鍵元等因素讓模型使用者犯難:模型決策的依據是什麼?應該相信模型麼?特別是對於金融,醫藥,生物等關鍵型任務,深度學習模型的弱解釋性成為人工智慧項目落地的最大障礙。
  • 近年來深度神經網絡模型不斷迎來重大突破
    近年來深度神經網絡模型不斷迎來重大突破,由深度學習為代表的機器學習相關研究取得了長足進步。但對機器學習研究普及者和研究機構來說,由於對機器學習原理、應用實踐以及技術應用多方面的缺乏概念理解,這些機器學習技術發展存在顯著的「彎路」。