神经网络学习之----进军多层-BP神经网络-数字识别(代码实现)
思路:
使用sklearn中的数字数据集,主要有0,1,2,3,4,5,6,7,8,9。我们需要编写一个BP网络模型对数字进行识别。
sklearn数据集:
from sklearn import datasets from matplotlib import pyplot as plt #获取数据集 digits = datasets.load_digits() #可视化 for i in range(1, 11): plt.subplot(2, 5, i) #划分成2行5列 plt.imshow(digits.data[i - 1].reshape([8, 8]), cmap=plt.cm.gray_r) plt.text(3, 10, str(digits.target[i - 1])) #在图片的任意位置添加文本 plt.xticks([]) #认为设置坐标轴显示的刻度值 plt.yticks([]) plt.show()
BP网络-数字识别代码实现
import numpy as np from sklearn.datasets import load_digits from sklearn.preprocessing import LabelBinarizer from sklearn.cross_validation import train_test_split def sigmoid(x): return 1/(1+np.exp(-x)) def dsigmoid(x): return x*(1-x) class NeuralNetwork: def __init__(self,layers):#(64,100,10) #权值的初始化,范围-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 def train(self,X,y,lr=0.11,epochs=10000): #添加偏置 temp = np.ones([X.shape[0],X.shape[1]+1]) temp[:,0:-1] = X X = temp for n in range(epochs+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)*dsigmoid(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]): 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 digits = load_digits()#载入数据 X = digits.data#数据 y = digits.target#标签 #输入数据归一化 X -= X.min() X /= X.max() nm = NeuralNetwork([64,100,10])#创建网络 X_train,X_test,y_train,y_test = train_test_split(X,y) #分割数据1/4为测试数据,3/4为训练数据 labels_train = LabelBinarizer().fit_transform(y_train)#标签二值化 0,8,6 0->1000000000 3->0001000000 labels_test = LabelBinarizer().fit_transform(y_test)#标签二值化 print('start') nm.train(X_train,labels_train,epochs=20000) print('end') # In[ ]: