神经网络——识别数字图片

神经网络——识别数字图片

神经网络——识别数字图片

文章目录

  • 神经网络——识别数字图片
  • 前言
  • 一、任务概述
  • 二、设计思路
    • 1.引入库
    • 2.读入数据
    • 3.编写功能函数
    • 4.设置神经网络基本参数和变量
    • 5.训练
    • 6.测试
    • 7.结果
  • 总结


前言

本人经过实验室对神经网络的学习,需完成通过神经网络实现数字图片识别的demo,现将思路与代码总结在博客中。


提示:以下思路及代码仅供参考

一、任务概述

我们使用MINST数据集
第一部分:60000张数字图片用于训练模型的数据,大小均为28 * 28的灰度图像。
第二部分:10000张数字图片用于测试模型效果,大小也均为28 * 28的灰度图像。
设计并编写反向传播神经网络模型,通过60000幅图像对模型进行训练,并利用模型对10000幅测试用例进行分析,最终显示正确率。

二、设计思路

1.引入库

代码如下:

import tensorflow as tf
import numpy as np

2.读入数据

代码如下(示例):

mint = tf.keras.datasets.mnist;
(x_train, y_train), (x_test, y_test) = mint.load_data("D:\\ChromeCoreDownloads\\anaconda\\Anaconda3-2020.02_64\\Lib\\site-packages\\tensorflow\\keras\\datasets\\mnist\\mnist.npz")
#要将训练集和测试机都转成float32的类型,否则后续运算中会报错,类型不匹配
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
#将训练集和测试集归一化
x_train /= 256
x_test /= 256

此处我是直接导入的已经下载在本地的MNIST数据集,也可不添加load_data()里的路径参数,它会自动从网上下载,但每次运行均会下载一次,因此保存至本地会方便一些。

3.编写功能函数

#激活函数
def get_act(inx):
    return 1.0 / (1 + np.exp(-inx))
#求导函数
def sigmoid_derivative(x):
    new_x = []
    for i in range(len(x)):
        new_x.append(get_act(x[i]) * (1 - get_act(x[i])))
    new_x = np.array(new_x)
    new_x = np.reshape(new_x, (x.shape[0], x.shape[1]))
    return new_x

4.设置神经网络基本参数和变量

#设置网络基本参数
    sampleNum =len(x_train)    #样本个数
    outputNum = 10   #0-9的数字,因此共10个神经元
    inputNum = 784  #一张照片28*28的规格,因此输入层有784个神经元
    hiddenNum = 45  #隐藏层神经元个数

    #初始化输入层与隐藏层之间的权值矩阵
    w = 1 * np.random.random((hiddenNum, inputNum))
    w /= sum(w)
    #初始化隐藏层与输出层之间的权值矩阵
    v = 1 * np.random.random((outputNum, hiddenNum))
    v /= sum(v)
	
    inputLearnRate = 1    #输入层学习率
    hiddenLearnRate = 1   #隐藏层学习率

    hiddenOffset = np.zeros(hiddenNum)  #隐藏层的偏置向量
    hiddenOffset = np.reshape(hiddenOffset, (hiddenNum, 1))

    outOffset = np.zeros(outputNum) #输出层的偏置向量
    outOffset = np.reshape(outOffset, (outputNum, 1))

代码中w /= sum(w)v /= sum(v)即是将矩阵中每个元素都除以矩阵每个元素相加的总和,使操作后的元素总和为1,目的是防止元素过大化影响结果。

5.训练

    #训练
    print("Start training...")
    for count in range(len(x_train)):
        x_t = x_train[count]
        x_t = np.reshape(x_t, (784, 1))
        x_t += 0.001
        # print(x_t)
        # print()
        expectLables = np.zeros(outputNum)  #预期结果
        expectLables[y_train[count]] = 1
        expectLables = np.reshape(expectLables, (10, 1))

        hiddenValue = np.dot(w, x_t) + hiddenOffset  #隐藏层的输入

        hiddenact = get_act(hiddenValue)    #隐藏层的输出

        outputValue = np.dot(v, hiddenact) + outOffset  #输出层的输入
        outputact = get_act(outputValue)    #输出层的输出

        error = (expectLables - outputact) * outputact * (1.0 - outputact)

        error_L = np.dot(v.T, error) * hiddenact * (1.0 - hiddenact)

        outOffset = outOffset + error    #更新输出层的偏置向量
        hiddenOffset = hiddenOffset + error_L    #更新隐藏层的偏置向量
        v = v + inputLearnRate * np.dot(error, np.transpose(hiddenact))
        w = w + hiddenLearnRate * np.dot(error_L, np.transpose(x_t))

6.测试

    print("start testing")
    right = 0
    rightCount = np.zeros(10)
    for count in range(len(x_test)):
        x_t = x_test[count]
        x_t = np.reshape(x_t, (784, 1))
        hiddenValue = np.dot(w, x_t) + hiddenOffset  # 隐藏层的输入
        hiddenact = get_act(hiddenValue)  # 隐藏层的输出
        outputValue = np.dot(v, hiddenact) + outOffset  # 输出层的输入
        #print(outputValue)
        outputact = get_act(outputValue)  # 输出层的输出
        #print(outputact)
        # print(y_test[count])
        max_num = outputact[0]
        index = 0
        for i in range(1, len(outputact)):
            if outputact[i] > max_num:
                max_num = outputact[i]
                index = i
        if(index == y_test[count]):
            rightCount[y_test[count]] += 1
    rightSum = rightCount.sum()
    print("The number of right result: {0}".format(rightSum))
    rate = rightSum / len(x_test)
    print("正确率:",end=' ')
    print(rate)

7.结果

运行结果如下图
神经网络——识别数字图片_第1张图片


总结

本次编写demo的过程中遇到了不少问题,例如:
1.为防止权值过大需要对其进行一定的处理,使各个元素之和为1。
2.权值修正时使用加号还是用减号都需要好好的推导一遍(你越想要某个输出越大那么它对应的权值就应该越大,因此权值的修正应该是预期的增大,其它的减小)。
3.为了使矩阵通过激活函数激活可利用循环对每个元素进行计算,但numpy提供了exp()函数可对整个矩阵进行操作。
4.(临时写的比较仓促,后续想到了再补充文章)

你可能感兴趣的:(实验室,神经网络,python,机器学习)