CV学习笔记:BP网络实现手写数字识别

CV学习笔记:BP网络实现手写数字识别

BP算法的基本思想是,学习过程由信号的正向传播与误差的反向传播两个过程组成。正向传播时,输入样本从输入层传入,经各隐藏层逐层处理后,传向输出层。若输出层的实际输出与期望的输出不符,则转入误差的反向传播阶段。误差反传是将输出误差以某种形式通过隐藏层向输入层逐层反传,并将误差分摊给各层的所有单元,从而获得各层单元的误差信号,此误差信号即作为修正各单元权值的依据。这种信号正向传播与误差反向传播的各层权值调整过程,是周而复始地进行的。权值不断调整的过程,也就是网络的学习训练过程。此过程一直进行到网络输出的误差减少到可接受的程度,或进行到预先设定的学习次数为止。

 先把BP算法的公式贴出来,后面代码中会用到。

在pycharm新建BP项目——新建Minist.py文件

1.载入数据显示手写数字图片

import numpy as np
from sklearn.datasets import load_digits #从sklearn数据集中加载手写数字图片
from sklearn.preprocessing import LabelBinarizer #对带有标签图片进行处理
from sklearn.model_selection import train_test_split #分割训练集和测试集
import  matplotlib.pyplot as plt #画图工具

#载入数据(手写数字图片)
digits=load_digits()
print(digits.images.shape)#打印数据集的形状


#显示手写数字图片
plt.imshow(digits.images[0],cmap='gray')
plt.show()
plt.imshow(digits.images[23],cmap='gray')
plt.show()

运行结果:

可以看到数据集中有1797个样本,每张手写数字图片大小为8*8,64个像素;并且显示了第0个和第23个样本的标签——0、3。

2.查看样本数据

#读入样本集的数据
X=digits.data
#读入样本集的标签
y=digits.target
print(X.shape)
print(y.shape)
print(X[:3])#打印样本集中前3个样本的数据0-2
print(y[:4])#打印样本集中前4个样本的标签0-3

运行结果:

可以看到,样本有多少标签就有多少,前3个样本中的64个像素值都被打印出来了以及前4个样本的标签值:0、1、2、3

3.建立BP算法的神经网络训练模型

#定义一个神经网络,网络结构——输入层:64个神经元;隐藏层:100个;输出层:10个神经元(10个输出值)
#定义输入层到隐藏层的权值矩阵
V=np.random.random((64,100))*2-1#64*100;random随机生成数字0-1;*2-1:从-1~1之间
#定义隐藏层到输出层的权值矩阵
W=np.random.random((100,10))*2-1#size:100*10

#数据切分
#一般将样本数据划分成:1/4为测试集(用来测试模型效果),3/4为训练集
X_train,X_test,y_train,y_test=train_test_split(X,y)

#标签二值化 (这步操作是把某个具体标签值转换成其在所有标签中的位置,方便输出)
#0—>1000000000
#3->0010000000
#9->0000000001
labels_train=LabelBinarizer().fit_transform(y_train)#把原本的标签训练集二值化
print(y_train[:5])
print(labels_train[:5])

#定义激活函数
def sigmod(x):
    return 1/(1+np.exp(-x))
#定义激活函数的导数
def dsigmod(x):
    return x*(1-x)
#定义训练模型
def train(X,y,steps,lr=0.11):#训练集、标签集、训练次数、学习率
    global V,W #调用全局变量
    for n in range(steps+1):
        #随机选取一个样本中的数据
        i=np.random.randint(X.shape[0])#取第一维数据,即训练样本中的第一个
        x=X[i]#取样本中的具体数值(64个)
        x=np.atleast_2d(x)#把一维数据表转成2维,方便与权值矩阵做乘法

        #BP算法公式
        #计算隐藏层的输出
        L1=sigmod(np.dot(x,V))
        #计算输出层的输出
        L2=sigmod(np.dot(L1,W))

        #计算L2_delta、 L1_delta(通多这两个值来更新权重)
        L2_delta=(y[i]-L2)*dsigmod(L2)#对应公式:输出层学习信号
        L1_delta=L2_delta.dot(W.T)*dsigmod(L1)#对应公式:第l层学习信号

        #更新权值
        W+=lr*L1.T.dot(L2_delta)
        V+=lr*x.T.dot(L1_delta)

        #每训练1000次可以预测一次准确率
        if n%1000==0:
            output=predict(X_test)#把测试集传入测试模型
            predictions=np.argmax(output,axis=1)#获取最大值的位置,实际上得到标签值

            # 对比网络预测值和真实的标签值是否相等,相等为TURE(1),不等为false(0),求平均,即为准确率
            acc=np.mean(np.equal(predictions,y_test))
            print("steps:",n,"accuracy:",acc)
#该函数输入测试集,输出标签值
def predict(x):
    # 计算隐藏层的输出
    L1 = sigmod(np.dot(x, V))
    # 计算输出层的输出
    L2 = sigmod(np.dot(L1, W))
    return L2

train(X_train,labels_train,20000)#调用BP算法训练模型

运算结果:

[4 6 0 2 8]
[[0 0 0 0 1 0 0 0 0 0]
 [0 0 0 0 0 0 1 0 0 0]
 [1 0 0 0 0 0 0 0 0 0]
 [0 0 1 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 1 0]]
steps: 0 accuracy: 0.15333333333333332
steps: 1000 accuracy: 0.7666666666666667
steps: 2000 accuracy: 0.8511111111111112
steps: 3000 accuracy: 0.8933333333333333
steps: 4000 accuracy: 0.9066666666666666
steps: 5000 accuracy: 0.9244444444444444
steps: 6000 accuracy: 0.9311111111111111
steps: 7000 accuracy: 0.9422222222222222
steps: 8000 accuracy: 0.9311111111111111
steps: 9000 accuracy: 0.9555555555555556
steps: 10000 accuracy: 0.9533333333333334
steps: 11000 accuracy: 0.9466666666666667
steps: 12000 accuracy: 0.9488888888888889
steps: 13000 accuracy: 0.9555555555555556
steps: 14000 accuracy: 0.96
steps: 15000 accuracy: 0.9511111111111111
steps: 16000 accuracy: 0.9555555555555556
steps: 17000 accuracy: 0.9755555555555555
steps: 18000 accuracy: 0.9777777777777777
steps: 19000 accuracy: 0.9733333333333334
steps: 20000 accuracy: 0.9711111111111111

Process finished with exit code 0

可以看到通过BP网络训练20000次后,手写数字识别准确率越来越高,说明这个训练模型效果好,能达到预期的目的。

参考:https://mooc.study.163.com/learn/2001390003?tid=2403020002&_trace_c_p_k2_=fd9cda6a4f4b4ac6a7cebaf9a79acf3d#/learn/content?type=detail&id=2403358542

发布了21 篇原创文章 · 获赞 21 · 访问量 2670

猜你喜欢

转载自blog.csdn.net/laozaoxiaowanzi/article/details/105225425
今日推荐