MNIST数据集 — 前期准备

2020-10-30 14:45:38 浏览数 (1)

前言

持续两个星期关于深度学习基础方面的更新,非常感谢我们这个小编为大家的总结分享。

前面都是基础零碎的知识,需要通过一个栗子来为大家把整个流程走一遍,从整体上对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
代码语言:javascript复制
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”)

小结

  • 变量管理
  • 代码持久化管理
  • 滑动平均模型
  • 学习速率衰减
  • 多目标优化,优化方向有多个时候怎么进行维护
  • 滑动平均模型 和学习速率衰减可以使模型更加健壮。

0 人点赞