前言
持续两个星期关于深度学习基础方面的更新,非常感谢我们这个小编为大家的总结分享。
前面都是基础零碎的知识,需要通过一个栗子来为大家把整个流程走一遍,从整体上对TensorFlow进行一个把握,大概分为四篇文章来说明吧(前期准备、前馈计算、模型训练、模型评价)。
变量管理
代码语言:javascript复制# get_variable
emb = tf.get_variable(name=“emb”, # 变量名称(必填)
shape # 词向量维度
initializer) # 词向量矩阵,训练好的
# Variable
emb = tf.Variable(initializer, # 词向量矩阵,训练好的
name=“emb” # 变量名称(可选)
上一篇文章说过声明变量的方法分为两种get_variable()和variable()方法,get_variable()其实是通过变量名来管理变量的方法,根据变量名称直接获取,如果不存在就创建一个新的。Variable()方法,创建一个新的变量,用具体的值初始化,变量名称可选。
Variable name_scope
通过组合可以简化命名参数,合理组织参数,在Tensorboard可视化展示过程中更加清晰结构逻辑。
使用name_scope进行空间命名,使用variable进行初始化。下面再定义一个名为conv2的空间,分别打印名称。
代码语言:javascript复制# 在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_scope('conv2') as scope:
weights2 = tf.Variable([4.0, 2.0], name='weights')
bias2 = tf.Variable([0.33], name='bias')
print (weights1.name) # conv1/weights
print (weights2.name) # conv2/weights
get_variable variable_scope
主要用于实现参数共享。
使用variable_scope创建变量名为s1的空间,通过get_variable获取方法。
代码语言:javascript复制# 根据变量名称直接获取,如果不存在就创建一个新的
with tf.variable_scope(“s1”):
v = get_variable(“v”, shape1, initializer1)
# 创建失败,由于变量名“v”已经存在
v1 = get_variable(“v”, shape1)
# 如果已经存在,直接返回当前变量
with tf.variable_scope(“s1”,reuse=True):
v2 = get_variable(“v”, shape1)
# 输出 True, 都是s1/v
print(v==v2)
代码语言:javascript复制# 变量空间s1下创建变量v
with tf.variable_scope(“s1”):
v = get_variable(“v”, shape1, initializer1)
print (v) # 输出 s1/v:0
# 变量空间s2下创建变量v
with tf.variable_scope(“s2”):
v = get_variable(“v”, shape1)
print (v) # 输出 s2/v:0
# 变量空间s2下创建变量v
v = get_variable(“s1/v”, shape1)
variable_scope vs. name_scope
代码语言:javascript复制# 在name_scope下调用get_variable
with tf.name_scope(“s1”):
v = get_variable(“v”, shape1, initializer1)
print (v) # 输出 v:0
# 在variable_scope下调用Variable
with tf.variable_scope(“s2”):
v = tf.Variable(“v”, shape1)
print (v) # 输出 s2/v:0
variable_scope和name_scope区别是什么?Name_scope和get_variable一起使用的时候,name_scope是不起任何作用的,variable_scope和Variable使用是有对应的作用的, get_variable是不受name_scope的限制的。
代码持久化管理
保存
代码语言:javascript复制# 前续TensorFlow代码
…………
# 用于保存模型参数
saver = tf.train.Saver()
With tf.Session() as sess:
…………
# 保存模型到制定路径下
saver.save(sess, “path/to/model/model.ckpt”)
我们把一个模型训练结束,一般是要把它保存下来,后期如果想用这个模型,会把这个模型导入进来,进行预测,这个就是持久化的过程,将内存中的模型导入到磁盘里边生成一个文件。持久化包括:保存和导入。TensorFlow里边怎么进行持久管理呢?前面我们说了很多进行模型训练,这里使用tf.train中的saver()保存。创建saver对象,在session中训练好模型,然后调用saver的save方法,指定路径进行保存。
保存为三个文件:
model.ckpt.meta, 计算图结构,模型结构
model.ckpt,模型参数
checkpoint,所有模型文件列表
导入
代码语言:javascript复制# 前续TensorFlow代码
…………
# 用于保存模型参数
saver = tf.train.Saver()
With tf.Session() as sess:
…………
# 导入指定路径下的模型
saver.restore(sess, “path/to/model/model.ckpt”)
然后需要进行导入,和保存的代码差不多,在session里边调用restore方法,指定路径。
前面的方法是直接重写一个模型结构再把参数导进来,这里是声明saver的时候,直接先把保存好的模型结构先导进来,然后把参数导进来。
前面的方法是直接重写一个模型结构再把参数导进来,这里是声明saver的时候,直接先把保存好的模型结构先导进来,然后把参数导进来。
代码语言:javascript复制# 直接加载计算结构图
saver = tf.train.import_meta_graph(
“path/to/model/model.ckpt/model.ckpt.meta”)
With tf.Session() as sess:
…………
# 导入指定路径下的模型
saver.restore(sess, “path/to/model/model.ckpt”)
部分保存
代码语言:javascript复制# 前续TensorFlow代码
…………
# 用于保存模型参数,通过词典给出要保存的参数列表
saver = tf.train.Saver({“v1”:v1, “v2”:v2})
With tf.Session() as sess:
…………
# 保存模型到制定路径下
saver.save(sess, “path/to/model/model.ckpt”)
持久化部分参数,如果需要针对性的导出,对每个参数进行命名,按照词典的方式进行参数名称对应参数值,用这个词典初始化saver类。
滑动平均模型
滑动平均模型可以使模型在测试数据上更健壮,适合基于梯度下降算法训练神经网络的过程。在TensorFlow中提供了该模型:tf.train.ExponentialMovingAverage。
代码语言:javascript复制# 定义一个变量
v1 = tf.Variable(0, dtype=tf.float32)
# num_updates 变量更新次数
step = tf.Variable(0, trainable=False)
# 定义一个滑动平均模型,给出decay和num_updates
ema=tf.train.ExponentialMovingAverage(0.99, step)
# 定义一个滑动平均计算操作,给出要维护的变量列表
maintain_averages_op = ema.apply([v1])
With tf.Session() as sess:
…………
sess.run(maintain_averages_op) # 运行滑动平均模型
学习速率衰减
学习速率不是一个固定的值,训练前期使用较大的学习率加速,让模型快速收敛,训练过程中主键减小学习速率,到训练后期使用较小的学习率,使模型在训练后期更稳定。
TensorFlow支持的学习速率衰减策略
- exponential_decay
- inverse_time_decay
- natural_exp_decay
- piecewise_constant
- polynomial_decay
tf.train.exponential_decay(
learning_rate, # 初始学习率
global_step, # 当前迭代次数
decay_steps, # 衰减速度,在迭代到该次数时衰减
decay_rate # 学习率衰减系数,通常介于0-1之间
)
有时需要同时维护多套参数。例如,使用滑动平均模型时除了模型参数,还需要维护模型参数对应的影子变量。这个时候可以通过group和control_dependencies完成。
代码语言:javascript复制# group,参数为需要维护的
tf.group(train_part1, train_part2)
# control_denendencies
With tf.control_dependencies([train_p1, train_p2]):
train_op = tf.no_op(name=“train”)
小结
- 变量管理
- 代码持久化管理
- 滑动平均模型
- 学习速率衰减
- 多目标优化,优化方向有多个时候怎么进行维护
- 滑动平均模型 和学习速率衰减可以使模型更加健壮。