bp

import numpy as np
import math
import random
import string
import matplotlib as mpl
import matplotlib.pyplot as plt

def random_number(a, b):
return (b - a) * random.random() + a


def makematrix(m, n, fill=0.0):
a = []
for i in range(m):
a.append([fill] * n)
return a


def sigmoid(x):
return math.tanh(x)


def derived_sigmoid(x):
return 1.0 - x ** 2


class BPNN:
def __init__(self, num_in, num_hidden, num_out):
self.num_in = num_in + 1
self.num_hidden = num_hidden + 1
self.num_out = num_out

self.active_in = [1.0] * self.num_in
self.active_hidden = [1.0] * self.num_hidden
self.active_out = [1.0] * self.num_out

self.wight_in = makematrix(self.num_in, self.num_hidden)
self.wight_out = makematrix(self.num_hidden, self.num_out)

for i in range(self.num_in):
for j in range(self.num_hidden):
self.wight_in[i][j] = random_number(-0.2, 0.2)
for i in range(self.num_hidden):
for j in range(self.num_out):
self.wight_out[i][j] = random_number(-0.2, 0.2)

self.ci = makematrix(self.num_in, self.num_hidden)
self.co = makematrix(self.num_hidden, self.num_out)

def update(self, inputs):
if len(inputs) != self.num_in - 1:
raise ValueError('与输入层节点数不符')

for i in range(self.num_in - 1):
# self.active_in[i] = sigmoid(inputs[i])
self.active_in[i] = inputs[i] # active_in[]是输入数据的矩阵

for i in range(self.num_hidden - 1):
sum = 0.0
for j in range(self.num_in):
sum = sum + self.active_in[i] * self.wight_in[j][i]
self.active_hidden[i] = sigmoid(sum) # active_hidden[]是处理完输入数据之后存储,作为输出层的输入数据

for i in range(self.num_out):
sum = 0.0
for j in range(self.num_hidden):
sum = sum + self.active_hidden[j] * self.wight_out[j][i]
self.active_out[i] = sigmoid(sum)

return self.active_out[:]

def errorbackpropagate(self, targets, lr, m):
if len(targets) != self.num_out:
raise ValueError('与输出层节点数不符!')

out_deltas = [0.0] * self.num_out
for i in range(self.num_out):
error = targets[i] - self.active_out[i]
out_deltas[i] = derived_sigmoid(self.active_out[i]) * error

hidden_deltas = [0.0] * self.num_hidden
for i in range(self.num_hidden):
error = 0.0
for j in range(self.num_out):
error = error + out_deltas[j] * self.wight_out[i][j]
hidden_deltas[i] = derived_sigmoid(self.active_hidden[i]) * error

for i in range(self.num_hidden):
for j in range(self.num_out):
change = out_deltas[j] * self.active_hidden[i]
self.wight_out[i][j] = self.wight_out[i][j] + lr * change + m * self.co[i][j]
self.co[i][j] = change

for i in range(self.num_in):
for i in range(self.num_hidden):
change = hidden_deltas[j] * self.active_in[i]
self.wight_in[i][j] = self.wight_in[i][j] + lr * change + m * self.ci[i][j]
self.ci[i][j] = change

error = 0.0
for i in range(len(targets)):
error = error + 0.5 * (targets[i] - self.active_out[i]) ** 2
return error

def test(self, patterns):
for i in patterns:
print(i[0], '->', self.update(i[0]))

def weights(self):
print("输入层权重")
for i in range(self.num_in):
print(self.wight_in[i])
print("输出层权重")
for i in range(self.num_hidden):
print(self.wight_out[i])

def train(self, pattern, itera=100000, lr=0.1, m=0.1):
for i in range(itera):
error = 0.0
for j in pattern:
inputs = j[0]
targets = j[1]
self.update(inputs)
error = error + self.errorbackpropagate(targets, lr, m)
if i % 100 == 0:
print('误差 %-.5f' % error)


def demo():
patt = [
[[1, 2, 5], [0]],
[[1, 3, 4], [1]],
[[1, 6, 2], [1]],
[[1, 5, 1], [0]],
[[1, 8, 4], [1]]
]
n = BPNN(3, 3, 1)
n.train(patt)
n.test(patt)
n.weights()

if __name__ == '__main__':
demo()
posted @ 2022-03-18 18:00  zty666  阅读(300)  评论(0)    收藏  举报