【发布时间】:2018-06-27 23:26:53
【问题描述】:
我正在使用 tf.estimator.Estimator 来管理我的代码的训练和测试部分。我正在调整一些超参数,所以我需要确保使用相同的随机种子初始化权重。无论如何为 tf.estimator 创建的会话设置随机种子?
【问题讨论】:
标签: tensorflow tensorflow-datasets tensorflow-estimator
我正在使用 tf.estimator.Estimator 来管理我的代码的训练和测试部分。我正在调整一些超参数,所以我需要确保使用相同的随机种子初始化权重。无论如何为 tf.estimator 创建的会话设置随机种子?
【问题讨论】:
标签: tensorflow tensorflow-datasets tensorflow-estimator
您应该在传递给估算器的配置中定义随机种子:
seed = 2018
config = tf.estimator.RunConfig(model_dir=model_dir, tf_random_seed=seed)
estimator = tf.estimator.Estimator(model_fn, config=config, params=params)
这是RunConfig 的文档。
需要注意的一点是,每次运行estimator.train(train_input_fn) 时,都会创建一个新图来训练模型(通过调用train_input_fn 来创建输入管道并在@987654327 的输出上调用model_fn @)。
一个问题是这个新图每次也将设置相同的随机种子。
让我用一个例子来解释。假设您在输入管道中执行数据扩充,并且您在每个 epoch 都评估您的模型。这会给你类似的东西:
def train_input_fn():
features = tf.random_uniform([])
labels = tf.random_uniform([])
dataset = tf.data.Dataset.from_tensors((features, labels))
return dataset
def model_fn(features, labels, mode, params):
loss = features
global_step = tf.train.get_global_step()
train_op = global_step.assign_add(1)
return tf.estimator.EstimatorSpec(mode, loss=loss, train_op=train_op)
seed = 2018
config = tf.estimator.RunConfig(model_dir="test", tf_random_seed=seed)
estimator = tf.estimator.Estimator(model_fn, config=config)
num_epochs = 10
for epoch in range(num_epochs):
estimator.train(train_input_fn, steps=1)
estimator.evaluate(train_input_fn, steps=1)
输入函数创建随机特征(和标签)。发生的情况是,创建的特征在每个时期都将完全相同。输出如下:
INFO:tensorflow:loss = 0.17983198, step = 1
INFO:tensorflow:Saving dict for global step 1: global_step = 1, loss = 0.006007552
INFO:tensorflow:loss = 0.17983198, step = 2
INFO:tensorflow:Saving dict for global step 2: global_step = 2, loss = 0.006007552
INFO:tensorflow:loss = 0.17983198, step = 3
INFO:tensorflow:Saving dict for global step 3: global_step = 3, loss = 0.006007552
...
您可以看到每个时期的损失(等于输入特征)是相同的,这意味着在每个时期使用相同的随机种子。
如果您想在每个 epoch 进行评估并执行数据增强,这是一个问题,因为您最终会在每个 epoch 获得相同的数据增强。
一个快速的解决方案是删除随机种子。但是,这会阻止您运行可重复的实验。
另一个更好的解决方案是在每个 epoch 使用相同的 model_fn 创建一个新的估算器,但随机种子不同:
seed = 2018
num_epochs = 10
for epoch in range(num_epochs):
config = tf.estimator.RunConfig(model_dir="test", tf_random_seed=seed + epoch)
estimator = tf.estimator.Estimator(model_fn, config=config)
estimator.train(train_input_fn, steps=1)
estimator.evaluate(train_input_fn, steps=1)
每个时期的特征都会正确改变:
INFO:tensorflow:loss = 0.17983198, step = 1
INFO:tensorflow:Saving dict for global step 1: global_step = 1, loss = 0.006007552
INFO:tensorflow:loss = 0.22154999, step = 2
INFO:tensorflow:Saving dict for global step 2: global_step = 2, loss = 0.70446754
INFO:tensorflow:loss = 0.48594844, step = 3
【讨论】: