从这以后应该是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