很多同學入門機器學習之后,直接用TensorFlow調包實現(xiàn)神經(jīng)網(wǎng)絡,對于神經(jīng)網(wǎng)絡內在機理知之甚少。
編程語言與技術框架變化更新非常之快,理解背后的原理才是王道。下面文摘菌和大家一起用Numpy實現(xiàn)一步一步實現(xiàn)神經(jīng)網(wǎng)絡。
此篇文章旨在幫大家梳理神經(jīng)網(wǎng)絡知識點,且此篇文章是第一部分,只是簡單搭一個簡單的框架。暫時不涉及梯度下降、學習率調參等知識點。
最簡單的神經(jīng)網(wǎng)絡包含三個要素,輸入層,隱藏層以及輸出層。關于其工作機理其完全可以類比成一個元函數(shù):Y=W*X+b。
一個簡單的神經(jīng)網(wǎng)絡可以理解為兩次一元函數(shù)的輸入和輸出。
第一次:Y1=A1(W1*X+b1) ,其中X是原始數(shù)據(jù)的輸入,A1代表激活函數(shù)。
第二次:Y2=A2(W2*Y1+b2),其中Y1是第一次的輸出,A2是激活函數(shù)。參數(shù)W1、W2、b1、b2原則上各不相同。
本篇文章我們用到的激活函數(shù)有兩個,一個是tan(x),另一個是softmax。兩者的函數(shù)曲線如下。
兩個函數(shù)都有相同的特點,即函數(shù)值在零點左右變化較大,當輸入值遠離零點,其輸出較穩(wěn)定。
首先導入相關的庫,需要兩個庫,一個用于科學計算的Numpy,另一個是math。
importnumpyasnpimport math
然后定義激活函數(shù),
def tanh(x): return np.tanh(x)def softmax(x): exp=np.exp(x-x.max()) return exp/exp.sum()
這兩個激活函數(shù),其中tanh函數(shù),Numpy直接內嵌。softmax根據(jù)數(shù)學定義進行設置。第二個激活函數(shù)因為是指數(shù)函數(shù),其值會變化較大,所以我們用x-x.max 縮小其變化范圍,這對結果不影響。
我們使用的圖片大小是 28*28像素。以后會用手寫數(shù)字數(shù)據(jù)集訓練網(wǎng)絡,所以會有10個數(shù)字輸入,分別是[1,2,3,4,5,6,7,8,9,10]。所以要先定義三個列表。
dinensions=[28*28,10]activation=[tanh,softmax]distribution=[{'b':[0,0]},{'b':[0,0],'w':[-math.sqrt(6/(dinensions[0]+dinensions[1])),math.sqrt(6/(dinensions[0]+dinensions[1]))]}]
dinensions列表里面包含兩個數(shù),第一個是圖片的像素大小,第二個是數(shù)字的輸入變化量。
activation列表包含兩個激活函數(shù),分別為tanh,softmax。
distribution 列表里面對應的是字典格式的數(shù)據(jù),分別對應神經(jīng)網(wǎng)絡參數(shù)取值范圍。
其中第一層不包含參數(shù)W。
definit_parameters_b(layer):dist=distribution[layer]['b'] return np.random.rand(dinensions[layer])*(dist[1]-dist[0])+dist[0] #使得生成的隨機數(shù)在 b 的區(qū)間內definit_parameters_w(layer):dist=distribution[layer]['w'] return np.random.rand(dinensions[layer-1],dinensions[layer])*(dist[1]-dist[0])+dist[0] #使得生成的隨機數(shù)在 b 的區(qū)間內
上面代碼是對b和w這兩個參數(shù)初始化,因為我們輸入的是28*28個數(shù)字,輸出的是10個數(shù)字。所以第一層的 b 也有28*28個數(shù)字組成。根據(jù)矩陣的乘法規(guī)則,第二層的時候,w的維度只有是28*28行,10列才能滿足輸出的10個數(shù)字。因此第二層的b是10個數(shù)字。
dinensions[X] 意思是取切片,dinensions[1] 取得是10,dinensions[0],取得是28*28。
又因為np.random.rand()這一函數(shù)輸出值的范圍在[0,1],括號里面的參數(shù)(即dinensions[layer]只是確保輸出的數(shù)字個數(shù)滿足要求),所以為了讓輸出的值在一開始設置的 b 的區(qū)間內,我們設置先乘(dist[1]-dist[0])然后加上dist[0]。dist[1]和dist[0]分別對應參數(shù)的上下限。
definit_parameters():parameters=[]foriinrange(len(distribution)):layer_parameters={}forjindistribution[i].keys():ifj=='b':layer_parameters['b']=init_parameters_b(i)continueifj=='w':layer_parameters['w']=init_parameters_w(i)continueparameters.append(layer_parameters) return parameters
上面代碼是將三個參數(shù)的初始化集成達到一個函數(shù)里面。
先定義一個空列表(不要寫錯成空字典)是為了將三個參數(shù)統(tǒng)一輸出。
注:字典類型不能用append,列表可以用,列表.append(字典) 也是可以的。
然后從零開始遍歷distribution。用if循環(huán)語句,目的是把參數(shù)全部包含進來。
第二層for循環(huán)和if語句是判斷,并正確添加參數(shù)。
parameters=init_parameters() #將參數(shù)賦值給新的變量。defpredict(img,parameters):I0_in=img+parameters[0]['b']I0_out=activation[0](I0_in)I1_in=np.dot(I0_out,parameters[1]['w']+parameters[1]['b'])I1_out=activation[1](I1_in) return I1_out
定義輸出函數(shù),思路是這樣的:輸入數(shù)據(jù)后,根據(jù)函數(shù):y=wx+b,進行變換,第一層w全為1。然后經(jīng)過激活函數(shù)(第一個激活函數(shù)是tanh,所以用activation[0]),得出第一層的輸入I0_out。 然后進入第二層,第一層的輸出作為輸入,根據(jù)函數(shù):y=wx+b,進行變換,第二層的w為parameters[1]['w'],第二層的b為parameters[1]['b']。然后再經(jīng)過激活函數(shù)softmax,得到輸出。
predict(np.random.rand(784),parameters).argmax()
最后,隨便輸入一個784維數(shù)據(jù)(像素),都可以輸出一個圖片標簽。
預測圖片中的數(shù)字
好了,我們第一個簡單的神經(jīng)網(wǎng)絡就搭建好了,關于如何使用梯度下降和學習率,如何訓練網(wǎng)絡以及如何加載圖片數(shù)據(jù),我們在以后的文章中會介紹。
注:此篇文章受B站up主大野喵渣的啟發(fā),并參考了其代碼,感興趣的同學可以去B站觀看他關于神經(jīng)網(wǎng)絡的教學視頻。
-
神經(jīng)網(wǎng)絡
+關注
關注
42文章
4797瀏覽量
102321 -
函數(shù)
+關注
關注
3文章
4365瀏覽量
63851 -
機器學習
+關注
關注
66文章
8481瀏覽量
133855
原文標題:TensorFlow什么的都弱爆了,強者只用Numpy搭建神經(jīng)網(wǎng)絡
文章出處:【微信號:BigDataDigest,微信公眾號:大數(shù)據(jù)文摘】歡迎添加關注!文章轉載請注明出處。
發(fā)布評論請先 登錄
相關推薦
神經(jīng)網(wǎng)絡教程(李亞非)
【PYNQ-Z2試用體驗】神經(jīng)網(wǎng)絡基礎知識
【PYNQ-Z2試用體驗】基于PYNQ-Z2的神經(jīng)網(wǎng)絡圖形識別[結項]
卷積神經(jīng)網(wǎng)絡如何使用
【案例分享】ART神經(jīng)網(wǎng)絡與SOM神經(jīng)網(wǎng)絡
如何構建神經(jīng)網(wǎng)絡?
基于BP神經(jīng)網(wǎng)絡的PID控制
輕量化神經(jīng)網(wǎng)絡的相關資料下載
使用keras搭建神經(jīng)網(wǎng)絡實現(xiàn)基于深度學習算法的股票價格預測
基于Numpy實現(xiàn)同態(tài)加密神經(jīng)網(wǎng)絡

基于Numpy實現(xiàn)神經(jīng)網(wǎng)絡:反向傳播

評論