本篇讲述三篇论文
《SeqGAN: Sequence Generative Adversarial Nets with Policy Gradient》
《Adversarial learning for neural dialogue generation》
《Deep Reinforcement Learning for Sequence-to-Sequence Models》
对于文本生成来说一般会有编码器(可以来源于文本,图像和图网络信息),还会有解码器
解码器的loss往往是使用每个词的NLL(negative log likelihood)来获得,而这意味着一旦进行了解码,就没有办法对整句话进行评价了。因此为了解决这个问题,往往使用强化学习的方法。
SeqGANs就使用了强化学习的方法来实现反向传播。中间为了使得生成完整的句子用于Discriminator能够衡量reward,还使用了蒙特卡洛的方法。之所以使用MCTS这主要受限于问题的假设,是没有编码器的文本生成,一开始的生成序列会非常短。这意味着就是生成的结果基本取决于训练的文本,就像是图像中的的人脸数据集就会生成人脸,而油画数据集就会生成油画一样。
对于我来说,最难的部分就在于如何在代码中计算loss,我在SeqGANs的代码中看到这样一段
def batchPGLoss(self, inp, target, reward):
"""
Returns a pseudo-loss that gives corresponding policy gradients (on calling .backward()).
Inspired by the example in http://karpathy.github.io/2016/05/31/rl/
Inputs: inp, target
- inp: batch_size x seq_len
- target: batch_size x seq_len
- reward: batch_size (discriminator reward for each sentence, applied to each token of the corresponding
sentence)
inp should be target with <s> (start letter) prepended
"""
batch_size, seq_len = inp.size()
inp = inp.permute(1, 0) # seq_len x batch_size
target = target.permute(1, 0) # seq_len x batch_size
h = self.init_hidden(batch_size)
loss = 0
for i in range(seq_len):
out, h = self.forward(inp[i], h)
# TODO: should h be detached from graph (.detach())?
for j in range(batch_size):
loss += -out[j][target.data[i][j]]*reward[j] # log(P(y_t|Y_1:Y_{t-1})) * Q
return loss/batch_size
访问代码中的博客http://karpathy.github.io/2016/05/31/rl/, 我确实被惊艳了,作者正好说了我最需要关注的东西,监督学习与强化学习的比较,我确实不敢相信它是如此的2016 (just joking)。
不过蒙特卡洛除了解决这一个问题之外,还解决了一个Reward for Every Generation Step(REGS)的问题,以下是从其他博文中找到的描述
‘’在以往的工作中,D效果非常好而G的效果非常糟糕会带来训练效果的下降。试想一下一个G所有产生的答案都被D驳回了,在这段时间内G的所有反馈都是负反馈,G就会迷失从而不知道向什么方向优化会得到正反馈,所以理想的情况下G和D是交替训练上升的。’’
《Adversarial learning for neural dialogue generation》正是注意到了这一点,对其使用部分片段的评价进行优化。
之后的内容待以后再更新….