神经网络学习(二)Tensorflow-简单神经网络(全连接层神经网络)实现手写字体识别

神经网络学习(二)神经网络-手写字体识别

框架:Tensorflow 1.10.0
数据集:mnist数据集
策略:交叉熵损失
优化:梯度下降
五个模块:拿数据、搭网络、求损失、优化损失、算准确率

一、拿数据

1、下载数据集

下载数据集点这里:mnist数据集官网下载。将下图四项下载下来。放入接下来代码所在的文件夹。在这里插入图片描述

2、导入数据

把tensorflow和input_data给导进来,tensorflow就不作解释了,input_data是用来操作mnist数据集的。代码如下。( ps:全部代码在最下面,不要着急,先按照下面的思路走完,然后再看代码也不迟。代码里也加了注释。静心往下看。)

from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf

将上面下载的四项数据文件的路径写进去代码如下,目标值使用独热编码(one_hot)

mnist = input_data.read_data_sets("./data/mnist/input_data/", one_hot=True)

3、数据集简介

手写数字的MNIST数据库有一个包含60,000个示例的训练集和一个包含10,000个示例的测试集。它是NIST中更大集合的子集。在固定大小的图像中,数字已被大小归一化并居中。
里面都是手写的数字(从0到9)的图片。

二、搭建网络

1、建立占位符

tf.variable_scope可以认为是一个空间或者是op管理器,在此范围内创建的变量都属于这个空间,注意:不可创建相同名称的变量。其中xy_true 作用是占座位或是分割数据,是为训练样本跟其对应的特征值(样本所所属的类别)准备的。784是如何来的呢?mnist数据集中包含很多图片,图片 长*宽=28×28=784,即像素为784。上面提到 mnist数据集里面包含6000个示例,其中一个示例就是一张照片, 一张照片就是28×28=784,那就可以把mnist数据集看做是一个6000×784的矩阵。 None(矩阵的行)在这的表示为任意值或不确定值,因为这关系到我们每一次训练模型时所用到的样本大小(batch)

  with tf.variable_scope("data"):  
        x = tf.placeholder(tf.float32, [None, 784]) 
        y_true = tf.placeholder(tf.int32, [None, 10])

2、搭建全连接层神经网络

简单的来说就是wx+b:w为权重,b为偏置。

神经网络训练的过程 其实就是通过对比预测值(y_predict)与目标值(y_true)间的差异来不断优化w跟b的一个过程。那么下面第一步就是初始化w跟b。

其中tf.random_normal([784, 10]两个变量784跟10,784为特征点(一张图片的784个像素点或一张图片的784个特征)数量,10为其目标值(0-9)的数量。
y_predict即为一次预测所得到的结果。

   with tf.variable_scope("fc_model"):
        # 随即初始化权重和偏置
        weight = tf.Variable(tf.random_normal([784, 10], dtype=float, name="w"))
        bias = tf.Variable(tf.constant(0.0, shape=[10]))
       
        y_predict = tf.matmul(x, weight) + bias  # tf.matmul是矩阵乘法

三、计算损失(loss)

求平均交叉熵损失(先经过softmax得到概率,后交叉熵拿损失,后求平均损失)
什么是损失,损失就是我们的预测值跟其对应的目标值(其真实值)之间的差异。
这里我们用到了交叉熵损失函数数学公式如下:
在求损失之前我们先计算预测值的概率,这里用到的是softmax函数,数学公式看不明白没事 tensorflow一行代码就解决,tf.nn.softmax_cross_entropy_with_logits(这一行代码就把softmax跟交叉熵损失函数包括了)

 with tf.variable_scope("soft_cross"):
        loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true, logits=y_predict))

交叉熵损失函数
在这里插入图片描述

四、梯度下降减小损失

0.1是学习率 不要太大了,再将损失传进去。个人认为这个过程才是真正的训练过程。

    with tf.variable_scope("optimizer"):
        train_op = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

五、计算准确率

 with tf.variable_scope("acc"):
        # 分别拿到预测样本跟目标样本每一行的最大下标 ,若下表相等 返回1 不相等返回0
        equal_list = tf.equal(tf.argmax(y_true, 1), tf.argmax(y_predict, 1))

        accuracy = tf.reduce_mean(tf.cast(equal_list, tf.float32))

六、效果

1、用了测试集的100张照片进行测试,准确率为85%。

在这里插入图片描述

七、代码

from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf

FlAGS = tf.flags.FLAGS
tf.flags.DEFINE_integer("is_train", 0, "指定程序是预测还是训练")


# 单层(全连接阶层)
def full_connected():
    # 获取数据
    mnist = input_data.read_data_sets("./data/mnist/input_data/", one_hot=True)
    #  1、建立数据占位符  x [None,784]  y_true[None,10]
    with tf.variable_scope("data"):  # tf.variable_scope算是个命名空间或者是op管理器,在此范围内创建的变量都属于这个空间,注意:不可创建相同名称的变量。
        x = tf.placeholder(tf.float32, [None, 784])  # 占位符,【none,784】表示任意行,取784列
        y_true = tf.placeholder(tf.int32, [None, 10])

    #  2、建立一个全连接层的神经网络 w = [784,10]  b = [10]
    with tf.variable_scope("fc_model"):
        # 随即初始化权重和偏置
        weight = tf.Variable(tf.random_normal([784, 10], dtype=float, name="w"))
        bias = tf.Variable(tf.constant(0.0, shape=[10]))
        # (前向传播)预测None个样本的输出结果matrix [None,784]*[784,10]+[10] = [None,10]
        y_predict = tf.matmul(x, weight) + bias  # tf.matmul矩阵乘法

    # 3、求所有样本的损失、然后求平均值
    with tf.variable_scope("soft_cross"):
        # 求平均交叉熵损失(先经过softmax得到概率,后交叉熵拿损失,后求平均损失)
        loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true, logits=y_predict))

    # 4、梯度下降求出损失
    with tf.variable_scope("optimizer"):
        train_op = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

    # 5、计算准确率
    with tf.variable_scope("acc"):
        # 分别拿到预测样本跟目标样本每一行的最大下标 ,若下表相等 返回1 不相等返回0
        equal_list = tf.equal(tf.argmax(y_true, 1), tf.argmax(y_predict, 1))

        # 准确率=算平均值 None个样本 [1,0,1,0,1,1,0,1,..............................]
        accuracy = tf.reduce_mean(tf.cast(equal_list, tf.float32))

    # 收集变量  (一维)单个数字值收集
    tf.summary.scalar("losses", loss)
    tf.summary.scalar("acc", accuracy)

    # 收集变量 高纬度变量收集
    tf.summary.histogram("weightes", weight)
    tf.summary.histogram("biases", bias)

    # 定义一个合并变量的操作operation
    merged = tf.summary.merge_all()

    # 定一个初始化变量的op
    init_op = tf.global_variables_initializer()

    # 定义一个saver用于保存模型
    saver = tf.train.Saver()
    correct = 0
    # 6、开启会话去训练
    with tf.Session() as sess:
        # 初始化变量
        sess.run(init_op)

        # 建立events文件,然后写入
        filewriter = tf.summary.FileWriter("./temp/summary/test/", graph=sess.graph)

        # 设置一个标志位用于判断是进行训练 还是进行测试机预测
        # 如果是1 则训练,0则预测
        if FlAGS.is_train == 1:
            # 迭代步数去训练,更新参数 预测
            for i in range(2000):
                # 取出真实存在的目标值和特征值
                mnist_x, mnist_y = mnist.train.next_batch(50)

                # 运行train_op训练
                sess.run(train_op, feed_dict={x: mnist_x, y_true: mnist_y})

                # 写入每一步训练的值
                summary = sess.run(merged, feed_dict={x: mnist_x, y_true: mnist_y})
                filewriter.add_summary(summary, i)
                print("训练地%d步,准确率为:%f" % (i, sess.run(accuracy, feed_dict={x: mnist_x, y_true: mnist_y})))

            # 保存模型
            saver.save(sess, "./temp/ckpt/fc_model")
        else:
            saver.restore(sess, "./temp/ckpt/fc_model")
            # 如果是0,则作出预测
            for i in range(100):
                # 每次测试一张图片
                x_test, y_test = mnist.test.next_batch(1)

                print("第%d张图片目标是%d,预测结果是:%d" % (
                    i,
                    tf.argmax(y_test, 1).eval(),
                    tf.argmax(sess.run(y_predict, feed_dict={x: x_test, y_true: y_test}), 1).eval()
                ))
                if (tf.argmax(y_test, 1).eval() == tf.argmax(sess.run(y_predict, feed_dict={x: x_test, y_true: y_test}),
                                                             1).eval()):
                    correct += 1
        print("100样本预测准确率:%f" % (correct/100))
    return None


if __name__ == "__main__":
    full_connected()

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值