GAN, дискриминатор выводит только 0 или 1 - PullRequest
0 голосов
/ 02 мая 2019

Я пытаюсь тренировать SRGAN.(Super Resolution GAN) Однако, выход дискриминатора сходится к 0 или 1, независимо от того, какой вход.Функция потери дискриминатора составляет только

D_loss = 0.5*(D_net(fake) + 1 - D_net(real))

D_net(fake) и D_net(real), оба становятся 0 или 1. (сигмоид)

Как я могу это исправить?

    for epoch_idx in range(epoch_num):
      for batch_idx, data in enumerate(data_loader):
        D_net.zero_grad()
        #### make real, low, fake
        real = data[0]
        for img_idx in range(batch_size):
            low[img_idx] = trans_low_res(real[img_idx])
        fake = G_net(Variable(low).cuda())

        #### get Discriminator loss and train Discriminator
        real_D_out = D_net(Variable(real).cuda()).mean()
        fake_D_out = D_net(Variable(fake).cuda()).mean()

        D_loss = 0.5*(fake_D_out + 1 - real_D_out)
        D_loss.backward()
        D_optim.step()

        #### train Generator

        G_net.zero_grad()
        #### get new fake D out with updated Discriminator
        fake_D_out = D_net(Variable(fake).cuda()).mean()
        G_loss = generator_criterion(fake_D_out.cuda(), fake.cuda(), real.cuda())
        G_loss.backward()
        G_optim.step()

Пакет: [10/6700] Discriminator_Loss: 0.0860 Generator_Loss: 0.1393

Пакет: [20/6700] Discriminator_Loss: 0.0037 Generator_Loss: 0.1282

Пакет: [30/6700] Discriminator_Loss: 0,0009 Generator_Loss: 0,0838

Пакет: [40/6700] Discriminator_Loss: 0,0002 Generator_Loss: 0,0735

Пакет: [50/6700] Discriminator_Loss: 0,0001 Generator_Loss: 0,0648

Batch: [60/6700] Discriminator_Loss: 0.5000 Generator_Loss: 0,0634

Пакет: [70/6700] Discriminator_Loss: 0.5000 Generator_Loss: 0.0706

Пакет: [80/6700] Discriminator_Loss: 0.5000 Generator_Loss: 0.069

Пакет: [90/6700] Discriminator_Loss: 0.5000 Generator_Loss: 0.0538 ...

1 Ответ

0 голосов
/ 04 мая 2019

Я не уверен, правильно ли я понимаю вашу проблему.Вы имели в виду, что сигмоидальный выходной сигнал от дискриминатора равен 0 или 1?

В вашей функции потерь: D_loss = 0.5 * (fake_D_out + 1 - real_D_out), вы напрямую оптимизируете выход сигмоида и похоже, что дискриминатор соответствует вашим данным, что он может точно предсказать 0 и 1 для поддельных и реальных примеров соответственно.

Есть несколько взломов GAN, предложенных экспертами в этой области.Вы можете найти список советов и рекомендаций здесь .Я хотел бы предложить вам использовать мягкие метки, а не жесткие (см. ref ).

Вы можете использовать BCEWithLogitsLoss () и вычислять потери на основе мягкихэтикетки вместо жестких этикеток.

Разница между жесткими и мягкими этикетками:

# hard labels
real = 1
fake = 0

# soft labels
real = np.random.uniform(0.7, 1.0)  # 1
fake = np.random.uniform(0.0, 0.3)  # 0
...