【发布时间】:2017-11-27 11:24:24
【问题描述】:
最近我了解了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()`
因此,它会计算论文中提到的生成器的损失。 但是,它会根据鉴别器输出调用生成器后向函数。鉴别器输出只是一个数字(不是数组)。
但我们知道,一般来说,为了训练网络,我们会在最后一层计算损失函数(最后一层输出和实际输出之间的损失),然后计算梯度。例如,如果输出是 64*64,那么我们将其与 64*64 的图像进行比较,然后计算损失并进行反向传播。
但是,在我在生成对抗网络中看到的代码中,我看到它们根据鉴别器输出(只是一个数字)计算生成器的损失,然后调用生成器的反向传播。生成器的最后一层是例如 64*64 像素,但鉴别器损失是 1*1(这与通常的网络不同)所以我不明白它是如何导致生成器被学习和训练的?
我想如果我们附加两个网络(附加生成器和鉴别器)然后调用反向传播但只更新生成器参数,这是有意义的并且应该可以工作。但我在代码中看到的完全不同。
所以我在问怎么可能?
谢谢
【问题讨论】:
-
你的问题不是很清楚,但是看看这是否有帮助。鉴别器是一个普通的分类器,它以图像为输入,对它的真假进行分类。真实数据来自训练集,假数据来自生成器。所以判别器是根据这两个输入来学习的。对于生成器的情况,它必须欺骗鉴别器,因此将生成器的输出馈送到鉴别器,并通过将鉴别器的输出设置为非假来学习生成器。这里只学习生成器。
-
谢谢。对不起我的坏问题。我的问题只是关于代码。我清楚地理解算法。我的问题是:为了训练生成器,我们必须将损失从鉴别器反向传播到生成器,但不更新鉴别器参数。但是,在代码中,我只看到他们使用鉴别器输出(损失)并且没有通过鉴别器反向传播,他们将其发送到生成器。我的错误是什么?
-
我对此并不完全确定,但我明白你的意思。如果反向传播确实通过了鉴别器(因为我们需要扩大规模),这对我来说是有意义的,但是,权重更新仅应用于网络的生成器部分
标签: machine-learning neural-network deep-learning generative