Tensorflow:是否可以在检查点中修改全局步骤

che*_*chi 2 python machine-learning tensorflow

我正在尝试修改global_step检查点中的内容,以便可以将培训从一台机器移至另一台机器。

假设我在机器A上进行了几天的训练。现在,我购买了具有更好图形卡和更多GPU内存的新机器B,并希望将训练从机器A转移到机器B。

为了恢复机器B中的检查点,我之前已经在机器A中指定了global_stepin Saver.save,但是大小batch_size越来越小sub_iterations

batch_size=10
sub_iterations=500
for (...)
    for i in range(sub_iterations):
        inputs, labels = next_batch(batch_size)
        session.run(optimizer, feed_dict={inputs: inputs, labels: labels})

saver = tf.train.Saver()
saver.save(session, checkpoints_path, global_step)
Run Code Online (Sandbox Code Playgroud)

现在,我将包括检查点在内的所有文件从机器A复制到机器B。由于机器B具有更多的GPU内存,因此我可以将修改batch_size为更大的值,但使用更少的sub_iterations

batch_size=100
sub_iterations=50 # = 500 / (100/10)
for (...)
    for i in range(sub_iterations):
        inputs, labels = next_batch(batch_size)
        session.run(optimizer, feed_dict={inputs: inputs, labels: labels})
Run Code Online (Sandbox Code Playgroud)

但是,由于global_step机器B中的不同,我们无法直接还原复制的检查点。例如,由于机器B中减少的数量,tf.train.exponential_decay将产生不正确的检查点。learning_ratesub_iterations

learning_rate = tf.train.exponential_decay(..., global_step, sub_iterations, decay_rate, staircase=True)
Run Code Online (Sandbox Code Playgroud)

是否可以修改global_step检查点中的?还是有替代的但更合适的方式来处理这种情况?

编辑1

除了计算之外learning_rate,我还使用了global_step来计算并减少迭代次数。

while i < iterations:
    j = 0

    while j < sub_iterations:
        inputs, labels = next_batch(batch_size)
        feed_dict_train = {inputs: inputs, labels: labels}
        _, gstep = session.run([optimizer, global_step], feed_dict=feed_dict_train)
        if (i == 0) and (j == 0):
            i, j = int(gstep/ sub_iterations), numpy.mod(gstep, sub_iterations)
        j = j + 1
    i = i + 1
Run Code Online (Sandbox Code Playgroud)

并且我们将从new ij。开始迭代。请对此发表评论,因为这可能不是恢复检查点并从已加载的检查点继续进行训练的好方法。

编辑2

在机器A,假设iterations为10000,sub_iterations是500和batch_size10。因此,我们的目标是列车批次总数为10000x500x10 = 50000000。假设我们已经训练了几天并global_step成为501。因此,训练的批次总数为501x10 =5010。未训练的剩余批次数目为5011至50,000,000。如果我们应用i, j = int(gstep/ sub_iterations), numpy.mod(gstep, sub_iterations),则最后训练的值为i501/500 = 1,并且j为501%500 = 1。

现在,您已将所有文件(包括检查点)复制到计算机B。由于B具有更多的GPU内存,并且我们可以为一个子迭代训练更多的批次,因此我们将其设置batch_size为100,并调整sub_iterations为50,但保留iterations为10000。培训的批次数量仍为5000万。因此问题来了,我们如何才能开始对5011到50,000,000的批次进行培训,而又不对前5010个样本进行培训?

为了从机器B中的5011开始并训练批次,我们应该设置i为1和j0,因为它训练的总批次为(1 * 50 + 0)* 100 = 5,000,接近5,010(因为batch_size在机器B中是100,而在机器A中是10,我们不能从5,010开始,我们可以选择5,000或5,100。

如果不进行调整global_step(如@ coder3101所建议),并i, j = int(gstep/ sub_iterations), numpy.mod(gstep, sub_iterations)在机器B中重新使用,i将变为501/50 = 10,j并将变为501%50 = 1。因此,我们将从批次50,100(= 501 * batch_size= 501 * 100)开始并进行训练,这是不正确的(不接近5010)。

i, j = int(gstep/ sub_iterations), numpy.mod(gstep, sub_iterations)之所以引入此公式,是因为如果我们停止在机器A上进行训练,则可以使用该公式恢复检查点并继续在机器A中进行训练。但是,当我们将训练从机器A移到机器B时,似乎该公式不适用。因此,我希望修改global_stepin检查点以应对这种情况,并想知道是否可能。

che*_*chi 5

是。有可能的。

要修改global_step机器B中的机器,您必须执行以下步骤:

计算相应 global_step

在上面的示例中,global_step在机器A中为501,受训批次的总数为501x10 = 5010。因此global_step,机器B中的对应值为5010/100 = 50。

修改检查点文件名

修改的后缀model_checkpoint_pathall_model_checkpoint_paths值使用正确的步数在/检查点(在上述的例子例如,50)。

修改检查点的索引,元数据和数据的文件名以使用正确的步骤号。

global_step恢复检查点后覆盖

saver.restore(session, model_checkpoint_path)
initial_global_step = global_step.assign(50)
session.run(initial_global_step)
...
# do the training
Run Code Online (Sandbox Code Playgroud)

现在,如果你恢复检查站(含global_step),并覆盖global_step,培训将使用更新global_step和调整i,并jlearning_rate正确。