Дискриминатор D и генератор G не будут обучаться параллельно при передаче списка [D_solver, D_loss, clip_D, G_solver, G_loss]
в функцию sess.run()
.Все операции этого списка будут выполнены, но функция Session.run()
не может гарантировать какой-либо порядок выполнения этих операций.Может случиться, что G выполняется перед D или наоборот.
Такое поведение Session.run () обсуждалось в предыдущих выпусках тензорного потока: # 13133 и # 10860 .
Редактировать: добавить ответ на перефразированный вопрос
Если вы дважды наберете sess.run
, как в вашем примере, вы сначала обучите дискриминатор D, а затем генератор G. Если вывызовите sess.run
только один раз, со всеми операциями для D и G в списке fetches
, все операции в этом списке будут выполнены в некотором порядке.Но нет никакой гарантии, в каком порядке это будет.При каждом вызове сначала можно обучить D, затем обучить сначала G или G, а затем D. Функция Session.run()
следует порядку выполнения и не выполняет операции параллельно, т. Е. Графовые операции не выполняются.в то же время.Этот порядок исполнения не обязательно является порядком, который вы передали в fetches=[D_solver, D_loss, clip_D, G_solver, G_loss]
.
Например, рассмотрим второй сценарий, где мы передаем все операции всего за один вызов sess.run()
.На первой итерации обучения может случиться так, что сначала выполняется G_loss
, после этого G_solver
, затем D_solver
и т. Д. На второй итерации мы можем фактически получить, что сначала выполняется D_loss
, затемD_solver
, затем G_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 ...
При таком подходе выне будет шаблона в вашей подготовке.Например, на первой итерации мы обучаем G перед обучением D. На второй итерации мы обучаем D без какого-либо недавнего обновления в G, т. Е. G не обучался между обучением D на итерации 1 и 2.
С другой стороны, при рассмотрении первого сценария, в котором мы последовательно обучаем D и G, мы гарантируем, что на каждой итерации нашего обучения D обучается до G, а метрики для D рассчитываются до обучения G, иметрики для G рассчитываются после обучения D.