BP神经网络实现手写数字识别 完整代码在最后
1.导入包
import numpy as np
from sklearn.datasets import load_digits
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report,confusion_matrix
import matplotlib.pyplot as plt
【深度学习|BP神经网络实现手写数字识别】像素值可以从digits.data.shape得到,这里输出结果表示有1797张图片,每张图片是64像素的,故有64个输入。标签值存在digits.target中取值是0~9。
文章图片
2.导入数据
digits = load_digits()
# 数据 图片的灰度信息存在digits.data中
X = digits.data
# 标签
y = digits.target
3.定义神经网络
64-100-10,即输入层64个神经元,隐层100个,输出层10个,关于输入层为什么没有加偏置 x 0 = 1 x_0 = 1 x0?=1,个人理解是在每张图片中加一个数据对训练结果影响不大,而且对图片加一个像素点也不是很方便?
# 定义神经网络64-100-10,64像素即64通道输入,隐藏层稍多于输入层,输出层为0-9,所以是10个
# 输入层到隐藏层v,隐藏层到输出层w
V = np.random.random((64,100)) * 2 - 1
W = np.random.random((100,10)) * 2 - 1
4.数据切分
把digits中的一部分数据用来做测试,一部分用来做训练
用到函数 train_test_split()
# 数据切分 train_test_split(X,y)可以把输入数据和标签数据切分为训练集和测试集
# default: 1/4测试集,3/4训练集
X_train,X_test,y_train,y_test = train_test_split(X,y)
5.标签二值化(one hot独热编码)
神经网络输出只有0、1,无法直接表示0,1,2,3,4…因此分类问题都要二值化
0→100000000
3→001000000
9→000000001
# 标签二值化
# 0->100000000
# 3->001000000
# 9->000000001
label_train = LabelBinarizer().fit_transform(y_train)
6.定义激活函数
用sidmoid函数做激活函数
# 激活函数
def sigmoid(x):
return 1/(1+np.exp(-x))
def dsigmoid(x):
s = 1/(1+np.exp(-x))
return s*(1-s)
7.训练模型
给训练函数一个训练集,从训练集中随机抽取一个数据作为本次训练的输入x,然后根据BP算法更新权值。
每训练1000次会计算一次准确率,计算方法是:把测试集作为输入,调用预测函数,返回的是当前训练次数下的神经元输出 L 2 L_2 L2?, L 2 L_2 L2?是10维的向量,值都在0到1之间,把最大的值认为是1,并筛选出来它的位置和测试集的标签值做比较,求个均值得到accuracy。
x = np.atleast_2d(x) 这里其实是把x转化为一维矩阵,因为x本身是一个list,不能进行矩阵运算,需要变成一维矩阵才能做矩阵乘法
# 训练模型
def train(X,y,Steps = 10000,lr = 0.12):
global W,V
for n in range(Steps):
# 随机选取一个数据
i = np.random.randint(X.shape[0])
x = X[i]
# 把数据变为2维数据,一维数据不能矩阵乘法
# ?????????
x = np.atleast_2d(x)# BP算法公式
L1 = sigmoid(np.dot(x,V))
L2 = sigmoid(np.dot(L1,W))# 学习信号
L2_delta = (y[i]-L2)*dsigmoid(np.dot(L1,W))
L1_delta = np.dot(L2_delta,W.T)*dsigmoid(np.dot(x,V))# 更新权值
W += lr*np.dot(L1.T,L2_delta)
V += lr*np.dot(x.T,L1_delta)#每训练1000次预测一次准确率
if n%1000 == 0:
output = predict(X_test)
# predictions:最大值所在位置(0-9)->预测的标签值
predictions = np.argmax(output,axis = 1)
acc = np.mean(np.equal(predictions,y_test))
print("steps:",n,"accuracy:",acc)
def predict(x):
L1 = sigmoid(np.dot(x,V))
L2 = sigmoid(np.dot(L1,W))
return L2
8.训练20000次
train(X_train,label_train,20000)
完整代码及结果
import numpy as np
from sklearn.datasets import load_digits
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report,confusion_matrix
import matplotlib.pyplot as pltdigits = load_digits()
# 数据 图片的灰度信息存在digits.data中
X = digits.data
# 标签
y = digits.target# 定义神经网络64-100-10,64像素即64通道输入,隐藏层稍多于输入层,输出层为0-9,所以是10个
# 输入层到隐藏层v,隐藏层到输出层w
V = np.random.random((64,100)) * 2 - 1
W = np.random.random((100,10)) * 2 - 1# 数据切分 train_test_split(X,y)可以把输入数据和标签数据切分为训练集和测试集
# default: 1/4测试集,3/4训练集
X_train,X_test,y_train,y_test = train_test_split(X,y)# 标签二值化
# 0->100000000
# 3->001000000
# 9->000000001
label_train = LabelBinarizer().fit_transform(y_train)# 激活函数
def sigmoid(x):
return 1/(1+np.exp(-x))
def dsigmoid(x):
s = 1/(1+np.exp(-x))
return s*(1-s)# 训练模型
def train(X,y,Steps = 10000,lr = 0.12):
global W,V
for n in range(Steps):
# 随机选取一个数据
i = np.random.randint(X.shape[0])
x = X[i]
# 把数据变为2维数据,一维数据不能矩阵乘法
# ?????????
x = np.atleast_2d(x)# BP算法公式
L1 = sigmoid(np.dot(x,V))
L2 = sigmoid(np.dot(L1,W))# 学习信号
L2_delta = (y[i]-L2)*dsigmoid(np.dot(L1,W))
L1_delta = np.dot(L2_delta,W.T)*dsigmoid(np.dot(x,V))# 更新权值
W += lr*np.dot(L1.T,L2_delta)
V += lr*np.dot(x.T,L1_delta)#每训练1000次预测一次准确率
if n%1000 == 0:
output = predict(X_test)
# predictions:最大值所在位置(0-9)->预测的标签值
predictions = np.argmax(output,axis = 1)
acc = np.mean(np.equal(predictions,y_test))
print("steps:",n,"accuracy:",acc)
def predict(x):
L1 = sigmoid(np.dot(x,V))
L2 = sigmoid(np.dot(L1,W))
return L2train(X_train,label_train,20000)
结果
steps: 0 accuracy: 0.06888888888888889
steps: 1000 accuracy: 0.6066666666666667
steps: 2000 accuracy: 0.7733333333333333
steps: 3000 accuracy: 0.8022222222222222
steps: 4000 accuracy: 0.8222222222222222
steps: 5000 accuracy: 0.8488888888888889
steps: 6000 accuracy: 0.84
steps: 7000 accuracy: 0.86
steps: 8000 accuracy: 0.8422222222222222
steps: 9000 accuracy: 0.86
steps: 10000 accuracy: 0.8666666666666667
steps: 11000 accuracy: 0.8533333333333334
steps: 12000 accuracy: 0.8666666666666667
steps: 13000 accuracy: 0.8644444444444445
steps: 14000 accuracy: 0.8644444444444445
steps: 15000 accuracy: 0.8688888888888889
steps: 16000 accuracy: 0.9044444444444445
steps: 17000 accuracy: 0.94
steps: 18000 accuracy: 0.9444444444444444
steps: 19000 accuracy: 0.94
推荐阅读
- 基于ARM主板的人工智能学习|树莓派镜像烧录教程(史上最全,最完整的树莓派学习专栏)
- GCN相关应用|图卷积神经网络(GCN)相关应用
- 数据分析与机器学习|大厂面试机器学习算法(5)推荐系统算法
- 机器学习|吴恩达机器学习作业二(利用逻辑回归模型预测一个学生是否被学校录取 ,二分类问题(python实现))
- 深度学习|目标检测入门常见问题(深度学习 / 图像分类)
- 目标检测|目标检测入坑指南3(VGGNet神经网络)
- python|【机器学习】一文详解异常检测算法(KNN)
- 网络|MobileViT: 一种更小,更快,高精度的轻量级Transformer端侧网络架构(附代码实现)...
- transformer|论文阅读|MobileViT