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

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

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

一、首先制作训练集
目录分布如下:分为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()

结果:

  • 2
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
三层bp神经网络是一种常见的人工神经网络模型,由输入层、隐藏层和输出层组成。在训练手写数字识别任务中,我们可以使用这个神经网络模型。 首先,我们需要准备一组已经标注好的手写数字图像作为训练数据集。每个图像都有相应的标签,代表图像上的数字。 然后,我们需要对输入层、隐藏层和输出层分别初始化相应数量的神经元。输入层的神经元数量取决于图像的大小,隐藏层和输出层的神经元数量可根据具体任务进行调整。 接下来,我们需要随机生成并初始化连接输入层和隐藏层之间、隐藏层和输出层之间的权重。这些权重将在训练过程中不断调整以达到更准确的识别结果。 然后,我们可以开始训练过程。首先将一个训练样本输入到输入层中,经过隐藏层的处理后得到输出结果。然后将输出结果与该样本的标签进行比较,计算出误差值。 接下来,我们通过反向传播算法来调整权重,使得误差值尽量减小。反向传播算法将误差从输出层向隐藏层一层层传递,并根据误差值调整相应的权重。这一过程将在每个训练样本上重复进行,直到达到预设的训练次数或者误差值满足要求。 最后,我们将训练好的神经网络模型应用于未知的手写数字图像上,将输入样本输入到训练好的网络中,经过前向传播计算后得到输出结果。根据输出结果可以判断图像上的数字是多少。 通过这种方式,使用三层bp神经网络固定权重训练识别手写数字,可以达到较高的识别准确率。当然,为了提高训练效果,我们可以使用更多的隐藏层、增大神经元数量、增加训练样本数量等方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值