tensorflow mnist数字识别

本文详细介绍TensorFlow的入门知识及应用,通过MNIST数据集训练神经网络,讲解了包括优化方法、全连接层、激活函数在内的核心概念,以及如何使用滑动平均模型提升预测准确性。

从这以后应该是tf的正式入门了,之前的优化方法将都会在这里使用,下面是完整mnist训练过程。

第一次运行时要等一会下载训练数据集。

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


# MNIST数据集相关参数
INPUT_NODE = 784
OUTPUT_NODE = 10

# 配置神经网络参数
LAYER1_NODE = 500
BATCH_SIZE = 100

LEARNING_RATE_BASE = 0.8
LEARNING_RATE_DECAY = 0.99

REGULARIZATION_RATE = 0.0001
TRAINING_STEPS = 30000

MOVING_AVERAGE_DECAY = 0.99

# 定义一个辅助函数,给定神经网络的输入和所有参数,计算神经网络的前向传播结果
# 定义了 激活函数ReLu的三层全连接神经网络,也支持传入计算参数平均值的类,方便测试时使用滑动平均模型
def inference(input_tensor, avg_class, weight1, biases1, weight2, biases2):
    if avg_class is None:
        # 计算隐藏层前向传播结果
        layer1 = tf.nn.relu(tf.matmul(input_tensor, weight1) + biases1)
        # 计算输出层的前向传播结果
        return tf.matmul(layer1, weight2) + biases2
    else:
        # 首先使用avg_class.average函数计算得出变量的滑动平均值
        # 然后计算响应神经网络的前向传播结果
        layer1 = tf.nn.relu(
            tf.matmul(input_tensor, avg_class.average(weight1)) + avg_class.average(biases1)
        )

        return tf.matmul(layer1, avg_class.average(weight2)) + avg_class.average(biases2)

# 训练模型过程
def train(mnist):
    x = tf.placeholder(tf.float32, [None, INPUT_NODE], name='x-input')
    y_ = tf.placeholder(tf.float32, [None, OUTPUT_NODE], name='y-input')

    # 生成隐藏层参数
    weight1 = tf.Variable(
        tf.truncated_normal([INPUT_NODE, LAYER1_NODE], stddev=0.1))
    biases1 = tf.Variable(tf.constant(0.1, shape=[LAYER1_NODE]))

    # 生成输出层参数
    weight2 = tf.Variable(
        tf.truncated_normal([LAYER1_NODE, OUTPUT_NODE], stddev=0.1))
    biases2 = tf.Variable(tf.constant(0.1, shape=[OUTPUT_NODE]))

    # 计算前向传播结果,滑动平均模型为None
    y = inference(x, None, weight1, biases1, weight2, biases2)

    # 定义储存训练轮数变量,在使用tf训练神经网络时,一般将代表训练轮数的变量指定为不可训练的参数
    global_step = tf.Variable(0, trainable=False)

    # 给定滑动平均衰减率和训练轮数,初始化滑动平均模型
    variable_average = tf.train.ExponentialMovingAverage(
        MOVING_AVERAGE_DECAY, global_step)

    # 在所有代表神经网络参数的变量上使用滑动平均
    variables_averages_op = variable_average.apply(
        tf.trainable_variables())

    # 计算使用了滑动平均之后的前向传播结果
    average_y = inference(
        x, variable_average, weight1, biases1, weight2, biases2)

    # 计算交叉熵作为损失函数,当分类问题中只有一个正确答案时,可以使用这个函数加速交叉熵的计算,第一个
    # 参数是不包含softmax层的前向传播结果,第二参数是训练数据的正确答案
    cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(
        logits=y, labels=tf.argmax(y_, 1))
    # 计算当前btach中所有样例的交叉熵平均值
    cross_entropy_mean = tf.reduce_mean(cross_entropy)

    # 计算L2函数
    regularizer = tf.contrib.layers.l2_regularizer(REGULARIZATION_RATE)
    # 计算模型正则化损失。一般只计算神经网络上的权重的正则化损失而不使用偏置项
    regularization = regularizer(weight1) + regularizer(weight2)
    # 总损失
    loss = cross_entropy_mean + regularization
    # 设置指数衰减率
    learning_rate = tf.train.exponential_decay(
        LEARNING_RATE_BASE,
        # 当前迭代轮数
        global_step,
        # 过完所有的训练数据所需的轮数
        mnist.train.num_examples / BATCH_SIZE,
        LEARNING_RATE_DECAY
    )

    # 定义优化方法
    train_step = tf.train.GradientDescentOptimizer(
        learning_rate).minimize(loss, global_step=global_step)

    # 每过一遍数据需要通过反向传播更新神经网络中的参数,又要更新每个参数滑动平均值
    with tf.control_dependencies([train_step, variables_averages_op]):
        train_op = tf.no_op(name='train')

    correct_prediction = tf.equal(tf.argmax(average_y, 1), tf.argmax(y_, 1))

    # 计算正确率
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

    # 初始会话并开始训练
    with tf.Session() as sess:
        tf.global_variables_initializer().run()

        # 准备验证数据
        validate_feed = {
            x: mnist.validation.images,
            y_: mnist.validation.labels
        }

        test_feed = {
            x: mnist.test.images,
            y_: mnist.test.labels
        }

        # 迭代训练神经网络
        for i in range(TRAINING_STEPS):
            if i % 1000 == 0:
                validate_acc = sess.run(accuracy, feed_dict=validate_feed)
                print("After %d training step(s), validation accuracy using average model is %g " %
                      (i, validate_acc))
            # 产生batch,并进行训练过程
            xs, ys = mnist.train.next_batch(BATCH_SIZE)
            sess.run(train_op, feed_dict={x: xs, y_: ys})

        # 训练结束后在测试数据上检测神经网络的最终正确率
        test_acc = sess.run(accuracy, feed_dict=test_feed)
        print("After %d training step(s), test accuracy using average model is %g " %
              (TRAINING_STEPS, test_acc))

# 主程序入口
def main(argv=None):
    mnist = input_data.read_data_sets("/tmp/data", one_hot=True)
    train(mnist)

# tf提供的一个主程序入口
if __name__ == '__main__':
    tf.app.run()


cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(
logits=y, labels=tf.argmax(y_, 1)) 当分类问题中只有一个正确答案时,可以使用这个函数加速交叉熵的计算,第一个参数是不包含softmax层的前向传播结果,第二参数是训练数据的正确答案。

y_是一个长度为10的一维数组,而sparse_softmax_cross_entropy_with_logits函数第二参数需要提供的是一个正确答案的数字,所以使用tf.argmax(y_, 1)函数来得的正确答案的对应编号。

    with tf.control_dependencies([train_step, variables_averages_op]):
        train_op = tf.no_op(name='train')

下面两个函数等价

with tf.control_dependencies([train_step, variables_averages_op]):
        train_op = tf.no_op(name='train')
# 等价于
train_op = tf.group(train_step, variables_averages_op)

tf.group()用于创造一个操作,可以将传入参数的所有操作进行分组。ops = tf.group(tensor1, tensor2,…) 其中*inputs是0个或者多个用于组合tensor,一旦ops完成了,那么传入的tensor1,tensor2,…等等都会完成了

generator_train_op = tf.train.AdamOptimizer(g_loss, ...)
discriminator_train_op = tf.train.AdamOptimizer(d_loss,...)
train_ops = tf.groups(generator_train_op ,discriminator_train_op)

with tf.Session() as sess:
  sess.run(train_ops) 
  # 一旦运行了train_ops,那么里面的generator_train_op和discriminator_train_op都将被调用

tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) 将布尔型的数值转化为实数型,然后计算平均值作为正确率
cast(x, dtype, name=None)
第一个参数 x: 待转换的数据(张量)
第二个参数 dtype: 目标数据类型
第三个参数 name: 可选参数,定义操作的名称

import tensorflow as tf

t1 = tf.Variable([1, 2, 3, 4, 5])
t2 = tf.cast(t1, dtype=tf.bool)
t3 = tf.Variable([True, False])
t4 = tf.cast(t3, dtype=tf.float32)

with tf.Session() as sess:
    init_op = tf.global_variables_initializer()
    sess.run(init_op)
    print(sess.run(t2))
    print(sess.run(t4))

输出结果

[ True  True  True  True  True]
[1. 0.]

tf.app.run()
https://blog.youkuaiyun.com/fxjzzyo/article/details/80466321

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值