我正在尝试训练SRGAN。 (超分辨率GAN) 但是,无论输入是什么,鉴别器的输出收敛到0或1。 判别器的损失函数仅为
D_loss = 0.5*(D_net(fake) + 1 - D_net(real))
D_net(fake)
和D_net(real)
都变为0或1。(S型)
我该如何解决?
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]判别器损耗:0.0860产生器损耗:0.1393
批次:[20/6700]判别器损耗:0.0037产生器损耗:0.1282
批次:[30/6700]判别器损耗:0.0009产生器损耗:0.0838
批次:[40/6700]判别器损耗:0.0002产生器损耗:0.0735
批次:[50/6700]判别器损耗:0.0001产生器损耗:0.0648
批次:[60/6700]判别器损耗:0.5000产生器损耗:0.0634
批次:[70/6700]判别器损耗:0.5000产生器损耗:0.0706
批次:[80/6700]判别器损耗:0.5000产生器损耗:0.0691
批次:[90/6700]判别器损耗:0.5000产生器损耗:0.0538 ...
答案 0 :(得分:0)
我不确定我是否正确理解您的问题。您的意思是鉴别器的S形输出是0还是1?
在损失函数let observableBatch= [];
for (let child of childTasksToSave){
observableBatch.push(this.workItemService.createChildWorkItem(parentId, child));
}
Observable.forkJoin(observableBatch).subscribe...;
中,您直接在S型输出上进行优化,并且看起来鉴别器对数据的拟合过度,可以分别准确地预测伪造样本和真实样本为0和1。
在这个问题上,专家建议一些GAN黑客。您可以找到提示和技巧列表here。我建议您使用软标签而不是硬标签(请参见ref)。
您可以使用BCEWithLogitsLoss()并根据软标签而不是硬标签来计算损失。
硬标签和软标签之间的差异:
D_loss = 0.5 * (fake_D_out + 1 - real_D_out)