TensorFlow MNIST DCGAN: как настроить функцию потерь?

Я хотел бы создать DCGAN для MNIST самостоятельно в TensorFlow. Тем не менее, я изо всех сил пытаюсь выяснить, как мне установить функцию потерь для генератора. В реализации Keras DCGAN автор использовал небольшой "обходной путь" для этой проблемы: он просто построил 3 модели. Генератор (G), дискриминатор (D) и третий, где он только что скомбинировал G с D, при этом установив способность поезда D к значению false.

Таким образом, он может кормить D реальными изображениями + сгенерированными изображениями, чтобы обучать D и обучать комбинированную модель G+D, потому что потеря D распространяется на G, так как D не обучаем в комбинированной модели G+D.

В TensorFlow я уже построил G и D. Обучение D относительно простое, поскольку мне просто нужно объединить партию реальных обучающих образов MNIST с созданными и вызвать учебную операцию:

session.run(D_train_op,
            feed_dict={x: batch_x, y: batch_y})

В этом примере обучающая операция представляет собой двоичную кросс-энтропию:

tf.losses.softmax_cross_entropy(y, D_out)

... но как мне настроить функцию потерь для G, если у меня нет "сложенной" модели, объединяющей "G и D" в одну, третью модель?

Я знаю, что мне нужно сгенерировать пакет изображений с помощью G, передать их в D, и тогда я смогу получить потерю D... однако вывод G имеет форму (batch_size, 28, 28, 1), Как бы я настроить функцию потерь для G вручную?

Без "обходного пути" для комбинированной модели "G and D" мне придется распространять потерю D, которая имеет выходную форму (batch_size, 1) на выходной слой Г.

Например, если G выполнит некоторую классификацию, это будет не так сложно выяснить... но G выводит изображения. Таким образом, я не могу напрямую отобразить потерю D на выходной слой G.

Нужно ли настраивать третью модель, сочетающую G+D? Или есть способ рассчитать потери для G вручную?

Любая помощь высоко ценится:)

1 ответ

Решение

На этапе обучения генератора вы можете подумать, что в сети также используется дискриминатор. Но чтобы сделать обратное распространение, вы будете учитывать только веса генератора. Хорошее объяснение этому можно найти здесь.

Как упоминалось в оригинальной статье, стоимость дискриминатора составляет:

А стоимость генератора составляет:

Конечно, вам не нужно рассчитывать это вручную. Tensorflow уже справляется с этим. Чтобы сделать весь процесс, вы можете реализовать следующее:

G_sample = generator(z)
D_real = discriminator(X)
D_fake = discriminator(G_sample)

D_loss = tf.reduce_mean(-tf.log(D_real)-tf.log(1-D_fake))
G_loss = tf.reduce_mean(-tf.log(D_fake))

где D_real, D_fake и D_sample - последние уровни вашей сети. Тогда вы можете реализовать тренировочный процесс стандартным способом:

D_solver = (tf.train.AdamOptimizer(learning_rate=0.0001,beta1=0.5)
            .minimize(D_loss, var_list=theta_D))
G_solver = (tf.train.AdamOptimizer(learning_rate=0.0001,beta1=0.5)
            .minimize(G_loss, var_list=theta_G))

И просто запустите решатели на сессии.

Другие вопросы по тегам