人工智慧不神秘,會一點加減乘除就夠了。
對於神經元來說,當神經受到刺激的時候,會釋放神經遞質傳給下一個神經元,不同程度的刺激對下一個神經元釋放的神經遞質的量也不同,所以模仿這個過程建立神經網路:
當輸入一個資料x的時候,類比輸入一個外界刺激,經過處理後,輸出的結果為f(x),把這個f(x)傳給下一個神經元,逐步求解,最終輸出一個值z,與給定的值進行對比(有監督學習),根據結果調整每個的神經元內建函式的參數,稱為反向擴散,然後在下一輪來重複這個過程,直到達到指定迭代次數,通過不斷調整參數以接近損失(lost)最小的點。
可以看出,輸出的值z應該具有一個範圍,比如識別一組圖片是否為貓,則在訓練範例中,結果應該是0或者1,那麼輸出也應該對應為0或1,所以需要映射到0/1上。而如果分類數增加,那麼範圍也應該相應擴大。
所以,舉例進行學習:
輸入為x,例如一張圖片,像素為34*34pixels,那麼根據RGB成色原理,共有34*34*3個資料,所以將x映射為一個(34*34*3, 1)的矩陣(一般採用w的轉置矩陣,即wT),按照R(34*34),G(34*34),B(34*34)進行排列。
下一步需要確定f(x)函數,先採取比較簡單的線性(一次)神經網路,比較常見的一元一次方程形式為f(x)= ax+b,所以採用類似的形式:
f(x) = W*x + b
其中,W為weight權重,b為bias偏差,即學習調整參數,也就是調整W和b的值。
注意:
矩陣相乘對矩陣的大小是有要求的,在這裡x的規格為(34*34*3, 1),所以W的列數也應該為34*34*3,如果我們只有一層神經元,那麼f(x)就是一個數,即(1, 1)的矩陣,所以此處W的大小應為(1, 34*34*3),b僅僅是一個常數。
線性方程的範圍大家都知道,是(-∞,+∞),所以我們需要映射到 [0,1] 的區間,也需要一個方程:
sigmoid(z) = 1 / (1 + e^(-z))
將變數映射到0,1之間,選擇這個方程的原因是求導容易, s’(x) = s(x) / (1 – s(x)).
評價參數是否合理也需要一個方程,即損失方程(Loss),表示的含義為預測值與標準(監督)值之間的偏差,盡量減小這個偏差來達到更好的預測(分類)效果,比較常用的損失方程為:
定義,a為預測值,y為準確值。
L(a, y)= -y * log(a)- (1 - y) * log (1 - a)
如果有m個訓練範例的話,平均損失函數為值加起來後除以m,即
L = sum(Li) / m
計算完cost後需要調整W和b的值,因為我們需要cost的值減小,所以需要對L方程求導擷取梯度值(gradient),逐步朝著最小值前進,此處’dw’、’db’均為方便在python代碼中進行表示,實際含義為右側等式(求的是微分):
‘dw’ = dJ/dw = (dj/dz)*(dz/dw)= X*(A-Y)T / m
‘db’ = dj/db = sum(a-y) / m
所以新的值為:
w = w – α * dw
b = b – α * db,其中 α 為學習速率,在下一輪迭代中採用新的w、b。
設定迭代次數,迭代完畢後,就是最終得到的參數w, b,用測試案例來驗證識別準確率,一般應該在70%以上。
在我的博文“知乎爬蟲”中,會有關於爬取資料進行訓練的代碼編寫過程,目前僅需要明白神經網路流程即可。
具體的代碼在https://github.com/Lee-Jiazheng/My_neural_network.git中的base_func.py,實現了簡單的神經網路,後續會增加更多神經元和最佳化速度。