三层神经网络识别手写体数字(自己制作训练集)

三层神经网络识别手写体数字(自己制作训练集)

整个部分分为训练集制作和运行网络两个部分

一、首先制作训练集
目录分布如下:分为data、test、手写数字数据集和两个脚本
在这里插入图片描述
步骤一: 自己手写几张数字,用手机拍照放在“手写数字数据集”,为了避免麻烦,每个图片对应的标签直接将照片命名为相应的数字,有重复的数字依次保存即可(只要第一个数字正确即可),例如数字“7”拍了很多张,保存成“7.jpg、7(1).jpg、7(2).jpg…”
如图所示:
在这里插入图片描述
步骤二:data里面放训练集,考虑到自己手机照的像素不一致,需要将照片全部改为28*28像素大小,运行“改变像素.py”,注意:手机照的图片放在“手写数字数据集”。
下面展示 改变像素.py

// 改变像素后存入到data文件夹下,原始手机图片放在“手写数字数据集”
import os
from PIL import Image

def image_processing():
    #  待处理图片路径下的所有文件名字
    all_file_names = os.listdir('手写数字数据集')
    for file_name in all_file_names:
        print(file_name)
        #  待处理图片路径
        img_path = Image.open(f'手写数字数据集\\{file_name}')
        #  resize图片大小,入口参数为一个tuple,新的图片的大小
        img_size = img_path.resize((28, 28))
        #  处理图片后存储路径,以及存储格式
        img_size.save(f'data\\{file_name}', 'JPEG')

if __name__ == '__main__':
    image_processing()

运行结束后data文件就出现制作好的训练集~
步骤三:测试集放入想要测试的图片,注意:像素也改成28*28,且命名方式和训练集一致,只需要把上述脚本其中两行做相应的改动即可,在运行一下,test就出现了制作好的测试集~

img_path = Image.open(f'手写数字数据集\\{file_name}')
img_size.save(f'data\\{file_name}', 'JPEG')

改为:

img_path = Image.open(f'XXXXX\\{file_name}')#XXXXX是用来测试的文件夹,存放没有拿来训练的原始手机照片
img_size.save(f'test\\{file_name}', 'JPEG')

步骤四:运行“神经网络(第三版).py”脚本即可出现结果:
下面展示 神经网络(第三版).py

import numpy
import scipy.special
import os
import re
import imageio

class neuraNetwork:
    #初始化神经网络
    #输入层节点、隐藏层节点、输出层节点数量
    def __init__(self,inputnodes,hiddennodes,outputnodes,learningrate):
        self.inodes = inputnodes #定义输入节点数
        self.hondes = hiddennodes#定义隐藏层节点数
        self.onodes = outputnodes#定义输出层节点数
        self.lr = learningrate#定义学习率
        self.wih = numpy.random.normal(0.0,pow(self.inodes,-0.5),(self.hondes,self.inodes))#定义输入层到隐藏层的权重矩阵
        self.who = numpy.random.normal(0.0,pow(self.hondes,-0.5),(self.onodes,self.hondes))#定义隐藏层到输出层的权重矩阵
        self.activation_function = lambda x: scipy.special.expit(x)
    #训练神经网络
    def train(self,inputs_list,targets_list):
        inputs = numpy.array(inputs_list,ndmin=2).T
        targets = numpy.array(targets_list,ndmin=2).T

        hidden_inputs = numpy.dot(self.wih,inputs)
        hidden_outputs = self.activation_function(hidden_inputs)#隐藏层输出

        final_inputs = numpy.dot(self.who,hidden_outputs)
        final_outputs = self.activation_function(final_inputs)#输出层输出

        #计算误差
        output_errors = targets - final_outputs #计算目标标记值-计算的输出值的误差
        hidden_errors = numpy.dot(self.who.T,output_errors) #根据权重分割误差
        #更新两层权重
        self.who += self.lr * numpy.dot((output_errors * final_outputs) * (1.0 - final_outputs),numpy.transpose(hidden_outputs))
        self.wih += self.lr * numpy.dot((hidden_errors * hidden_outputs) * (1.0 - hidden_outputs),numpy.transpose(inputs))
        #梯度下降法更新权重
    #预测
    def query(self, inputs_list):
        inputs = numpy.array(inputs_list, ndmin=2).T
        hidden_inputs = numpy.dot(self.wih, inputs)
        hidden_outputs = self.activation_function(hidden_inputs)
        final_inputs = numpy.dot(self.who, hidden_outputs)
        final_outputs = self.activation_function(final_inputs)
        return final_outputs

#*****************************************************************************************************************
#训练part
def train_first():
    inputs = []
    global epochs
    all_file_names = os.listdir('data')
    while epochs:
        for file_name in all_file_names:
            img_array = imageio.imread(f'data\\{file_name}', as_gray=True)
            image_data = 255.0 - img_array.reshape(784)
            # print(image_data)
            image_data = (image_data / 255.0 * 0.99) + 0.01
            inputs.append(image_data)
            targets = numpy.zeros(outputs_nodes) + 0.01
            num = re.findall("\d+",file_name)
            num_ = num[0]
            targets[int(num_)] = 0.99
            n_train.train(image_data, targets)
        print(f'训练了{n-epochs+1}次')
        epochs -= 1
    print('训练完成!')
#*****************************************************************************************************************
#测试part
def perdict():
    files = os.listdir('test')
    add = []
    for file in files:
        img_array = imageio.imread(f'test\\{file}', as_gray=True)
        image_data = 255.0-img_array.reshape(784)
        image_data = (image_data/255.0*0.99)+0.01
        outputs = n_train.query(image_data)
        num = re.findall("\d+", file)#图片名字
        num_ = int(num[0])
        label = numpy.argmax(outputs)  #网络的预测结果值
        print(num_,label,'真实值:预测值')
        if num_ == label:
            add.append(1)
        else:
            add.append(0)
        scorecard_array = numpy.asanyarray(add)
    print('预测完成!')
    print("准确率==", scorecard_array.sum() / scorecard_array.size)
#***********************************************************************************************************
if __name__ == '__main__':
    input_nodes = 784 #输入节点数(像素:28*28=784)
    hidden_nodes = 100 #隐藏层节点数
    outputs_nodes = 10 #输出节点数(预测0~9)
    learning_rate = 0.1 #学习率
    epochs = n = 300 #训练样本循环次数
    n_train = neuraNetwork(input_nodes,hidden_nodes,outputs_nodes,learning_rate)
    train_first()
    perdict()

结果:


版权声明:本文为weixin_44715077原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。