最近我了解了生成对抗网络。
为了训练生成器,我对它的学习方式感到困惑。下面是 GAN 的实现:
`# train generator
z = Variable(xp.random.uniform(-1, 1, (batchsize, nz), dtype=np.float32))
x = gen(z)
yl = dis(x)
L_gen = F.softmax_cross_entropy(yl, Variable(xp.zeros(batchsize, dtype=np.int32)))
L_dis = F.softmax_cross_entropy(yl, Variable(xp.ones(batchsize, dtype=np.int32)))
# train discriminator
x2 = Variable(cuda.to_gpu(x2))
yl2 = dis(x2)
L_dis += F.softmax_cross_entropy(yl2, Variable(xp.zeros(batchsize, dtype=np.int32)))
#print "forward done"
o_gen.zero_grads()
L_gen.backward()
o_gen.update()
o_dis.zero_grads()
L_dis.backward()
o_dis.update()`
因此,它会计算论文中提到的生成器的损失。但是,它会根据鉴别器输出调用生成器后向函数。鉴别器输出只是一个数字(不是数组)。
但我们知道,一般来说,为了训练网络,我们在最后一层计算损失函数(最后一层输出和实际输出之间的损失),然后计算梯度。例如,如果输出是 64*64,那么我们将其与 64*64 图像进行比较,然后计算损失并进行反向传播。
但是,在我在生成对抗网络中看到的代码中,我看到它们从鉴别器输出(只是一个数字)计算生成器的损失,然后调用生成器的反向传播。生成器的最后一层是例如 64*64 像素,但鉴别器损失是 1*1(这与通常的网络不同)所以我不明白它是如何导致生成器被学习和训练的?
我想如果我们附加两个网络(附加生成器和鉴别器)然后调用反向传播但只更新生成器参数,它是有意义的并且应该可以工作。但是我在代码中看到的完全不同。
所以我问怎么可能?
谢谢