准备工作
变量管理
# get_variable
#根据变量名称直接获取,如果不存在就创建一个新的
emb = tf.get_variab1e(name="emb",#变量名称(必填)
shape #词向量维度
initializer) # 词向量矩阵, 训练好的
# Variable
#创建一个新的变量,用具体的值初始化,变量名称可选
emb = tf.Variable(initializer,#词向量矩阵,训练好的
name="emb" #变量名称(可选)
tf.Variable + tf. name_ scope
通过组合可以简化命名参数,合理组织参数,在Tensorboard可视化展示过程中更加清晰结构逻辑tf.get_variable + tf.variab1e_scope
主要用于实现参数共享
Variable+name_ scope
#在conv1命名空间下定义变量
with tf.name_scope('conv1') as scope:
weights1 = tf.Variable([1.0, 2.0] , name= 'weights')
bias1 = tf.Variable([0.3], name='bias')
#在conv2命名空间下定义变量
with tf . name_ scoрe(' conv2') as scope :
weights2 = tf.Variable([4.0, 2.0], name= 'weights')
bias2 = tf.Variable([0.33], name='bias')
print (weights1.name) # conv1/wei ghts
print (weights2.name) # conv2/wei ghts
get_variable +variable_scope
#根据变量名称直接获取,如果不存在就创建一个新的
with tf.variable_scope(“s1"):
V = get_variab1e(“V", shape1, initializer1)
#创建失败,由于变量名“V”已经存在
v1 = get_variab1e(“v", shape1)
#如果已经存在,直接返回当前变量
with tf.variab1e_scope(“s1", reuse=True):
v2 = get_variab1e(“V", shape1)
#输出True, 都是s1/v
print (V==v2)
#変量空囘s1下創建変量v
with tf.variab1e_scope("s1"):
v = get_variab1e(“v", shape1, initializer1)
print (V) #輸出s1/v:0
#変量空囘s2下創建変量v
with tf.variab1e_scope("s2"):
v = get_variab1e(“v", shape1)
print (V) #輸出s2/v:0
#変量空囘s2下創建変量v
V = get_variab1e(“s1/v", shape1)
variable_scope VS . name_scope
#在name_scope下凋用get_variable
with tf.name_scope(“s1"):
v = get_variable(“v", shape1, initializer1)
print (V) #輸出v:0
#在variable_scope下凋用Variable
with tf.variab1e_scope(“s2"):
v = tf.Variab1e(“v", shape1)
print (v) #輸出s2/v:0
get_variable是不受name_scope的限制
持久化管理
保存
# 前续TensorFlow代码
......
#用于保存模型参数
saver = tf.train.Saver()
With tf.Session() as sess:
......
#保存模型到制定路径下
saver.save(sess, "path/to/model/model.ckpt")
生成三个文件:
model.ckpt.meta
计算图结构,模型结构model.ckpt
模型参数checkpoint
所有模型文件列表
部分保存
# 前续TensorFlow代码
......
#用于保存模型参数,通过词典给出要保存的参数列表
saver = tf.train.Saver({"v1":v1, "v2":v2})
With tf.Session() as sess:
......
#保存模型到制定路径下
saver.save(sess, "path/to/model/model.ckpt")
导入
# 前续TensorFlow代码
......
#用于保存模型参数
saver = tf.train.Saver()
With tf.Session() as sess:
......
#导入指定路径下的模型
saver.restore(sess, "path/to/model/model.ckpt")
--------------------------------------------------------
#直接加载计算结构图
saver = tf. train. import_meta_graph("path/to/model/model.ckpt/mode1.ckpt.meta")
With tf.Session() as sess:
......
#导入指定路径下的模型
saver.restore(sess, "path/to/model/model.ckpt")
滑动平均模型
滑动平均模型可以使模型在测试数据上更健壮,适合基于梯度下降算法训练神经网络的过程。在TensorFlow中提供了该模型: tf.train.ExponentialMovingAverage
#定义一个变量
v1 = tf.Variab1e(0, dtype=tf.f1oat32)
# num_updates变量更新次数
step = tf.variab1e(0, trainab1e=Fa1se)
#定义一个滑动平均模型,给出decay和num_updates
ema=tf.train.Exponentia1MovingAverage(0.99,step)
#定义一个滑动平均计算操作,给出要维护的变量列表
maintain_averages_op = ema.app1y([v1])
With tf.Session() as sess:
.......
sess. run(maintain_averages_op) # 运行滑动平均模型
学习速率衰减
训练前期使用较大的学习率加速,让模型快速收敛,训练过程中主键减小学习速率,到训练后期使用较小的学习率,使模型在训练后期更稳定。
# TensorFlow支持的学习速率衰减策略
exponential_decay
tf.train.exponential_decay(learning_rate,# 初始学习率
global_step,# 当前迭代次数
decay_steps,# 衰减速度,在迭代到该次数时衰减
decay_rate# 学习率衰减系数,通常介于0-1之间)
inverse_time_decay
natural_exp_decay
piecewise_constant
polynomial_decay
多目标优化
有时需要同时维护多套参数。例如,使用滑动平均模型时除了模型参数,还需要维护模型参数对应的影子变量。这个时候可以通过group和control_ dependencies完成。
# group
tf.group(train_part1, train_part2)
# control_denendencies
With tf.control_dependencies([train_p1, train_p2]) :
train_op = tf.no_op (name="train")
MNIST数字识别程序构成
mnist_inference.py
前馈计算,定义神经网络模型结构。mnist_train.py
模型训练,定义神经网络的训练过程。mnist_eval.py
模型评价,定义程序测试过程。
前馈计算
- 导入Mnist数据集
- 设置神经网络结构相关的参数
- 定义获取变量函数
- 定义神经网络的前向传播过程
MNIST数据集
MNIST是一个手写体数字识别数据集,它的训练数据集包含60000张图片,测试数据集包含10000张图片,其中每一-张图片都代表0~9中的一个数字。
1、导入Mnist数据集
# -*- coding: utf-8 -*
# 从Tensorflow里边加载MNIST数据集
from tensorflow.examples.tutorials.mnist import input_data
# 载入MBNIST数据集,如果之前没有下载过,则会自动下载到相应的目录
mnist = input_data.read_data_sets('./path/MNIST_data', one_hot=True)
# 打印training_data_size: 55000
print('training_data_size:', mnist.train.num_examples)
# 打印Example training data
print('Example training data:', mnist.train.images[0])
输出结果
training_data_size: 55000
Example training data: [0. 0. 0. ... 0.3803922 0.37647063 0.3019608
0.81568635 0.7803922 0.7803922 0.7803922 ....
0. 0. ]
代码中的one hot=True ,表示将样本标签转化为one hot 编码。
举例来解释one_hot 编码: 假如一共10 类。0 的one_hot 为1000000000,1 的one_hot为0100000000 , 2 的one hot 为0010000000 , 3 的one hot 为0001000000 ..…·依此类推。只有一个位为1 , 1 所在的位置就代表着第几类。
2、设置神经网络结构相关的参数
# 输入层的节点数。对于MNIST数据集,这个等于图片的总像素=28*28
INPUT_NODE = 784
# 输出层的节点数。在MNIST数据集中有0~9这10个数字类别
OUTPUT_NODE = 10
# 神经网络隐藏节点数
LAYERl_NODE = 500
3、定义获取变量函数
def get_weight_variable(shape, regularizer):
# shape是变量的大小,regularizer是正则化函数。
# tf.truncated_normal_initializer是正态分布初始化函数
weights = tf.get_variable("weights", shape, initializer=tf.truncated_normal_initializer(stddev=0.1))
# tf.add_to_collections 将当前变量的正则化损失加入名字为1osses的集合
if regularizer != None:
tf.add_to_col1ections('losses', regularizer(weights))
return weights
4、定义神经网络的前向传播过程
def inference(input_tensor, regularizer):
# 声明第一层神经网络的名 命空间'layer1'及相关变量,并完成前向传播过程
with tf.variable_scope("layer1"):
weights = get_weight_variable([INPUT_NODE, LAYERl_NODE], regularizer)
biases = tf.get_variab1e("biases", [LAYERl_NODE], initializer=tf.constant_initializer(0.0))
output1 = tf.matmul(input_tensor, weights) + biases
# 使用relu激活函数
layer1 = tf.nn.relu(output1)
# 声明第二层神经网络的名命空间'layer2’及相关变量,并完成前向传播过程
with tf.variable_scope('layer2'):
weights = get_weight_variable([LAYERl_NODE, OUTPUT_NODE], regularizer)
biases = tf.get_variable('biases', [OUTPUT_NODE], initializer=tf.constant_initializer(0.0))
layer2 = tf.matmul(layer1, weights) + biases
# 返回前向传播的结果
return layer2
模型训练
- 配置训练参数
- 定义训练模型
- 进行训练
配置训练参数
# 一个训练batch中的训练数据个数
BATCH_SIZE = 100
# 基础学习率
LEARNING_RATE_BASE = 0.8
# 学习率的衰减率
LEARNING_RATE_DECAY = 0.99
# 正则化项在损失函数里的系数
REGULARAZTION_RATE = 0.0001
# 训练轮数
TRAINING_STEPS = 30000
# 滑动平均衰减率
MOVING_AVERAGE_DECAY = 0.99
# 配置神经网络参数
MODEL_SAVE_PATH = "/path/to/model"
MODEL_NAME ="model.ckpt"
定义训练模型
# 定义训练模型
def train(mnist):
# 定义输入输出的placeholder
x = tf.placeholder(tf.f1oat32, [NONE, mnist_inference.INPUT_NODE], name='x-input')
y_ = tf.placeholder(tf.f1oat32, [NONE, mnist_inference.OUTPUT_NODE], name='y-input')
# 并定义正则化方法(tensorflow中的12正则化法)
regularizer = tf.contrib.layers.l2_regularizer(REGULARAZTION_RATE)
# 直接调用mnist_inference.py中定义的前向传播过程
y = mnist_inference.inference(x, regularizer)
# 定义迭代次数变量,一般会将训练轮数的变量指定为不可训练的参数
global_step = tf.Variable(0, trainable=False)
# 滑动平均模型定义滑动平均操作,提升模型对数据对鲁棒性
variable_averages = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY, global_step)
# 使用tf.trainable_variables可以获得神经网络中所有trainable=True的变量
variable_averages_op = variable_averages.apply(tf.trainable_variables())
# 定义模型预测值与真实标签的交叉熵
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=y_)
# 求一个batch的平均交叉熵
cross_entropy_mean = tf.reduce_mean(cross_entropy)
# 定义损失函数,包含预测标签与实际标签的损失和正则化损失
loss = cross_entropy_mean + tf.add_n(tf.get_collection('losses'))
# 定义指数衰减学习率,训练前期使用较大的学习率加速,训练后期使用较小的学习率,使模型在训练后期更稳定
learning_rate = tf.train.exponential_decay(LEARNING_RATE_BASE, # 基础学习率
global_step, # 当前迭代轮数
mnist.train.num_examples/BATCH_SIZE, # 所有训练数据需要迭代的轮数
LEARNING_RATE_DECAY) # 学习率衰减速度
# 定义优化函数,使用tensorflow的梯度下降优化器
train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step)
# 训练时,每过一遍数据,需要更新参数以及每个参数的滑动平均值,使用tf.group()
train_op = tf.group(train_step, variable_averages_op)
# 初始化Tensorflow持久化类
saver = tf.train.Saver()
with tf.Session() as sess:
# 初始化全局的变量
tf.global_variables_initializer().run()
for i in range(TRAINING_STEPS):
# 自动获取一个batch的数据
xs, ys = mnist.train.next_batch(BATCH_SIZE)
_, loss_value, step = sess.run([train_op, loss, global_step], feed_dict={x: xs, y: ys})
# 每1000轮保存一次模型
if i % 1000 == 0:
# 输出当前训练情况,并保存当前模型
print("After %d training step(s), loss on training batch is %g" % (step, loss_value))
saver.save(sess, os.path.join(MODEL_SAVE_PATH, MODEL_NAME), global_step=global_step)
进行训练
# 执行训练
def main():
mnist = mnist_inference.mnist
train(mnist)
if __name__ == '__main__':
main()
模型评价
import time
import tensorflow as tf
from tftest import mnist_inference
from tftest import mnist_train
# 每10秒加载一次最新模型。并进行一次测试
EVAL_INTERVAL_SEC = 10
def evaluate(mnist):
with tf.Graph().as_default() as g:
# 定义输入输出格式
x = tf.placeholder(tf.float32, [None, mnist_inference.INPUT_NODE], name='x-input')
y_ = tf.placeholder(tf.float32, [None, mnist_inference.OUTPUT_NODE], name='y-input')
# 5000个验证集导入
validate_feed = {x: mnist.validation.images,
y_: mnist.validation.labels}
# 调用封装好的函数计算前向传播结果,测试时不关注正则化损失的值
y = mnist_inference.inference(x, None)
# 使用tf.argmax(y, 1)得到输入样例的预测类别,判断预测和真实标签是否相等
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
# 计算预测的精确率
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
variable_averages = tf.train.ExponentialMovingAverage(mnist_train.MOVING_AVERAGE_DECAY)
# variables_to_restore是Tensorflow为滑动模型提供
# 可以指定载入的是对应的影子变量
variables_to_restore = variable_averages.variables_to_restore()
# 直接用影子变量的参数赋值给inference的变量
saver = tf.train.Saver(variables_to_restore)
# 每隔10秒调用一次正确率的过程,观察训练过程中的正确率变化
while True:
with tf.Session() as sess:
# 通过checkpoint文件自动找到目录中最新模型的文件名
ckpt = tf.train.get_checkpoint_state(mnist_train.MODEL_SAVE_PATH)
if ckpt and ckpt.model_checkpoint_path:
# 加载模型
saver.restore(sess, ckpt.model_checkpoint_path)
# 从模型保存文件里得到模型保存时的迭代轮数
global_step = ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1]
accuracy_score = sess.run(accuracy, feed_dict=validate_feed)
print("After %s training step(s), validation accuracy=%g" % (global_step, accuracy_score))
else:
# 说明并没有保存已经训练好的模型参数存储文件
print("No checkpoint file found")
return
# 程序休眠10秒
time.sleep(EVAL_INTERVAL_SEC)
def main():
mnist = mnist_inference.mnist
evaluate(mnist)
if __name__ == '__main__':
main()
遇到的问题
1、编码问题
SyntaxError: Non-ASCII character '\xe4' in file mnist_inference.py on line 1, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
解决方法
在文件头追加:
# -*- coding: utf-8 -*
2、没有对应的模型输出
ImportError: No module named tutorials.mnist
我的电脑在(tensorflow) cyh@chenyonghuandeMacBook-Pro ~/tensorflow/lib/python2.7/site-packages
目录下有文件夹tensorflow, tensorflow_core, tensorflow_estimator等文件夹。进入tensorflow_core文件夹,里面发现一个examples文件夹,但是文件夹下只有saved_model这个文件,没有找到tutorials。
解决方法
进入 tensorflow主页 下载缺失的tutorials文件。我是直接把整个下载下来,然后在下载文件的路径tensorflow-master\tensorflow\examples\
这里找到了tutorials,把tutorials整个文件夹拷贝到上文中提到的tensorflow_core\examples\
文件夹下。
3、使用TensorFlow 从网上下载数据集到本地时,pycharm 没有写入权限
tensorflow.python.framework.errors_impl.PermissionDeniedError: /path; Read-only file system
解决方法
#使用终端 进入到编辑的项目
cd /Users/cyh/doc/code/VGG16/tftest
#使用命令
sudo python mnist_inference.py