0

通常在使用 TensorFlow 的 GAN 代码中,我们有以下形式:

 _, D_loss_curr, _ = sess.run(
            [D_solver, D_loss, clip_D],
            feed_dict={X: X_mb, z: sample_z(mb_size, z_dim)}
        )

 _, G_loss_curr = sess.run(
        [G_solver, G_loss],
        feed_dict={z: sample_z(mb_size, z_dim)}
    )

这可以看作是先训练判别器(D),然后训练生成器(G)。但是,如果我们执行以下操作会怎样:

 _, D_loss_curr, _ ,_, G_loss_curr= sess.run(
                [D_solver, D_loss, clip_D,G_solver, G_loss],
                feed_dict={X: X_mb, z: sample_z(mb_size, z_dim)}
            )

现在是否意味着 D 和 G 正在并行训练?还是和以前相比,G 现在已经“过时”了 D?

4

1 回答 1

0

[D_solver, D_loss, clip_D, G_solver, G_loss]将列表传递给 function时,鉴别器 D 和生成器 G 不会被并行训练sess.run()。该列表的所有操作都将被执行,但该函数Session.run()不能保证这些操作的执行顺序。可能会发生 G 在 D 之前执行,反之亦然。

Session.run()的这种行为在之前的 tensorflow 问题中讨论过:#13133#10860

编辑:为改写的问题添加答案

如果您调用sess.run两次,如在您的示例中,您将首先训练鉴别器 D,然后是生成器 G。如果您sess.run只调用一次,并且 D 和 G 的fetches所有操作都在 list 中,那么该列表中的所有操作都将在一些命令。但不能保证它将是哪个顺序。在每次调用时,可以先训练 D,然后训练 G,或者可以先训练 G,然后训练 D。函数Session.run()遵循执行顺序,不会并行运行操作,即图操作不会同时执行时间。这个执行顺序不一定是你传入的顺序fetches=[D_solver, D_loss, clip_D, G_solver, G_loss]

例如,考虑第二种情况,我们在一次调用中传递所有操作sess.run()。在您的第一次训练迭代中,可能会G_lossG_solver执行,然后执行,然后D_solver等等。在第二次迭代中,我们实际上可能会D_loss先执行,然后执行D_solverG_solver等等。

sess.run每次迭代执行的执行顺序示例(不带clip_D): 迭代 1:G_loss、G_solver、D_solver、D_loss
迭代 2:D_loss、D_solver、G_solver、G_loss
迭代 3:G_solver、G_loss、D_loss、D_solver
迭代 4:G_solver、G_loss , D_loss, D_solver ...

使用这种方法,您的训练中不会有模式。例如,在第一次迭代中,我们在训练 D 之前训练 G。在第二次迭代中,我们在 G 最近没有任何更新的情况下训练 D,即在迭代 1 和 2 的 D 训练之间没有训练 G。

另一方面,在考虑顺序训练 D 和 G 的第一个场景时,我们保证在每次训练迭代中,D 在 G 之前训练,并且 D 的指标在 G 的训练之前计算,并且指标对于 G 是在 D 的训练之后计算的。

于 2018-12-17T16:58:43.837 回答