Artificial intelligence, neural networks --BP

BP neural network should be relatively straightforward one all neural networks inside.

Of course, python is BP neural network library, but I give this code, a neural network model is a hidden layer of my own based on the case of the Internet Gangster, written in his own hand.

Flow of the code is as follows:
1. Read the data train training set, the test set of test data reading.
2. The data is normalized.
3. Initialize wherein w (weight), b (offset).
4. a randomly selected set of training data, for forward propagation, XI * H = Wi + .... + B1
5. The expected value of the correct answer for comparison. Obtained error value.
6. reverse spread by the error value. The correction value of the respective weights and offset values.
7. testing a test set, the recognition rate of the test model.
8. If the recognition rate is less than 80%, then repeat step 4
9 outputs the current accuracy

About optimization or improvement:
About learning rate: I am learning rate in the hidden layer to the output layer unified setting is 0.5, but the learning rate in the input layer to the hidden layer is uniformly set to 0.2 since the two. affect the end result is not as big, so the set of weights is not the same.
About the recognition rate: I made some compromise on the recognition rate, three data would have appeared to be more than 0.90 data appears I was correct judgment. But after debugging, I will change it to 0.75. But that did not make the correct rate becomes higher. So I think this should be hidden layer due to insufficient number of layers.
I'm the only one hidden layer, and only four nodes. I think this is one of the key issues affecting the recognition rate.

Training and test sets of data link:
link: https://pan.baidu.com/s/1O1Zvn4eNii3DJDSn03v43w
extraction code: 25eh

import random
import math
#该实验设置4个隐含层节点,3个输出层节点
#每个隐含层节点都有4个输出,3个输出
#权值都放在W中,其中
#共计有w0-w15作为输入层权值,w16-27是作为输出层权值
#阈值的初始值设置为1
#每一个隐含层节点都储存在独立的数组h中
#每层都有一个偏置数组
x = []#训练数据储存
w = []#hi权值的存放(28)
h = []#隐含层数组
out = []#输出层数组
b1 = []#偏置
b2 = []#偏置
y = []#测试集数据储存

def putin(w,a,j,b1):#计算输出层到隐含层的函数,w为权值数组,a为训练数组中元素,j为第几个中间隐含层
	sum = 0
	yin = b1[j]
	j = j * 4
	for n in range(0,4):
		sum = sum + a[n]*w[j]
		j = j + 1
	sum = sum + yin
	return sum

def putout(h,w,j,b2):#计算隐含层到输出层的函数
	sum = 0
	yin = b2[j]
	j = j + 16 + j * 3
	for n in range(0,3):
		sum = sum + h[n]*w[j]
		j = j + 1
	sum = sum + yin
	return sum

def back2w(O,out,h,i,j):#i为第几个输出层元素,j为隐含层的输入
	val = 0.0
	val = - 2/3 * (O[i] - out[i])
	val =  val * (out[i] * (1- out[i]) * h[j])
	return val

def back2b(O,out,h,i,j):#i为第几个输出层元素,j为隐含层的输入
	val = 0.0
	val = - 2/3 * (O[i] - out[i])
	val =  val * out[i] * (1- out[i])
	return val

def back1w(O,out,w,j):#i为第几个输出层元素,w[j]为权值
	sum = 0
	for i in range(3):
		val = 0.0
		val = - 2/3 * (O[i] - out[i])
		val =  val * (out[i] * (1- out[i]) * w[16 + j])
		sum = sum + val
		j = j + 4
	return sum

def sigmoid(h):#翻新隐含层数组
	for i in range(0,len(h)):
		AS = round(-h[i],6)
		y = 1/(math.exp(AS)+1)
		y = round(y,4)
		h[i] = y

def acc(O,out):
	max = out[0]
	max_v = 0
	for i in range(3):
		if out[i] > max:
			max = out[i]
			max_v = i
	if max >= 0.75:
		for i in range(3):
			if O[i] == 0.95:
				if max_v == i:
					return 1
	return 0

reload = 200 #最大学习次数为50次
f = open('iris-data-training.txt')
char = f.readline()
while char:#输入训练模型的数据
	char1 = char.split( )
	x1 = float(char1[0])
	x2 = float(char1[1])
	x3 = float(char1[2])
	x4 = float(char1[3])
	x5 = int(char1[4])
	char2 = [x1,x2,x3,x4,x5]
	x.append(char2)
	char = f.readline()
f.close()
x_max = []
x_min = []
for j in range(0,4):#x变量归一化
	max = 0
	min = 0
	for i in range(0,len(x)):
		if x[i][j] > max:
			max = x[i][j]
		if x[i][j] < min:
			min = x[i][j]
	x_max.append(max)
	x_min.append(min)
	for i in range(0,len(x)):
		x[i][j] = round(((x[i][j] - min)/(max-min)),4)
for i in range(0,len(x)):
	if x[i][4] == 1:
		x[i].append(0)
		x[i].append(0)
	if x[i][4] == 2:
		x[i][4] = 0
		x[i].append(1)
		x[i].append(0)
	if x[i][4] == 3:
		x[i][4] = 0
		x[i].append(0)
		x[i].append(1)

f = open('iris-data-testing.txt')
char = f.readline()
while char:#输入训练模型的数据
	char1 = char.split( )
	x1 = float(char1[0])
	x2 = float(char1[1])
	x3 = float(char1[2])
	x4 = float(char1[3])
	x5 = int(char1[4])
	char2 = [x1,x2,x3,x4,x5]
	y.append(char2)
	char = f.readline()
f.close()
for i in range(0,len(y)):
	for j in range(0,4):
		y[i][j] = round(((y[i][j] - x_min[j])/( x_max[j]- x_min[j])),4)
for i in range(0,len(y)):
	if y[i][4] == 1:
		y[i].append(0)
		y[i].append(0)
	if y[i][4] == 2:
		y[i][4] = 0
		y[i].append(1)
		y[i].append(0)
	if y[i][4] == 3:
		y[i][4] = 0
		y[i].append(0)
		y[i].append(1)

for j in range(0,28):#w初始化
	rand = random.uniform(-1,1)
	rand = round(rand,2)
	w.append(rand)
for i in range(0,4):#偏置初始化
	rand = random.uniform(-0.5,0.5)
	rand = round(rand,2)
	b1.append(rand)
for i in range(0,3):#偏置初始化
	rand = random.uniform(-0.5,0.5)
	rand = round(rand,2)
	b2.append(rand)
while(1):
	a = []
	O = []
	a_a = int(random.uniform(0,len(x)))
	for i in range(0,7):
		a.append(x[a_a][i])
		if x[a_a][i] == 1:
			if i == 4:
				O = [0.95,0.025,0.025]
			if i == 5:
				O = [0.025,0.95,0.025]
			if i == 6:
				O = [0.025,0.025,0.95]
	for i in range(100):
		#随机选取一个x内的元素作为训练集
		h = []
		out = []


		for i in range(0,4):
			h.append(putin(w,a,i,b1))
		sigmoid(h)
		for i in range(0,3):
			out.append(putout(h,w,i,b2))
		sigmoid(out)
		e = []
		e_total = 0
		for i in range(0,3):#得到偏差
			K = 1/3*((O[i] - out[i])**2)
			e.append(K)
			e_total = e_total + K


		for i in range(3):#修正隐含层到输出层的权值
			for j in range(4):
				w[16+(4*i)+j] = w[16+(4*i)+j] - 0.5 * back2w(O,out,h,i,j)

		for j in range(3):#修正隐含层到输出层的偏置值
			b2[j] = b2[j] - 0.5 * back2b(O,out,h,i,j)

		for i in range(4):
			for j in range(4):
				w[(4*i)+j] = w[(4*i)+j] - 0.2 *(back1w(O, out, w, j) * h[i] * a[i])
		for j in range(4):
			b1[j] = b1[j] - 0.2 *(back1w(O, out, w, j) * h[i])


	sum = 0#测试精确度
	for j in range(len(y)):
		b = []
		O = []
		bb = j
		for i in range(0, 7):
			b.append(y[bb][i])
			if y[bb][i] == 1:
				if i == 4:
					O = [0.95, 0.025, 0.025]
				if i == 5:
					O = [0.025, 0.95, 0.025]
				if i == 6:
					O = [0.025, 0.025, 0.95]
		h = []
		out = []
		for i in range(0,4):
			h.append(putin(w,b,i,b1))
		sigmoid(h)
		for i in range(0,3):
			out.append(putout(h,w,i,b2))
		sigmoid(out)
		sum = sum + acc(O,out)
	print(sum)
	if sum/len(y) >= 0.80:
		break

Guess you like

Origin blog.csdn.net/weixin_41171064/article/details/90670558