最近在看吴恩达老师的机器学习视频,讲到神经网络时有些模糊,于是决定自己用代码实现一下最基本的神经网络。

关于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
import numpy as np

class NeuralNetwork(object):
def __init__(self,input_nodes,hidden_nodes,output_nodes,learning_rate):
#设定输入层,隐藏层,输出层的节点个数
self.input_nodes = input_nodes+1
# +1 设置偏执神经元来进行修正
self.hidden_nodes = hidden_nodes
self.output_nodes = output_nodes

#初始化权值和学习速率
self.weight_input_to_hidden = np.random.normal(0.0,self.hidden_nodes**-0.5,(self.hidden_nodes,self.input_nodes))
self.weight_hidden_to_output = np.random.normal(0.0,self.output_nodes**-0.5,(self.output_nodes,self.hidden_nodes))

self.lr = learning_rate

#激励函数
def Sigmoid(self,x):
return 1.0 / (1.0 + np.exp(-x))

def train(self,input_list,target_list):
inputs = np.array(input_list,ndmin=2).T
targets = np.array(target_list,ndmin=2).T

#前向传播
hidden_inputs = np.dot(self.weight_input_to_hidden,inputs)
hidden_outputs= self.Sigmoid(hidden_inputs)

final_inputs = np.dot(self.weight_hidden_to_output,hidden_outputs)
final_outputs = self.Sigmoid(final_inputs)

#反向传播
outputs_errors = (final_outputs - targets) * final_outputs * (1 - final_outputs)
hidden_errors = np.dot(self.weight_hidden_to_output.T,outputs_errors)

#梯度下降
self.weight_input_to_hidden -= np.dot((hidden_errors * hidden_outputs * (1 - hidden_outputs)),inputs.T) * self.lr
self.weight_hidden_to_output -= np.dot(outputs_errors,hidden_outputs.T) *self.lr

print("误差:")
print(1/2 * np.square((final_outputs-targets)))
#测试函数
def run(self,inputs_list):
inputs = np.array(inputs_list,ndmin=2).T

hidden_inputs = np.dot(self.weight_input_to_hidden,inputs)
hidden_outputs = self.Sigmoid(hidden_inputs)

final_inputs = np.dot(self.weight_hidden_to_output,hidden_outputs)
final_outputs = self.Sigmoid(final_inputs)

return final_outputs

#测试用神经网络实现异或功能
def main():
cases = [[0,0,0.1],
[0,1,0.1],
[1,0,0.1],
[1,1,0.1]]

labels = [[0],[1],[1],[0]]
#迭代10000次
limit = 10000
nn = NeuralNetwork(2,4,1,0.5)

for i in range(limit):
for i in range(4):
nn.train(cases[i],labels[i])

a = nn.run([1,1,0.1])
print(a)

if __name__ == '__main__':
main()

只在输入层加入了偏执神经元,在第二层并没有添加,在第二层添加对拟合效果的提升并不是很大(主要是实现会更复杂一些(逃