最近我学到了Generative Adversarial Networks .
为了训练发电机,我对它的学习方式感到困惑 . Here是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()`
所以它计算了发电机的损耗,正如文中提到的那样 . 但是,它根据Discriminator输出调用Generator向后功能 . 鉴别器输出只是一个数字(不是数组) .
但是我们知道,一般来说,为了训练网络,我们在最后一层计算一个损失函数(最后一层输出和实际输出之间的损失)然后我们计算梯度 . 因此,例如,如果输出是64 * 64,那么我们将它与64 * 64图像进行比较,然后计算损耗并进行反向传播 .
但是,在我在Generative Adversarial Networks中看到的代码中,我看到它们从鉴别器输出(这只是一个数字)计算发生器的损耗,然后它们调用Generator的反向传播 . 发生器最后一层是例如64 * 64像素,但鉴别器丢失是1 * 1(这与通常的网络不同)所以我不明白它是如何导致生成器被学习和训练的?
我想如果我们连接两个网络(附加Generator和Discriminator)然后调用反向传播但只更新Generators参数,它是有意义的,它应该工作 . 但我在代码中看到的完全不同 .
所以我问这怎么可能?
谢谢