tensorflow:在多个检查点上运行模型评估

时间:2017-03-01 12:42:43

标签: python tensorflow

在我目前的项目中,我每100次迭代步骤训练一个模型并保存检查点。检查点文件全部保存到同一目录(model.ckpt-100,model.ckpt-200,model.ckpt-300等)。之后,我想根据所有已保存检查点的验证数据评估模型,而不仅仅是最新的检查点。

目前我恢复检查点文件的代码如下:

ckpt = tf.train.get_checkpoint_state(FLAGS.checkpoint_dir)
ckpt_list = saver.last_checkpoints
print(ckpt_list)
if ckpt and ckpt.model_checkpoint_path:
    print("Reading model parameters from %s" % ckpt.model_checkpoint_path)
    saver.restore(sess, ckpt.model_checkpoint_path)
    # extract global_step from it.
    global_step = ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1]
    print('Succesfully loaded model from %s at step=%s.' %
            (ckpt.model_checkpoint_path, global_step))
else:
    print('No checkpoint file found')
    return

但是,这仅恢复最新保存的检查点文件。那么如何在所有保存的检查点文件上编写循环?我尝试使用saver.last_checkpoints获取检查点文件列表,但是返回的列表为空。

任何帮助都将受到高度赞赏,提前谢谢!

3 个答案:

答案 0 :(得分:1)

您可以遍历目录中的文件:

import os

dir_path = './' #change that to wherever your files are
ckpt_files = [f for f in os.listdir(dir_path) if os.path.isfile(
    os.path.join(dir_path, f)) and 'ckpt' in f]

for ckpt_file in ckpt_files:
    saver.restore(sess, dir_path + ckpt_file)
    global_step = ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1]
    print('Succesfully loaded model from %s at step=%s.' %
          (ckpt.model_checkpoint_path, global_step))

    # Do your thing

在上面的列表理解中添加更多条件,以便更具选择性:and 'meta' not in f等等,具体取决于该目录中的内容和您拥有的保护程序版本

答案 1 :(得分:1)

最快的解决方案:

tensor2tensor有一个模块utils和一个脚本avg_checkpoints.py,该脚本将平均权重保存在新的检查点中。假设您有一个要平均的检查点列表。您有2种使用方式:

  1. 从命令行

    TRAIN_DIR=path_to_your_model_folder
    FNC_PATH=path_to_tensor2tensor+'/utils/avg.checkpoints.py'
    CKPTS=model.ckpt-10000,model.ckpt-20000,model.ckpt-100000
    
    python3 $FNC_PATH --prefix=$TRAIN_DIR --checkpoints=$CKPTS \ 
        --output_path="${TRAIN_DIR}averaged.ckpt"
    
  2. 通过您自己的代码(使用os.system):

    import os
    os.system(
        "python3 "+FNC_DIR+" --prefix="+TRAIN_DIR+" --checkpoints="+CKPTS+
        " --output_path="+TRAIN_DIR+"averaged.ckpt"
    )
    

作为指定检查点列表和使用--checkpoints参数的替代方法,您可以仅使用--num_checkpoints=10对最后10个检查点取平均值。

如果您不想依赖tensor2tensor

这是一个不依赖tensor2tensor的代码段,但仍可以平均可变数量的检查点(与ted的回答相反)。假设steps是应合并的检查点列表(例如[10000, 20000, 30000, 40000])。

然后:

# Restore all sessions and save the weight matrices
values = []
for step in steps:
    tf.reset_default_graph()
    path = model_path+'/model.ckpt-'+str(step)
    with tf.Session() as sess:
        saver = tf.train.import_meta_graph(path+'.meta')
        saver.restore(sess, path)
        values.append(sess.run(tf.all_variables()))

# Average weights
variables = tf.all_variables()
all_assign = []
for ind, var in enumerate(variables):
    weights = np.concatenate(
        [np.expand_dims(w[ind],axis=0)  for w in values],
        axis=0
    )
    all_assign.append(tf.assign(var, np.mean(weights, axis=0))

然后,您可以继续进行操作,例如,保存平均检查点:

# Now save the new values into a separate checkpoint
with tf.Session() as sess_test:
    sess_test.run(all_assign)
    saver = tf.train.Saver() 
    saver.save(sess_test, model_path+'/average_'+str(num_checkpoints))

答案 2 :(得分:1)

最佳解决方案,请遵循此link

我已经使用了很长一段时间,它很简洁。 您可以根据自己喜欢的度量标准保存模型。 恢复模型时,它将删除较旧的检查点并加载最佳的检查点。

如果将准确性用作度量标准集,则maximum == True可根据最大准确性保存模型。 如果要基于验证损失评估模型,则可以将最大化标志设置为False,以保存验证损失最少的模型。