BP网络数字识别

我们使用sklearn库来进行训练,识别数字0~9。

1.导入包

import numpy as np
from sklearn.datasets import load_digits		#数据集
from sklearn.preprocessing import LabelBinarizer		#标签二值化
from sklearn.cross_validation import train_test_split		#切分数据 把数据分为测试数据和训练数据

2.定义训练函数

def sigmoid(x):
	return 1/(1+np.exp(-x))
	
def dsigmoid(x):
	return x*(1-x)

3.定义神经网络的类

在这里,自己定义一个类表示神经网络

class NeuralNetwork:

 初始化:将输入层作为初始化参数,如(64,100,10)为输入64个神经元,隐藏层100个,输出10个

	def __init__(self,layers):	
		#权值初始化,范围-1,1   输入层隐藏层+1代表偏置值
		self.V = np.random.random((layers[0]+1,layers[1]+1))*2-1
		self.W = np.random.random((layers[1]+1,layers[2]))*2-1

训练函数:X  为训练的数据 y标签 epochs迭代次数

	def train(self,X,y,lr=0.11,epochs=10000):
	#添加偏置操作
		temp = np.ones([X.shape[0],X.shape[1]+1])   	#定义一个临时矩阵 行数与X一样 列比X多一列 数据都为1
		temp[:,0:-1] = X    #将X矩阵赋值给temp的第一列到倒数第二列
		X = temp	#此时X矩阵多一列都为1的数据
	
		#循环训练	
		for n in range(epochs+1):        #层数+1 偏置值
			i = np.random.randint(X.shape[0])		#随机选取一个数据(一行)
			x = [X[i]]
			x = np.atleast_2d(x)		#将数据转为2维数据
			
			#隐藏层输出
			L1 = sigmoid(np.dot(x,self.V))
			#输出层的输出
			L2 = sigmoid(np.dot(L1,self.W))
			
			#误差信号
			L2_delta = (y[i]-L2)*dsigmoid(L2)
			L1_delta = L2_delta.dot(self.W.T)*sigmoid(L1)
			
			#权值的调整
			self.W += lr*L1.T.dot(L2_delta)
			self.V += lr*x.T.dot(L1_delta)
			
			#每训练1000次预测一次准确率
			if n%1000 == 0:
				predictions = []
				for j in range(X_test.shape[0]):		#X_test测试数据 把所有的数据都执行一遍 
					o = self.predict(X_test[j])
					predictions.append(np.argmax(o))	#获取预测结果
				accuracy = np.mean(np.equal(predictions,y_test))	#对比求平均值
				print('epoch:',n,'accuracy:',accuracy)

预测函数:

 

	def predict(self,x):
		#添加偏置
		temp = np.ones(x.shape[0]+1)
		temp[0:-1] = x
		x = temp
		x = np.atleast_2d(x)	#转化为2维数据		
		#隐藏层输出
		L1 = sigmoid(np.dot(x,self.V))
			#输出层的输出
		L2 = sigmoid(np.dot(L1,self.W))	
		return L2

到这里就完成了类的构建

4.载入数据 训练

#载入数据
digits	= load_digits()
X = digits.data#数据
y = digits.target#标签
#输入数据归一化变为(0,1)之间的数 便于进行权值调整和训练学习 详见sigmoid函数图像
X -=X.min()
X /= X.max()

nm = NeuralNetwork([64,100,10])	#创建网络  进入网络的类 进行权值初始化等

X_train,X_test,y_train,y_test = train_test_split(X,y)#分割3/4训练数据和1/4为测试数据,

labels_train = LabelBinarizer().fit_transform(y_train)	#标签二值化  0->100000000   3->0001000000	与输出层的10个神经元对应
labels_test = LabelBinarizer().fit_transform(y_test)	#标签二值化

print('start')

#开始训练 将数据传入类的训练函数
nm.train(X_train,labels_train,epochs = 20000)
print('end')

运行结果 可以看出 准确率在提高

BP网络数字识别_第1张图片

 

你可能感兴趣的:(深度学习)