參考教程 python 手動搭建ANN,並進行具體實現


用 Python 手動進行 ANN 的搭建(簡單的BP型網絡),可加深對其深入的理解,同時熟練coding,具有xxx、yyy之功效。

網上手動建NN的帖子有不少,不過多數沒有實現過程,這里把這一部分補上,方便大家參考使用。

 

前半步主要是參考如下的帖子,建立 ANN:

  • https://towardsdatascience.com/how-to-build-your-own-neural-network-from-scratch-in-python-68998a08e4f6

    但這個帖子有個問題,就是建立了ANN 卻並沒有實現過程,同時其中前后傳播方法的‘feedforward’和 ‘backprop’ 中的sigmoid函數及其導數也沒有具體的函數定義。

 
    • 因此,進一步參考如下的網頁:

    • http://python3.codes/neural-network-python-part-1-sigmoid-function-gradient-descent-backpropagation/
    • http://python.jobbole.com/82758/

      另外下面的這個也不錯,只是有點太細碎了,大線條看着有點亂:

    • http://www.bogotobogo.com/python/python_Neural_Networks_Backpropagation_for_XOR_using_one_hidden_layer.php

       

以下具體步驟:

1. 建立 ANN:

 有些說明在注釋中寫了。

 1 class NeuralNetwork:
 2     
 3     # 通過初始化的方式實現 輸入‘x’及輸出‘y’、以及網絡權重(定義了二層4節點的網絡結構) 的基本結構:
 4     def __init__(self, x, y):
 5         self.input = x
 6         self.weights1 = np.random.rand(self.input.shape[1],4) 
 7         # 這樣的結構,意味着weights1的行數是輸入變量x的列數,那么相乘時可能是與常規的 W·X 的方式相反,即 X·W
 8         # 因此,X的每一行,代表着一次x輸入,對應着每一個輸出y
 9         
10         # 同上的,這樣的結構形式定義,代表的表達式或應是:[(X·W1+b1)·W2]+b2
11         ## 而在經過上述W1與W2的相乘后,每一行的x對應着一個y_i的值
12         self.weights2 = np.random.rand(4,1)
13         
14         # 對應着y作為輸出,定義self.output 的結構
15         self.y = y
16         self.output = np.zeros(y.shape)
17 
18     
19     def feedforward(self): #定義前傳方法:
20         # 注意忽略了每層的偏差 b_i
21         # 且轉換函數使用 sigmoid()
22         # 因沒有相應的函數定義,將其中的 sigmoid() 函數進行展開
23         # sigmoid(m)=1/(1 + np.exp(-m))
24        
25         npDotW1_Inpt = np.dot(self.input, self.weights1)
26         self.layer1 = 1/(1+np.exp(-1*npDotW1_Inpt))
27         
28         npDotL1_W2 = np.dot(self.layer1, self.weights2)
29         self.output = 1/(1+np.exp(-1*npDotL1_W2))
31         
32     def backprop(self): # 定義后傳方法:
33         # application of the chain rule to find derivative of the loss function with respect to weights2 and weights1
34         # 以上是原文注解,即在向后傳播 backprop 時,使用鏈式法則獲得相應權重值的損失函數
35         # 因沒有相應的函數定義,將原貼中的 sigmoid_derivative() 函數進行展開
36         # sigmoid_derivative(m)=m * (1 - m)
37 
38         ## 此處采用的是 s_deriv(x) = x*(1-x) 的方式,如采用 exp(-x)/(1+exp(-x))^2) 的解析式也可以,本質相同:
39         d_weights2 = np.dot(self.layer1.T, (2*(self.y - self.output) * (self.output*(1-self.output))))
40         d_weights1 = np.dot(self.input.T,  (np.dot(2*(self.y - self.output) * (self.output*(1-self.output)), self.weights2.T) * (self.layer1*(1-self.layer1))))
41     
42         # update the weights with the derivative (slope) of the loss function
43         # 通過上面的求導斜率,對W1和W2進行更新:
44         self.weights1 += d_weights1
45         self.weights2 += d_weights2            

 

2. 實現過程:

此步原文沒有寫,估計作者覺得太簡單了,貂尾續根草吧。

但這里的輸入和輸出是按原文給的,便於對比實現結果是否一致。

 1 # 建立輸入和輸出變量:
 2 x_input = np.array([[0,0,1],[0,1,1],[1,0,1],[1,1,1]])
 3 y_obj = np.array([[0,1,1,0]]).T
 4 
 5 # 實例化 ANN:
 6 nn = NeuralNetwork(x_input, y_obj)
 7 
 8 # 進行計算,迭代次數為1500次:
 9 m = 1500
10 loss = np.zeros(m)
11 
12 for i in range(m):
13     nn.feedforward() # 前傳計算結果
14     nn.backprop() # 后傳更新權重
15 
16     loss[i] = np.sum((nn.output-y_obj)**2) # 記錄每次的結果偏差
17 
18 # 繪制結果圖形:
19 plt.plot(loss)
20 plt.xlabel('Iteration')
21 plt.ylabel('LossValue')
22 plt.grid(True)

 

結果如圖:

Enjoy it  :)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM