一.神經網絡的大體結構可分為三個函數,分別如下:
1.初始化函數
設定輸入層節點,隱藏層節點和輸出層節點的數量。
2.訓練
學習給定訓練集樣本后,優化權重。
3.查詢
給定輸入,從輸出節點給出答案
所編寫的代碼框架可如下所示:
1 #神經網絡類定義 2 class NeuralNetwork(): 3 #初始化神經網絡 4 def _init_(): 5 pass 6 7 #訓練神經網絡 8 def train(): 9 pass 10 11 #查詢神經網絡 12 def query(): 13 pass
二.初始化網絡
需要設置輸入層節點,隱藏層節點和輸出層節點的數量,同時不要忘記設置學習率。
1 def _init_(self,inputnodes,hiddennodes,outputnodes,learningrate): 2 #設置輸入層節點,隱藏層節點和輸出層節點的數量 3 self.inodes = inputnodes 4 self.hnodes = hiddennodes 5 self.onodes = outputnodes 6 #學習率設置 7 self.lr = learningrate 8 pass
如果每層創建三個節點,學習率為0.5的小型神經網絡對象則如下所示:
1 #設置每層節點個數為3個 2 input_nodes = 3 3 hidden_nodes = 3 4 output_nodes = 3 5 #設置學習率為0.5 6 learning_rate =0.5 7 #創建神經網絡 8 n = NeuralNetwork(input_nodes,hidden_nodes,output_nodes,learning_rate)
三. 權重-網絡的核心
簡單而又比較流行的優化初始權重的方式是:使用正態概率分布采樣權重,其中平均值為0,標准方差為節點傳入鏈接數目的開方。
python中可用numpy.random.normal()函數來以正態分布的方式采樣,其中初始化權重的代碼如下所示:
self.wih = numpy.random.normal(0.0,pow(self.hnodes,-0.5),(self.hnodes,self.inodes))
self.who = numpy.random.normal(0.0,pow(self.onodes,-0.5),(self.onodes,self.hnodes))
我將正態分布的中心設置為0.0,與下一層中節點相關的標准方差為節點數目的-0.5次方,最后一個參數,是numpy數組的形狀大小。
因為權重是神經網絡的固有部分,與神經網絡共存亡,它不是一個臨時的數據集,不會隨着函數調用結束而消失,因此,權重必須也是初始化的一部分,並且可以使用其他函數(如訓練函數和查詢函數)來訪問。
四.查詢網絡
query()函數接受神經網絡的輸入,返回網絡的輸出,它需要來自輸入層節點的輸入信號,通過隱藏層,最后從輸出層輸出。
(1)第一步需要做的是輸入的數據和輸入層與隱藏層之間的權重矩陣相乘,得到傳輸到隱藏層的輸入信號,可表示如下:
Xhidden = Winput_hidden * I
用python可表示為:
hidden_inputs= numpy.dot(self.wih,inputs)
(2)為了獲得從隱藏層節點處出現的信號,需要增加激活函數sigmod()
Ohidden = sigmod(Xhidden)
python中的Scripy庫中有此函數,可表示為:
import scripy.special self.activation_function = lambda x:scripy.special.expit(x)
(3)隱藏層的輸入輸出呢?和上面的思路一樣,可定義如下:
1 #計算到輸出層的信號 2 final_inputs= numpy.dot(self.who,hidden_outputs) 3 final_outputs = self.activation_function(final_inputs)
至此,訓練函數還沒有完成,以上部分的完整代碼如下:
import numpy import scripy.special #神經網絡類定義 class NeuralNetwork(): #初始化神經網絡 def _init_(self,inputnodes,hiddennodes,outputnodes,learningrate): #設置輸入層節點,隱藏層節點和輸出層節點的數量 self.inodes = inputnodes self.hnodes = hiddennodes self.onodes = outputnodes #學習率設置 self.lr = learningrate #權重矩陣設置 正態分布 self.wih = numpy.random.normal(0.0,pow(self.hnodes,-0.5),(self.hnodes,self.inodes)) self.who = numpy.random.normal(0.0,pow(self.onodes,-0.5),(self.onodes,self.hnodes)) #激活函數設置,sigmod()函數 self.activation_function = lambda x:scripy.special.expit(x) pass #訓練神經網絡 def train(): pass #查詢神經網絡 def query(self,input_list): #轉換輸入列表到二維數組 inputs = numpy.array(input_list,ndmin = 2).T #計算到隱藏層的信號 hidden_inputs= numpy.dot(self.wih,inputs) #計算隱藏層輸出的信號 hidden_outputs = self.activation_function(hidden_inputs) #計算到輸出層的信號 final_inputs= numpy.dot(self.who,hidden_outputs) final_outputs = self.activation_function(final_inputs) return final_outputs #設置每層節點個數為3個 input_nodes = 3 hidden_nodes = 3 output_nodes = 3 #設置學習率為0.5 learning_rate =0.5 #創建神經網絡 n = NeuralNetwork(input_nodes,hidden_nodes,output_nodes,learning_rate)
下面定義一個輸入為:
print(n.query([1.0,0.5,-1.5]))
可看到程序的實際運行效果為:
[[0.65948789] [0.4672955 ] [0.66051158]]
輸入是列表,輸出也是一個列表。正確,但是這個輸出沒有實際意義,因為我們還沒有訓練網絡。