本文实例讲述了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