Плохой результат с пакетной нормализацией

Я пытался реализовать DCGan, документ для лица, и заблокирован двумя нижеприведенными проблемами почти для 2 недели. Мы ценим любые предложения. Спасибо.

Проблема 1:

В документе DCGAN предлагается использовать BN (Batch Normalization) как генератор, так и дискриминатор. Но я не мог добиться лучшего результата с BN, чем без BN.

Я скопировал модель DCGAN, которую использовал, которая точно такая же, как и у бумаги DCGAN. Я не думаю, что это из-за переобучения. Потому что (1) он продолжает показывать шум так же, как и исходное изображение шума, и, кажется, никогда не обучался. (2) Значение потерь очень стабильно, так что gan и дискриминатор на самом деле не меняются. (Он остается на уровне 0,6 ~ 0,7 и никогда не ощущается вниз или вверх, как когда обе модели свернуты.) Если я проверю только функцию потерь, похоже, что она хорошо обучается.

Проблема 2:

Когда я использовал float16, он всегда дает мне Nan с моделью ниже. Я изменил эпсилон как 1e-4 1e-3, но не смог. И еще один вопрос. Если я не использую BatchNormalization, это может быть Nan. это имеет смысл, я понимаю. Но если я использую BatchNormalization, он нормализуется на каждом уровне. Даже если результат станет очень большим или очень маленьким, он будет нормализован на каждом слое, так что результат будет почти центрирован и исчезновения не должно произойти. не так ли? на самом деле это моя мысль, но я не знаю, что я неправильно думаю ... пожалуйста, кто-нибудь, помогите мне.

===== Генератор =====

Ввод # (Нет, 128) ‹= скрытый

Плотный # (Нет, 16384)
Пакетная нормализация
LeakyReLU

Изменить форму # (Нет, 4, 4, 1024)

Conv2DTranspose # (Нет, 4, 4, 512)

Пакетная нормализация
LeakyReLU

Conv2DTranspose # (Нет, 8, 8, 256)

Пакетная нормализация
LeakyReLU

Conv2DTranspose # (Нет, 16, 16, 128)

Пакетная нормализация
LeakyReLU

Conv2DTranspose # (Нет, 32, 32, 64)

Пакетная нормализация
LeakyReLU

Conv2DTranspose # (Нет, 64, 64, 32)

Пакетная нормализация
LeakyReLU

Conv2DTranspose # (Нет, 128, 128, 16)

Пакетная нормализация
LeakyReLU

Conv2D # (Нет, 128, 128, 3)

===== Дискриминатор =====

Conv2D # (Нет, 128, 128, 3) LeakyReLU

Conv2D # (None, 64, 64, 16) BatchNormalization
Dropout
LeakyReLU

Conv2D # (Нет, 32, 32, 32)
BatchNormalization
Dropout
LeakyReLU

Conv2D # (None, 16, 16, 64)
BatchNormalization
Dropout
LeakyReLU

Conv2D # (None, 8, 8, 128)
BatchNormalization
Dropout
LeakyReLU

Conv2D # (None, 4, 4, 256)
BatchNormalization
Dropout
LeakyReLU

Conv2D # (None, 2, 2, 512)
BatchNormalization
Dropout
LeakyReLU

Сглаживание
Выпадение
Плотность

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

image_shape => (128, 128, 3)
latent_dim => 128
channels => 3
iterations => 10000
batch_size => 128
epsilon => 0.005
weight_init_stddev => 0.02
beta_1 => 0.5
discriminator_lr => 0.0002
gan_lr => 0.0002

person yongwoo    schedule 14.10.2019    source источник
comment
Возможный дубликат Используется ли Leaky ReLu после партии Нормализация (BN) полезна   -  person Sachin Yadav    schedule 14.10.2019


Ответы (3)


Я не знаю подробностей тезиса DCGAN, но если я изучу его, я могу найти приведенные ниже инструкции по созданию стабильной DCGAN. Почему вы использовали LeakyReLU в Генераторе вместо ReLU?

Рекомендации по архитектуре стабильных глубоких сверточных сетей GAN

  • Замените любые объединяющие слои свертками с поперечным сечением (дискриминатор) и свертками с дробным шагом (генератор).
  • Используйте батчнорм как в генераторе, так и в дискриминаторе.
  • Удалите полностью связанные скрытые слои для более глубоких архитектур.
  • Использовать активацию ReLU в генераторе для всех слоев, кроме выходного, в котором используется Tanh.
  • Используйте активацию LeakyReLU в дискриминаторе для всех слоев
person Wonil    schedule 14.10.2019
comment
Спасибо за внимание к моему вопросу, да, в фейсбуке написано ReLU, и на самом деле это моя ошибка с моим вопросом, но я уже использовал ReLU и потерпел неудачу. LeakyReLU - еще одна моя попытка. - person yongwoo; 14.10.2019

Как мы знаем, псевдокод обучения пакетной нормализации

moving_mean = None;
moving_variance = None;

if not moving_mean:
  moving_mean = current_batch_mean
else:
  moving_mean = moving_mean * momentum + current_batch_mean * (1-momentum)

if not moving_variance:
  moving_variance = current_batch_variance
else:
  moving_variance = moving_variance * momentum + current_batch_variance * (1-momentum)

и вот в чем дело.

По умолчанию импульс tensorflow и keras равен 0,99, и если вы используете его без изменений, следующее значение обновления не влияет на новое обновленное значение. в случае pytorch импульс по умолчанию равен 0,1, что совпадает с 0,9 в тензорном потоке или керасе.

С измененным значением импульса я получил улучшенный результат.

если кто-то испытал такой же симптом, как я, попробуйте уменьшить значение импульса.

Спасибо.

person yongwoo    schedule 17.10.2019
comment
ваше предложение не сработало для меня, но при удалении batchnorm с дискриминатора он работает - person RNs_Ghost; 12.11.2020

Использование SpectralNorm в дискриминаторе и SelfModulationBatchNorm в генераторе. Или используйте ConditionalBatchNorm, если у вас есть этикетка.

Код, справку по другим методам и обучение GAN можно найти здесь

person Mr. For Example    schedule 07.12.2020