Tensorflow 神经网络 MNIST

Mnist手写数字识别

Mnist数据集可以从官网下载,网址: http://yann.lecun.com/exdb/mnist/ ,包含55000行的训练数据集(mnist.train)和10000行的测试数据集(mnist.test),图片长宽为28*28,数据集中的图片如下图所示:
Tensorflow 神经网络 MNIST_第1张图片

MNIST图片识别流程:先读取MNIST数据集,再随机给出权重和偏置,计算平均交叉熵损失,最后通过反向传播算法优化权重和偏置。

 

one-hot编码

处理预测的结果,对10个类别进行标记,例如“4”处理过后的结果如下:
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0,]  将4对应的位置标记为1,其余位置为0,类似下图,将样本所属的类别标记为1.

Tensorflow 神经网络 MNIST_第2张图片

SoftMax回归

softmax实际上是一个概率计算模型,用来做输出判定,根据预测的概率得出预测值,为下一步计算交叉熵做准备。

举个栗子:对于mnist数据集,有0-9十个数,softmax的作用是计算一张图片是这十个数的概率, 其中所有的概率相加和为1。

softmax计算公式如下:

在神经网络中,整个过程如下:

Tensorflow 神经网络 MNIST_第3张图片
最后的softmax模型,用数学式子表示:

 

softmax,sigmod,relu激活函数对比

relu计算公式:

sigmod计算公式:

softmax作为分类输出,保证输出的概率为1,一般用在最后一层。

sigmod和relu都用于隐藏层输出,差别在于sigmod更擅长于二分类问题,sigmod的缺点是可能会发生“梯度爆炸”也就是“”梯度消失”,产生的原因是权重过大。

使用梯度下降优化参数,对损失函数求导,那么这个过程是按照某一点在w​1​​‘上的偏导数下降寻找最低点,直到找到最低点为止,二维梯度下降求导流程图如下:

Tensorflow 神经网络 MNIST_第4张图片

sigmod的原函数和导函数如下:

Tensorflow 神经网络 MNIST_第5张图片

在x轴的两边,导函数趋于0,这时发生梯度消失。

relu的导函数如下(蓝色):

Tensorflow 神经网络 MNIST_第6张图片

 

损失计算-交叉熵损失

每个样本都会有一个交叉熵,如果预测样本的某个特征为1,真实的特征也为1,那么刚好相乘求和等于0,相反如果求得的交叉熵较大,那么需要更新相关的权重和偏置。

备注:信息熵越大说明不确定性越大。

交叉熵损失的计算公式如下:

其中yi'表示真实值,yi表示预测值,实际上是softmax处理过后得到的概率值。

 

反向传播算法

反向传播:根据输出向前更新权重和偏置。

正向传播:输入数据一层层的得到输出结果。

实际上在tensorflow中,整张数据流图的计算过程都被记录下来,在交叉熵损失计算出来后,数据流图优化权重和偏置参数,看起来好像是从后面往前传播的一样,所以命名为反向传播。算法在本质还是梯度下降,只不过这里的更新权重有一个传播的概念,通过损失梯度下降来求里面的每一个部分的权重去更新。

 

实现神经网络模型

代码实现的的流程:

1.对训练的数据占位。
2.初始化权重+偏置。
3.求出平均交叉熵损失(使用softmax函数)。
4.梯度下降优化损失。
5.计算准确率。


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

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


def full_connected():

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

    # variable_scope定义变量作用域
    with tf.variable_scope("data"):
        # 先对需要进行训练的数据占位
        x = tf.placeholder(tf.float32, [None, 784])

        y_true = tf.placeholder(tf.int32, [None, 10])

    with tf.variable_scope("fc_model"):

        # 初始化权重和偏置
        weight = tf.Variable(tf.random_normal([784, 10], mean=0.0, stddev=1.0), name="w")
        bias = tf.Variable(tf.constant(0.0, shape=[10]))
        # 计算预测值
        y_predict = tf.matmul(x, weight) + bias

    # 求出所有损失,然后求平均值
    with tf.variable_scope("soft_cross"):
        # 平均交叉熵损失,损失计算,这里有一步softmax计算,将传入的值计算概率,与目标值计算。
        loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true, logits=y_predict))

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

    with tf.variable_scope("acc"):
        equal_list = tf.equal(tf.argmax(y_true, 1), tf.argmax(y_predict, 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)

    init_op = tf.global_variables_initializer()

    merged = tf.summary.merge_all()

    # 定义保存模型变量
    saver = tf.train.Saver()

    with tf.Session() as sess:

        sess.run(init_op)

        filewriter = tf.summary.FileWriter("./tmp/summary/", graph=sess.graph)

        if FLAGS.is_train == 1:

            for i in  range(2000):

                mnist_x, mnist_y = mnist.train.next_batch(50)

                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, "./tmp/ckpt/fc_model")

        else:
            # 读取模型
            saver.restore(sess, "./tmp/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()
                ))


    return None


if __name__ == '__main__':
    full_connected()



使用训练好的模型进行预测,使用命令行,cd到当前.py文件的目录,执行以下命令:

python3 ./mnist.py --is_train=0

运行结果如下:

Tensorflow 神经网络 MNIST_第7张图片

 

你可能感兴趣的:(tensorflow,神经网络,mnist,DeepLearning)