bp手写数字识别

bp神经网络实现手写数字识别,数据集:sklearn自带的digits.data,由1797个8x8像素矩阵组成,digits.target里为其标签,即0-9

BP网络训练参数

训练次数20000
神经网络层数64-100-10
激活函数sigmoid
输入数据(个数,维度)1,8x8
输出数据(个数,维度)1,8x8
训练集(个数,维度)1348,8x8
测试集(个数,维度)449,8x8
整体步骤如下:

1.加载手写数字数据集,分别将灰度信息和标签赋值给变量X和y。

2.定义了一个有64个输入节点、100个隐层节点和10个输出节点的神经网络,即V为64100的矩阵,W为10010的矩阵。

3.将原始数据集切分为训练集和测试集,然后对训练集的标签进行二值化。

4.定义了sigmoid激活函数及其导数函数dsigmoid。

5.定义了函数train(),通过不断更新权值(W和V),使用BP算法进行模型训练,并每训练1000次预测一次准确率。

6.定义了函数predict(),用于对测试集进行预测。

7.定义了函数show_predict(),随机选择一个测试数据,对其进行预测并展示这张图片。

代码整体过程比较简单,主要难点在于理解BP算法的原理和公式。其中,sigmoid函数作为常用的激活函数,主要用于将线性变换的结果压缩到0~1之间,形成非线性的特征表示,使得神经网络可以拟合更为复杂的函数关系。而BP算法则是通过计算误差信号和梯度信息,对权值进行不断更新和调整,从而提高模型的准确率。

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.model_selection import train_test_split
import matplotlib
import matplotlib.pyplot as plt

digits = 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->1000000000
# 3->0010000000
# 9->0000000001
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 L2


def show_predict(test_index):
    result = predict(X_test[test_index])
    print("预测值:", np.argmax(result), "实际值:", y_test[test_index])
    plt.imshow(X_test[test_index].reshape(8, 8))
    plt.show()
train(X_train, label_train, 20000)
steps: 0 accuracy: 0.19111111111111112
steps: 1000 accuracy: 0.5355555555555556
steps: 2000 accuracy: 0.6911111111111111
steps: 3000 accuracy: 0.7244444444444444
steps: 4000 accuracy: 0.7933333333333333
steps: 5000 accuracy: 0.8288888888888889
steps: 6000 accuracy: 0.9044444444444445
steps: 7000 accuracy: 0.9177777777777778
steps: 8000 accuracy: 0.8977777777777778
steps: 9000 accuracy: 0.9377777777777778
steps: 10000 accuracy: 0.94
steps: 11000 accuracy: 0.9555555555555556
steps: 12000 accuracy: 0.9355555555555556
steps: 13000 accuracy: 0.9577777777777777
steps: 14000 accuracy: 0.9622222222222222
steps: 15000 accuracy: 0.9577777777777777
steps: 16000 accuracy: 0.96
steps: 17000 accuracy: 0.9644444444444444
steps: 18000 accuracy: 0.9355555555555556
steps: 19000 accuracy: 0.9466666666666667
print(X.shape)#%digits.data是8x8的矩阵,共有1797个,即维度8x8
print(y.shape)
(1797, 64)
(1797,)
some_digit = X_test[3]
print(some_digit)#输出测试的图片8x8矩阵
print(y_test[3])#输出测试图片的标签,即实际值
show_predict(3)#调用预测绘图函数
[ 0.  0.  0.  0. 14. 13.  1.  0.  0.  0.  0.  5. 16. 16.  2.  0.  0.  0.
  0. 14. 16. 12.  0.  0.  0.  1. 10. 16. 16. 12.  0.  0.  0.  3. 12. 14.
 16.  9.  0.  0.  0.  0.  0.  5. 16. 15.  0.  0.  0.  0.  0.  4. 16. 14.
  0.  0.  0.  0.  0.  1. 13. 16.  1.  0.]
1
预测值: 1 实际值: 1

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值