本文實例講述了Python實現的三層BP神經網絡算法。分享給大家供大家參考,具體如下:
這是一個非常漂亮的三層反向傳播神經網絡的python實現,下一步我準備試著將其修改為多層BP神經網絡。
下面是運行演示函數的截圖,你會發現預測的結果很驚人!
提示:運行演示函數的時候,可以嘗試改變隱藏層的節點數,看節點數增加了,預測的精度會否提升
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
import math import random import string random.seed( 0 ) # 生成區間[a, b)內的隨機數 def rand(a, b): return (b - a) * random.random() + a # 生成大小 I*J 的矩陣,默認零矩陣 (當然,亦可用 NumPy 提速) def makeMatrix(I, J, fill = 0.0 ): m = [] for i in range (I): m.append([fill] * J) return m # 函數 sigmoid,這里采用 tanh,因為看起來要比標準的 1/(1+e^-x) 漂亮些 def sigmoid(x): return math.tanh(x) # 函數 sigmoid 的派生函數, 為了得到輸出 (即:y) def dsigmoid(y): return 1.0 - y * * 2 class NN: ''' 三層反向傳播神經網絡 ''' def __init__( self , ni, nh, no): # 輸入層、隱藏層、輸出層的節點(數) self .ni = ni + 1 # 增加一個偏差節點 self .nh = nh self .no = no # 激活神經網絡的所有節點(向量) self .ai = [ 1.0 ] * self .ni self .ah = [ 1.0 ] * self .nh self .ao = [ 1.0 ] * self .no # 建立權重(矩陣) self .wi = makeMatrix( self .ni, self .nh) self .wo = makeMatrix( self .nh, self .no) # 設為隨機值 for i in range ( self .ni): for j in range ( self .nh): self .wi[i][j] = rand( - 0.2 , 0.2 ) for j in range ( self .nh): for k in range ( self .no): self .wo[j][k] = rand( - 2.0 , 2.0 ) # 最后建立動量因子(矩陣) self .ci = makeMatrix( self .ni, self .nh) self .co = makeMatrix( self .nh, self .no) def update( self , inputs): if len (inputs) ! = self .ni - 1 : raise ValueError( '與輸入層節點數不符!' ) # 激活輸入層 for i in range ( self .ni - 1 ): #self.ai[i] = sigmoid(inputs[i]) self .ai[i] = inputs[i] # 激活隱藏層 for j in range ( self .nh): sum = 0.0 for i in range ( self .ni): sum = sum + self .ai[i] * self .wi[i][j] self .ah[j] = sigmoid( sum ) # 激活輸出層 for k in range ( self .no): sum = 0.0 for j in range ( self .nh): sum = sum + self .ah[j] * self .wo[j][k] self .ao[k] = sigmoid( sum ) return self .ao[:] def backPropagate( self , targets, N, M): ''' 反向傳播 ''' if len (targets) ! = self .no: raise ValueError( '與輸出層節點數不符!' ) # 計算輸出層的誤差 output_deltas = [ 0.0 ] * self .no for k in range ( self .no): error = targets[k] - self .ao[k] output_deltas[k] = dsigmoid( self .ao[k]) * error # 計算隱藏層的誤差 hidden_deltas = [ 0.0 ] * self .nh for j in range ( self .nh): error = 0.0 for k in range ( self .no): error = error + output_deltas[k] * self .wo[j][k] hidden_deltas[j] = dsigmoid( self .ah[j]) * error # 更新輸出層權重 for j in range ( self .nh): for k in range ( self .no): change = output_deltas[k] * self .ah[j] self .wo[j][k] = self .wo[j][k] + N * change + M * self .co[j][k] self .co[j][k] = change #print(N*change, M*self.co[j][k]) # 更新輸入層權重 for i in range ( self .ni): for j in range ( self .nh): change = hidden_deltas[j] * self .ai[i] self .wi[i][j] = self .wi[i][j] + N * change + M * self .ci[i][j] self .ci[i][j] = change # 計算誤差 error = 0.0 for k in range ( len (targets)): error = error + 0.5 * (targets[k] - self .ao[k]) * * 2 return error def test( self , patterns): for p in patterns: print (p[ 0 ], '->' , self .update(p[ 0 ])) def weights( self ): print ( '輸入層權重:' ) for i in range ( self .ni): print ( self .wi[i]) print () print ( '輸出層權重:' ) for j in range ( self .nh): print ( self .wo[j]) def train( self , patterns, iterations = 1000 , N = 0.5 , M = 0.1 ): # N: 學習速率(learning rate) # M: 動量因子(momentum factor) for i in range (iterations): error = 0.0 for p in patterns: inputs = p[ 0 ] targets = p[ 1 ] self .update(inputs) error = error + self .backPropagate(targets, N, M) if i % 100 = = 0 : print ( '誤差 %-.5f' % error) def demo(): # 一個演示:教神經網絡學習邏輯異或(XOR)------------可以換成你自己的數據試試 pat = [ [[ 0 , 0 ], [ 0 ]], [[ 0 , 1 ], [ 1 ]], [[ 1 , 0 ], [ 1 ]], [[ 1 , 1 ], [ 0 ]] ] # 創建一個神經網絡:輸入層有兩個節點、隱藏層有兩個節點、輸出層有一個節點 n = NN( 2 , 2 , 1 ) # 用一些模式訓練它 n.train(pat) # 測試訓練的成果(不要吃驚哦) n.test(pat) # 看看訓練好的權重(當然可以考慮把訓練好的權重持久化) #n.weights() if __name__ = = '__main__' : demo() |
希望本文所述對大家Python程序設計有所幫助。
原文鏈接:http://www.cnblogs.com/hhh5460/p/4304628.html