在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于NumPy創建一個可以工作的神經網絡

zhKF_jqr_AI ? 來源:未知 ? 作者:李倩 ? 2018-10-18 09:02 ? 次閱讀

編者按:和Piotr Skalski一起,基于NumPy手寫神經網絡,通過親自動手實踐,加深對神經網絡內部機制的理解。

Keras、TensorFlow、PyTorch等高層框架讓我們可以快速搭建復雜模型。然而,花一點時間了解下底層概念是值得的。前不久我發過一篇文章,以簡單的方式解釋了神經網絡是如何工作的。但這是一篇高度理論性的文章,主要以數學為主(數學是神經網絡超能力的來源)。我打算以實踐的方式繼續這一主題,在這篇文章中,我們將嘗試僅僅基于NumPy創建一個可以工作的神經網絡。最后,我們將測試一下創建的模型——用它來解決簡單的分類問題,并和基于Keras搭建的神經網絡比較一下。

顯然,今天的文章會包含很多Python代碼,我希望你不會因此覺得枯燥。我同時也把文中所有的代碼發在GitHub上:SkalskiP/ILearnDeepLearning.py

概覽

在開始編程之前,先讓我們準備一份基本的路線圖。我們的目標是創建一個特定架構(層數、層大小、激活函數)的密集連接神經網絡。然后訓練這一神經網絡并做出預測。

上面的示意圖展示了訓練網絡時進行的操作,以及單次迭代不同階段需要更新和讀取的參數

初始化神經網絡層

讓我們從初始化每一層的權重矩陣W和偏置向量b開始。下圖展示了網絡層l的權重矩陣和偏置向量,其中,上標[l]表示當前層的索引,n表示給定層中的神經元數量。

我們的程序也將以類似的列表形式描述神經網絡架構。列表的每一項是一個字典,描述單個網絡層的基本參數:input_dim是網絡層輸入的信號向量的大小,output_dim是網絡層輸出的激活向量的大小,activation是網絡層所用的激活函數。

nn_architecture = [

{"input_dim": 2, "output_dim": 4, "activation": "relu"},

{"input_dim": 4, "output_dim": 6, "activation": "relu"},

{"input_dim": 6, "output_dim": 6, "activation": "relu"},

{"input_dim": 6, "output_dim": 4, "activation": "relu"},

{"input_dim": 4, "output_dim": 1, "activation": "sigmoid"},

]

如果你熟悉這一主題,你的腦海中大概已經回蕩起焦急的聲音:“喂喂!搞錯了!這里有些是不必要的……”這一次,你內心的聲音是對的,一個網絡層的輸出向量同時也是下一層的輸入,所以其實只用列出兩者之一就夠了。不過,我故意使用這樣的表示法,使每一層的格式保持一致,也讓初次接觸這一主題的人更容易理解代碼。

def init_layers(nn_architecture, seed = 99):

np.random.seed(seed)

number_of_layers = len(nn_architecture)

params_values = {}

for idx, layer in enumerate(nn_architecture):

layer_idx = idx + 1

layer_input_size = layer["input_dim"]

layer_output_size = layer["output_dim"]

params_values['W' + str(layer_idx)] = np.random.randn(

layer_output_size, layer_input_size) * 0.1

params_values['b' + str(layer_idx)] = np.random.randn(

layer_output_size, 1) * 0.1

return params_values

上面的代碼初始化了網絡層的參數。注意我們用隨機的小數字填充矩陣W和向量b。這并不是偶然的。權重值無法使用相同的數字初始化,否則會造成破壞性的對稱問題。基本上,如果權重都一樣,不管輸入X是什么,隱藏層的所有單元也都一樣。這樣,我們就會陷入初始狀態,不管訓練多久,網絡多深,都無望擺脫。線性代數不會原諒我們。

小數值增加了算法的效率。我們可以看看下面的sigmoid函數圖像,大數值處的函數圖像幾乎是扁平的,這會對神經網絡的學習速度造成顯著影響。所有參數使用小隨機數是一個簡單的方法,但它保證了算法有一個足夠好的開始。

激活函數

激活函數只需一行代碼就可以定義,但它們給神經網絡帶來了非線性和所需的表達力?!皼]有它們,神經網絡將變成線性函數的組合,也就是單個線性函數?!奔せ詈瘮涤泻芏喾N,但在這個項目中,我決定使用其中兩種——sigmoid和ReLU。為了同時支持前向傳播和反向傳播,我們還需要準備好它們的導數。

def sigmoid(Z):

return1/(1+np.exp(-Z))

def relu(Z):

return np.maximum(0,Z)

def sigmoid_backward(dA, Z):

sig = sigmoid(Z)

return dA * sig * (1 - sig)

def relu_backward(dA, Z):

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

dZ[Z <= 0] = 0;

return dZ;

前向傳播

我們設計的神經網絡有一個簡單的架構。輸入矩陣X傳入網絡,沿著隱藏單元傳播,最終得到預測向量Y_hat。為了讓代碼更易讀,我將前向傳播拆分成兩個函數——單層前向傳播,和整個神經網絡前向傳播。

def single_layer_forward_propagation(A_prev, W_curr, b_curr, activation="relu"):

Z_curr = np.dot(W_curr, A_prev) + b_curr

if activation is"relu":

activation_func = relu

elif activation is"sigmoid":

activation_func = sigmoid

else:

raiseException('Non-supported activation function')

return activation_func(Z_curr), Z_curr

這部分代碼大概是最直接,最容易理解的。給定來自上一層的輸入信號,我們計算仿射變換Z,接著應用選中的激活函數?;贜umPy,我們可以對整個網絡層和整批樣本一下子進行矩陣操作,無需迭代,這大大加速了計算。除了計算結果外,函數還返回了一個反向傳播時需要用到的中間值Z。

基于單層前向傳播函數,編寫整個前向傳播步驟很容易。這是一個略微復雜一點的函數,它的角色不僅是進行預測,還包括組織中間值。

def full_forward_propagation(X, params_values, nn_architecture):

memory = {}

A_curr = X

for idx, layer in enumerate(nn_architecture):

layer_idx = idx + 1

A_prev = A_curr

activ_function_curr = layer["activation"]

W_curr = params_values["W" + str(layer_idx)]

b_curr = params_values["b" + str(layer_idx)]

A_curr, Z_curr = single_layer_forward_propagation(A_prev, W_curr, b_curr, activ_function_curr)

memory["A" + str(idx)] = A_prev

memory["Z" + str(layer_idx)] = Z_curr

return A_curr, memory

損失函數

損失函數可以監測進展,確保我們向著正確的方向移動。“一般來說,損失函數是為了顯示我們離‘理想’解答還有多遠?!睋p失函數根據我們計劃解決的問題而選用,Keras之類的框架提供了很多選項。因為我計劃將神經網絡用于二元分類問題,我決定使用交叉熵:

為了取得更多關于學習過程的信息,我決定另外實現一個計算精確度的函數。

def get_cost_value(Y_hat, Y):

m = Y_hat.shape[1]

cost = -1 / m * (np.dot(Y, np.log(Y_hat).T) + np.dot(1 - Y, np.log(1 - Y_hat).T))

return np.squeeze(cost)

def get_accuracy_value(Y_hat, Y):

Y_hat_ = convert_prob_into_class(Y_hat)

return (Y_hat_ == Y).all(axis=0).mean()

反向傳播

不幸的是,很多缺乏經驗的深度學習愛好者都覺得反向傳播很嚇人,難以理解。微積分和線性代數的組合經常會嚇退那些沒有經過扎實的數學訓練的人。所以不要過于擔心你現在還不能理解這一切。相信我,我們都經歷過這個過程。

def single_layer_backward_propagation(dA_curr, W_curr, b_curr, Z_curr, A_prev, activation="relu"):

m = A_prev.shape[1]

if activation is"relu":

backward_activation_func = relu_backward

elif activation is"sigmoid":

backward_activation_func = sigmoid_backward

else:

raiseException('Non-supported activation function')

dZ_curr = backward_activation_func(dA_curr, Z_curr)

dW_curr = np.dot(dZ_curr, A_prev.T) / m

db_curr = np.sum(dZ_curr, axis=1, keepdims=True) / m

dA_prev = np.dot(W_curr.T, dZ_curr)

return dA_prev, dW_curr, db_curr

人們經常搞混反向傳播和梯度下降,但事實上它們不一樣。前者是為了高效地計算梯度,后者則是為了基于計算出的梯度進行優化。在神經網絡中,我們計算損失函數在參數上的梯度,但反向傳播可以用來計算任何函數的導數。反向傳播算法的精髓在于遞歸地使用求導的鏈式法則,通過組合導數已知的函數,計算函數的導數。下面的公式描述了單個網絡層上的反向傳播過程。由于本文的重點在實際實現,所以我將省略求導過程。從公式上我們可以很明顯地看到,為什么我們需要在前向傳播時記住中間層的A、Z矩陣的值。

和前向傳播一樣,我決定將計算拆分成兩個函數。之前給出的是單個網絡層的反向傳播函數,基本上就是以NumPy方式重寫上面的數學公式。而定義完整反向傳播過程的函數,主要是讀取、更新三個字典中的值。

def full_backward_propagation(Y_hat, Y, memory, params_values, nn_architecture):

grads_values = {}

m = Y.shape[1]

Y = Y.reshape(Y_hat.shape)

dA_prev = - (np.divide(Y, Y_hat) - np.divide(1 - Y, 1 - Y_hat));

for layer_idx_prev, layer in reversed(list(enumerate(nn_architecture))):

layer_idx_curr = layer_idx_prev + 1

activ_function_curr = layer["activation"]

dA_curr = dA_prev

A_prev = memory["A" + str(layer_idx_prev)]

Z_curr = memory["Z" + str(layer_idx_curr)]

W_curr = params_values["W" + str(layer_idx_curr)]

b_curr = params_values["b" + str(layer_idx_curr)]

dA_prev, dW_curr, db_curr = single_layer_backward_propagation(

dA_curr, W_curr, b_curr, Z_curr, A_prev, activ_function_curr)

grads_values["dW" + str(layer_idx_curr)] = dW_curr

grads_values["db" + str(layer_idx_curr)] = db_curr

return grads_values

基于單個網絡層的反向傳播函數,我們從最后一層開始迭代計算所有參數上的導數,并最終返回包含所需梯度的python字典。

更新參數值

反向傳播是為了計算梯度,以根據梯度進行優化,更新網絡的參數值。為了完成這一任務,我們將使用兩個字典作為函數參數:params_values,其中保存了當前參數值;grads_values,其中保存了用于更新參數值所需的梯度信息。現在我們只需在每個網絡層上應用以下等式即可。這是一個非常簡單的優化算法,但我決定使用它作為更高級的優化算法的起點(大概會是我下一篇文章的主題)。

def update(params_values, grads_values, nn_architecture, learning_rate):

for idx, layer in enumerate(nn_architecture):

layer_idx = idx + 1

params_values["W" + str(layer_idx)] -= learning_rate * grads_values["dW" + str(layer_idx)]

params_values["b" + str(layer_idx)] -= learning_rate * grads_values["db" + str(layer_idx)]

return params_values;

整合一切

萬事俱備只欠東風。最困難的部分已經完成了——我們已經準備好了所需的函數,現在只需以正確的順序把它們放到一起。

def train(X, Y, nn_architecture, epochs, learning_rate):

params_values = init_layers(nn_architecture, 2)

cost_history = []

accuracy_history = []

for i in range(epochs):

Y_hat, cashe = full_forward_propagation(X, params_values, nn_architecture)

cost = get_cost_value(Y_hat, Y)

cost_history.append(cost)

accuracy = get_accuracy_value(Y_hat, Y)

accuracy_history.append(accuracy)

grads_values = full_backward_propagation(Y_hat, Y, cashe, params_values, nn_architecture)

params_values = update(params_values, grads_values, nn_architecture, learning_rate)

return params_values, cost_history, accuracy_history

大衛對戰歌利亞

該是看看我們的模型能不能解決一個簡單的分類問題的時候了。我生成了一個包含兩個分類的數據點的數據集,如下圖所示。

作為對比,我用高層框架Keras搭建了一個模型。兩個模型采用相同的架構和學習率。不過這仍然是一場不公平的較量,因為我們的模型用的都是最簡單的方案。最終,基于NumPy和Keras的模型在測試集上都取得了類似的精確度(95%)。不過,我們的模型收斂的速度要慢很多倍。在我看來,這主要是因為我們的模型缺乏恰當的優化算法。

再見

希望我的文章拓展了你的視野,增加了你對神經網絡內部運作機制的理解——這將是對我投入精力撰寫本文的最好回報。我在編寫代碼和說明的時候也學到了很多東西,親自動手實踐能讓你學到很多東西。

如你有任何疑問,或者找到了代碼中的錯誤,請留言告知。如果你喜歡這篇文章,可以在Twitter(PiotrSkalski92)和Medium(piotr.skalski92)上關注我,也可以上GitHub(SkalskiP)和Kaggle(skalskip)查看我的其他項目。本文是“神經網絡的奧秘”系列的第三篇,如果你還沒有讀過前兩篇,可以看一下https://towardsdatascience.com/preventing-deep-neural-network-from-overfitting-953458db800a

保持好奇心!

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 神經網絡
    +關注

    關注

    42

    文章

    4783

    瀏覽量

    101233
  • python
    +關注

    關注

    56

    文章

    4811

    瀏覽量

    85075
  • keras
    +關注

    關注

    2

    文章

    20

    瀏覽量

    6099

原文標題:只用NumPy實現神經網絡

文章出處:【微信號:jqr_AI,微信公眾號:論智】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    人工神經網絡原理及下載

    人工神經網絡是根據人的認識過程而開發出的種算法。假如我們現在只有些輸入和相應的輸出,而對如何由輸入得到輸出的機理并不清楚,那么我們可以把輸入與輸出之間的未知過程看成是
    發表于 06-19 14:40

    【PYNQ-Z2試用體驗】神經網絡基礎知識

    語言,使用numpy.dot方法即可計算矩陣乘法。 以上便是簡單神經網絡的基本原理,對神經網絡有了基本的認識之后,我們才能進行復雜的
    發表于 03-03 22:10

    【PYNQ-Z2試用體驗】基于PYNQ-Z2的神經網絡圖形識別[結項]

    。可以看到文件列表中多了我們剛剛克隆的項目。如下圖: 圖3神經網絡源碼分析在運行代碼之前,我們先來了解
    發表于 03-18 21:51

    卷積神經網絡如何使用

    卷積神經網絡(CNN)究竟是什么,鑒于神經網絡在工程上經歷了曲折的歷史,您為什么還會在意它呢? 對于這些非常中肯的問題,我們似乎可以給出相對簡明的答案。
    發表于 07-17 07:21

    【案例分享】ART神經網絡與SOM神經網絡

    今天學習了兩神經網絡,分別是自適應諧振(ART)神經網絡與自組織映射(SOM)神經網絡。整體感覺不是很難,只不過些最基礎的概念容易理解不
    發表于 07-21 04:30

    如何移植CNN神經網絡到FPGA中?

    訓練神經網絡并移植到Lattice FPGA上,通常需要開發人員既要懂軟件又要懂數字電路設計,是不容易的事。好在FPGA廠商為我們提供了許多工具和IP,我們
    發表于 11-26 07:46

    如何構建神經網絡?

    原文鏈接:http://tecdat.cn/?p=5725 神經網絡種基于現有數據創建預測的計算系統。如何構建神經網絡神經網絡包括:輸
    發表于 07-12 08:02

    神經網絡移植到STM32的方法

    神經網絡移植到STM32最近在做的項目需要用到網絡進行擬合,并且將擬合得到的結果用作控制,就在想能不能直接在單片機上做神經網絡計算,這
    發表于 01-11 06:20

    基于Numpy實現同態加密神經網絡

    在分布式AI環境下,同態加密神經網絡有助于保護商業公司知識產權和消費者隱私。本文介紹了如何基于Numpy實現同態加密神經網絡。
    的頭像 發表于 03-27 14:52 ?8021次閱讀
    基于<b class='flag-5'>Numpy</b>實現同態加密<b class='flag-5'>神經網絡</b>

    基于Numpy實現神經網絡:反向傳播

    和DeepMind數據科學家、Udacity深度學習導師Andrew Trask起,基于Numpy手寫神經網絡,更深刻地理解反向傳播這概念。
    的頭像 發表于 04-01 09:29 ?5207次閱讀
    基于<b class='flag-5'>Numpy</b>實現<b class='flag-5'>神經網絡</b>:反向傳播

    基于Numpy實現神經網絡:如何加入和調整dropout?

    幾乎所有目前最先進的神經網絡都用到了dropout. 這篇教程介紹如何通過幾行Python代碼在神經網絡中加入Dropout. 讀完這篇教程之后,你將得到
    的頭像 發表于 04-15 09:59 ?7679次閱讀
    基于<b class='flag-5'>Numpy</b>實現<b class='flag-5'>神經網絡</b>:如何加入和調整dropout?

    如何使用numpy搭建卷積神經網絡詳細方法和程序概述

    內容將繼續秉承之前 DNN 的學習路線,在利用Tensorflow搭建神經網絡之前,先嘗試利用numpy手動搭建卷積神經網絡,以期對卷積神經網絡的卷積機制、前向傳播和反向傳播的原理和過
    的頭像 發表于 10-20 10:55 ?6123次閱讀

    如何使用Numpy搭建神經網絡

    很多同學入門機器學習之后,直接用TensorFlow調包實現神經網絡,對于神經網絡內在機理知之甚少。
    的頭像 發表于 05-18 11:02 ?3640次閱讀
    如何使用<b class='flag-5'>Numpy</b>搭建<b class='flag-5'>神經網絡</b>

    卷積神經網絡工作原理 卷積神經網絡通俗解釋

    。CNN可以幫助人們實現許多有趣的任務,如圖像分類、物體檢測、語音識別、自然語言處理和視頻分析等。本文將詳細介紹卷積神經網絡工作原理并用通俗易懂的語言解釋。 1.概述 卷積神經網絡
    的頭像 發表于 08-21 16:49 ?3936次閱讀

    使用NumPy實現前饋神經網絡

    要使用NumPy實現前饋神經網絡(Feedforward Neural Network),我們需要從基礎開始構建,包括初始化網絡參數、定
    的頭像 發表于 07-11 16:30 ?2037次閱讀
    主站蜘蛛池模板: 天天操夜夜操夜夜操 | 国产色婷婷精品免费视频 | 最色网在线观看 | 一区二区三区在线播放 | 老色歌uuu26 老湿成人影院 | 亚洲国产日韩女人aaaaaa毛片在线 | 亚洲午夜一级毛片 | 日本黄色免费电影 | 1515hh四虎免费观38com | 91亚色视频在线观看 | 九九国产精品视频 | 国产精欧美一区二区三区 | 五月激情综合 | 中文字幕在线观看一区二区三区 | 婷婷开心六月久久综合丁香 | 国产精品人人爱一区二区白浆 | 国产美女免费 | 狠狠色噜噜狠狠狠 | 午夜情趣视频 | 午夜不卡影院 | 亚洲免费网 | 日韩欧美成人乱码一在线 | 久久久久性 | 性欧美丨18一19 | 男人呻吟双腿大开男男h互攻 | 激情综合在线 | 香港三级理论在线观看网站 | 在线免费视频手机版 | 在线免费视频你懂的 | 天堂资源地址在线 | 在线观看日本免费视频大片一区 | 久久久综合视频 | 中文字幕亚洲综合久久2 | www.欧美黄色 | 一卡二卡≡卡四卡亚洲高清 | 调教双性学霸美人 | 亚洲毛片基地4455ww | 久久午夜神器 | 黄色片xxxx | 婷婷午夜激情 | 一女被两男吃奶玩乳尖口述 |