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