我们使用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')
运行结果 可以看出 准确率在提高