最近两天,我在网上查找相关资料学习了多层神经网络的相关信息。
然后根据查找到的资料,我自己也设计了一个异或逻辑神经网络的学习。
① 设计输入和输出input= [[0, 0],[0, 1],[1, 0],[1, 1]
output = [[0], [1], [1], [0]]
设计学习率learn=0.05
设计矫正率correct=0.1
②设计隐含层中的神经元数量hidden(自己设定神经元的数量,也可以设计成多个隐藏层的样式),并随机给每个神经元分配一组初始权值。
③四组输入依次经过神经元的算法得到该层神经元的输出
for j in range(hidden_n):
total = 0.0
for i in range(input_n):
total += input[i] * input_weights[i][j]
hidden[j] = sigmoid(total)
多层隐藏层则将③计算出的输出带入下一层即可,改变参数就可以继续计算
④将隐藏层中计算出的数据再次经过计算得到最终输出。
for k in range(output_n):
total = 0.0
for j in range(hidden_n):
total += hidden_cells[j] * output_weights[j][k]
output_cells[k] = sigmoid(total)
⑤将最终输出与原来的标准输出作比较算出误差,输出层的误差和隐藏层的误差
for o in range(output_n):
error = output[o] - output_cells[o]
output_deltas[o] = sigmod_derivate(output_cells[o]) * error
for h in range(hidden_n):
error = 0.0
for o in range(output_n):
error += output_deltas[o] * output_weights[h][o]
hidden_deltas[h] = sigmod_derivate(hidden_cells[h]) * error
⑥将反馈回来的误差传回输出层和隐藏层,计算后修改权值
for h in range(self.hidden_n):
for o in range(self.output_n):
change = output_deltas[o] * self.hidden_cells[h]
self.output_weights[h][o] += learn * change + correct * self.output_correction[h][o]
self.output_correction[h][o] = change
for i in range(input_n):
for h in range(hidden_n):
change = hidden_deltas[h] *input_cells[i]
input_weights[i][h] += learn * change + correct * self.input_correction[i][h]
input_correction[i][h] = change
循环③至⑥10000次,得到经过训练后的权值。
import math
import random
random.seed(0)
def rand(a, b):
return (b - a) * random.random() + a
def make_matrix(m, n, fill=0.0):
mat = []
for i in range(m):
mat.append([fill] * n)
return mat
def sigmoid(x):
return 1.0 / (1.0 + math.exp(-x))
def sigmoid_derivative(x):
return x * (1 - x)
class BPNeuralNetwork:
def __init__(self):
self.input_n = 0
self.hidden_n1 = 0
self.hidden_n2 = 0
self.output_n = 0
self.input_cells = []
self.first_hidden_cells = []
self.second_hidden_cells=[]
self.output_cells = []
self.input_weights = []
self.hidden_weights=[]
self.output_weights = []
self.input_correction = []
self.hidden_correction=[]
self.output_correction = []
def setup(self, ni, nh1,nh2,no):
#save inputs and bias
self.input_n = ni + 1
self.hidden_n1 = nh1
self.hidden_n2 = nh2
self.output_n = no
# init cells
self.input_cells = [1.0] * self.input_n
self.first_hidden_cells = [1.0] * self.hidden_n1
self.second_hidden_cells = [1.0] * self.hidden_n2
self.output_cells = [1.0] * self.output_n
# init weights
self.input_weights = make_matrix(self.input_n, self.hidden_n1)
self.hidden_weights = make_matrix(self.hidden_n1, self.hidden_n2)
self.output_weights = make_matrix(self.hidden_n2, self.output_n)
# random activate
for i in range(self.input_n):
for h in range(self.hidden_n1):
self.input_weights[i][h] = rand(-2.0, 2.0)
for h1 in range(self.hidden_n1):
for h2 in range(self.hidden_n2):
self.hidden_weights[h1][h2]=rand(-2.0,2.0)
for h in range(self.hidden_n2):
for o in range(self.output_n):
self.output_weights[h][o] = rand(-2.0, 2.0)
# init correction matrix
self.input_correction = make_matrix(self.input_n, self.hidden_n1)
self.hidden_correction = make_matrix(self.hidden_n1,self.hidden_n2)
self.output_correction = make_matrix(self.hidden_n2, self.output_n)
def predict(self, inputs):
# activate input layer
for i in range(self.input_n - 1):
self.input_cells[i] = inputs[i]
# activate first hidden layer
for j in range(self.hidden_n1):
total = 0.0
for i in range(self.input_n):
total += self.input_cells[i] * self.input_weights[i][j]
self.first_hidden_cells[j] = sigmoid(total)
# activate second hidden layer
for j in range(self.hidden_n2):
total = 0.0
for i in range(self.hidden_n1):
total += self.first_hidden_cells[i] * self.hidden_weights[i][j]
self.second_hidden_cells[j] = sigmoid(total)
# activate output layer
for k in range(self.output_n):
total = 0.0
for j in range(self.hidden_n2):
total += self.second_hidden_cells[j] * self.output_weights[j][k]
self.output_cells[k] = sigmoid(total)
return self.output_cells[:]
def back_propagate(self, case, label, learn, correct):
# feed forward
self.predict(case)
# get output layer error
output_deltas = [0.0] * self.output_n
for o in range(self.output_n):
error = label[o] - self.output_cells[o]
output_deltas[o] = sigmoid_derivative(self.output_cells[o]) * error
# get second hidden layer error
second_hidden_deltas = [0.0] * self.hidden_n2
for h in range(self.hidden_n2):
error = 0.0
for o in range(self.output_n):
error += output_deltas[o] * self.output_weights[h][o]
second_hidden_deltas[h] = sigmoid_derivative(self.second_hidden_cells[h]) * error
# get first hidden layer error
first_hidden_deltas = [0.0] * self.hidden_n1
for h in range(self.hidden_n1):
error = 0.0
for o in range(self.hidden_n2):
error += first_hidden_deltas[o] * self.hidden_weights[h][o]
first_hidden_deltas[h] = sigmoid_derivative(self.first_hidden_cells[h]) * error
# update output weights
for h in range(self.hidden_n2):
for o in range(self.output_n):
change = output_deltas[o] * self.second_hidden_cells[h]
self.output_weights[h][o] += learn * change + correct * self.output_correction[h][o]
self.output_correction[h][o] = change
# update hidden weights
for h in range(self.hidden_n1):
for o in range(self.hidden_n2):
change = second_hidden_deltas[o] * self.first_hidden_cells[h]
self.hidden_weights[h][o] += learn * change + correct * self.hidden_correction[h][o]
self.hidden_correction[h][o] = change
# update input weights
for i in range(self.input_n):
for h in range(self.hidden_n1):
change = first_hidden_deltas[h] * self.input_cells[i]
self.input_weights[i][h] += learn * change + correct * self.input_correction[i][h]
self.input_correction[i][h] = change
#print(self.input_weights)
# get error
error = 0.0
for o in range(len(label)):
error += 0.5 * (label[o] - self.output_cells[o]) ** 2
def train(self, cases, labels, limit=10000, learn=0.05, correct=0.1):
for j in range(limit):
# error = 0.0
for i in range(len(cases)):
label = labels[i]
case = cases[i]
self.back_propagate(case, label, learn, correct)
def test(self):
cases = [
[0, 0],
[0, 1],
[1, 0],
[1, 1],
]
labels = [[0], [1], [1], [0]]
self.setup(2, 5, 5, 1)
self.train(cases, labels, 10000, 0.05, 0.1)
for case in cases:
print(self.predict(case))
if __name__ == '__main__':
nn = BPNeuralNetwork()
nn.test()