基于神经网络手写数字识别的简略设计

基于神经网络手写数字识别的简略设计

引用了小哥的代码,我自己照着看了一遍后就写了一下,感觉对于初学者还是比较有益的,感谢https://blog.csdn.net/weixin_46824122/article/details/105417564的贡献!!下面时我自己进行整理了一下后的所写内容,希望对大家有益啦~
在这里插入图片描述
1. 代码块

import tensorflow as tf
import matplotlib.pyplot as plt
from tensorflow.examples.tutorials.mnist import input_data

mg = tf.Graph()
with mg.as_default():#打开tensorflow中默认的图,在图上进行以下的操作
    #手写数字图片数据的读取
    #1 准备数据
    mnist = input_data.read_data_sets("./MNIST_data", one_hot=True)#读取图片数据
    #x y_true 主要目的是占位,为以后的运行会话时,将数据传入
    x = tf.placeholder(tf.float32, [None, 784])
    y_true = tf.placeholder(tf.int32, [None, 10])

    input_X = tf.reshape(x, [-1, 28, 28, 1])#因为输入的图片是[1,784]格式,需要转换为[28,28]的格式的图片(灰度图,二维图)
    #2 卷积神经网络
    #卷积层——卷积、激活、池化
    #刚开始是随机定义卷积核(权重)和偏置的值
    conv1_weights = tf.Variable(tf.random_normal([3, 3, 1, 32]))#卷积核大小为3*3*1 32个
    conv1_bias = tf.Variable(tf.random_normal([32]))
    conv1_x = tf.nn.conv2d(input_X, conv1_weights, [1,1,1,1],padding="SAME")+conv1_bias#参数为输入的图片数据、卷积核、步长、padding值
    #padding为SAME时,输出大小为输入大小/步长,取上整
    #padding为VALID时,输出大小为(输入大小-卷积核大小+1)/ 步长
    relu1_x = tf.nn.relu(conv1_x) #激活函数,relu、tanh等
    #池化层参数为输入数据、框大小、步长
    pool1_x = tf.nn.max_pool(relu1_x,ksize=[1,2,2,1],strides=[1,2,2,1],padding="SAME")

    #第一层卷积层输出结果 28/1 = 28  28/2=14   → 14*14*32

    conv2_weights = tf.Variable(tf.random_normal([3,3,32,64]))
    conv2_bias = tf.Variable(tf.random_normal([64]))
    conv2_x = tf.nn.conv2d(pool1_x,conv2_weights,[1,1,1,1],padding="SAME")+conv2_bias
    relu2_x = tf.nn.relu(conv2_x)
    pool2_x = tf.nn.max_pool(relu2_x,ksize=[1,2,2,1],strides=[1,2,2,1],padding="SAME")

    #第二层卷积层输出结果 14/1 = 14 14/2=7   → 7*7*64

    #3 全连接层
    #[None,7*7*64] * [7*7*64,10] = [None,10]
    x_fc = tf.reshape(pool2_x,shape=[-1,7*7*64])
    weights_fc = tf.Variable(tf.random_normal([7*7*64,10]))
    bias_fc = tf.Variable(tf.random_normal([10]))
    y_predict = tf.matmul(x_fc,weights_fc)+bias_fc#得到的最后的结果


    #4 softmax回归函数以及交叉熵损失计算
    loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=y_predict,labels=y_true))
    #利用tensorflow中的损失优化进行训练,0.01为学习率,通过让损失值loss最小化,回归得到最适合的卷积核和偏置
    #5 梯度下降法、Adam、Adagrad等方法
    train_op = tf.train.AdamOptimizer(0.01).minimize(loss)
    #得出每次训练的结果与真实数据y_true是否相同,判断相同个数
    equal_list = tf.equal(tf.argmax(y_true,1),tf.argmax(y_predict,1))
    #算出准确率即结果的平均值
    accuracy = tf.reduce_mean(tf.cast(equal_list,tf.float32))
    #初始化所有的变量
    init_op = tf.global_variables_initializer()
    #保存训练模型
    saver = tf.train.Saver()
#开启会话去训练
with tf.Session(graph=mg) as sess:
    sess.run(init_op)#进行初始化操作
    #记录准确率
    acc = []
    #循环训练100次
    for i in range(100):
        #每次训练从所有数据中拿出500个作为一次,然后下次训练就拿出后面500个,如果到最后了还没结束,就重新打乱所有的键值再重新取值
        mnist_x,mnist_y = mnist.train.next_batch(500)
        mnist_x *=255 #由于数据是经过归一化的,像素值为0-1 所以需要✖255
        #开始运行训练
        #将数据“喂”进去,train_op即损失优化的最后结果保存在_里面
        _,ac = sess.run([train_op,accuracy],feed_dict={x:mnist_x,y_true:mnist_y})
        print("训练第%d步的准确率为:%f,损失为:%f"%(i+1,
                                       #输出的准确率、损失值都需要重新sess.run一下,不然输出不了
                                        sess.run(accuracy,feed_dict={x:mnist_x,y_true:mnist_y}),
                                        sess.run(loss, feed_dict={x: mnist_x, y_true: mnist_y})
                                        ))

        acc.append(ac) #将ac加入到acc数组中
        plt.plot(acc) #用图形表示变化
        plt.show()
        #将模型保存起来
        saver.save(sess,r"model_ckpt\second.ckpt")









2 整理的相关一些知识点
👉 Padding=”SAME” Padding=”VALID”
从程序中可以看出我的输入是553,过滤器是333,padding设置的值是SAME,所以我一开始预想的是输出557(有7个过滤器),可是最后程序运行的结果是337,和我预想的不一致,原来tensorflow官网定义的padding如下:

padding = “SAME”输入和输出大小关系如下:

输出大小等于输入大小除以步长向上取整,s是步长大小;

padding = “VALID”输入和输出大小关系如下:

输出大小等于输入大小减去滤波器大小加上1,最后再除以步长(f为滤波器的大小,s是步长大小)。

因此还是上述的那个例子,我的输入是553,滤波器是333,padding= “SAME”,步长s = 2,因此根据公式我的输出是(5/2=2.5),2.5向上取整是3,因此符合上述程序输出的结果,如果我将padding的值改成“VALID”,则最后的输出结果是
(5-3+1)/2=1.5,1.5向上取整是2,因此输出应该是227。

👉 tf.argmax() tf.agrmin()
axis = 0:
  axis=0时比较每一列的元素,将每一列最大元素所在的索引记录下来,最后输出每一列最大元素所在的索引数组。
axis = 1:
  axis=1的时候,将每一行最大元素所在的索引记录下来,最后返回每一行最大元素所在的索引数组。

👉 tf.cast(x,tf.float32)
数据类型转换。

👉 mnist.train.next_batch
是专门用于由tensorflow提供的MNIST教程的函数。它的工作原理是在开始时将训练图像和标签对随机化,并在每次调用该函数时选择每个随后的batch_size张图像。一旦到达末尾,图像标签对将再次随机分配,并重复该过程。仅在使用所有可用对后,才重新组合和重复整个数据集。

👉 tf.Graph().as_default()
表示实例化了一个类,一个用于 tensorflow 计算和表示用的数据流图,通俗来讲就是:在代码中添加的操作(画中的结点)和数据(画中的线条)都是画在纸上的“画”,而图就是呈现这些画的纸,你可以利用很多线程生成很多张图,但是默认图就只有一张。
tf.Graph().as_default() 表示将这个类实例,也就是新生成的图作为整个 tensorflow 运行环境的默认图,如果只有一个主线程不写也没有关系,tensorflow 里面已经存好了一张默认图,可以使用tf.get_default_graph() 来调用(显示这张默认纸),当你有多个线程就可以创造多个tf.Graph(),就是你可以有一个画图本,有很多张图纸,这时候就会有一个默认图的概念了。

适合小白哦~~~有错误的地方欢迎批评指正!!!!

爱你三千遍!!!!~~

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于神经网络手写数字识别是一种广泛应用的人工智能技术,它主要通过深度学习的方法来解决字符识别问题,特别是针对像MNIST这样的手写数字数据集。以下是概念设计的基本步骤: 1. 数据预处理:首先,收集和清理包含手写数字的图像数据集,将其转换为适合神经网络输入的标准化格式,如灰度图像,并进行归一化或标准化。 2. 网络结构选择:使用卷积神经网络(CNN)作为基础架构,因为CNN特别适合处理图像数据。它包括卷积层、池化层来提取特征,以及全连接层用于分类。 3. 模型构建:设计多层的CNN,通常包括输入层、卷积层(可能有多个,每层可有多个滤波器),然后是激活函数(如ReLU)、池化层以减少计算量并保留关键特征,接着是 Flatten 层将数据展平成一维,最后是几个全连接层用于分类,输出层通常使用 softmax 函数生成每个数字的概率分布。 4. 损失函数和优化器:选择适当的损失函数(如交叉熵),用于衡量模型预测与真实标签之间的差异。使用优化算法,如Adam或SGD,来调整网络权重,最小化损失。 5. 训练与验证:将数据集分为训练集和验证集,用训练集训练模型,通过验证集监控模型性能并防止过拟合。这个过程可能需要多次迭代,每次迭代后更新模型参数。 6. 测试与评估:在独立的测试集上评估模型的泛化能力,计算准确率或其他性能指标。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值