基于Conditional Layer Normalization的条件文本生成
By 苏剑林 | 2019-12-14 | 111070位读者 |从文章《从语言模型到Seq2Seq:Transformer如戏,全靠Mask》中我们可以知道,只要配合适当的Attention Mask,Bert(或者其他Transformer模型)就可以用来做无条件生成(Language Model)和序列翻译(Seq2Seq)任务。
可如果是有条件生成呢?比如控制文本的类别,按类别随机生成文本,也就是Conditional Language Model;又比如传入一副图像,来生成一段相关的文本描述,也就是Image Caption。
相关工作 #
八月份的论文《Encoder-Agnostic Adaptation for Conditional Language Generation》比较系统地分析了利用预训练模型做条件生成的几种方案;九月份有一篇论文《CTRL: A Conditional Transformer Language Model for Controllable Generation》提供了一个基于条件生成来预训练的模型,不过这本质还是跟GPT一样的语言模型,只能以文字输入为条件;而最近的论文《Plug and Play Language Models: a Simple Approach to Controlled Text Generation》将$p(x|y)$转化为$p(x)p(y|x)$来探究基于预训练模型的条件生成。
不过这些经典工作都不是本文要介绍的。本文关注的是以一个固定长度的向量作为条件的文本生成的场景,而方法是Conditional Layer Normalization——把条件融合到Layer Normalization的$\beta$和$\gamma$中去。
思路细节 #
Conditional Layer Normalization的想法来源于图像中流行的条件GAN的思路——条件BN(Conditional Batch Normalization),相关内容可以参考《从DCGAN到SELF-MOD:GAN的模型架构发展一览》。条件BN还有一个变种,称之为AdaIN(Adaptive Instance Normalization)。条件BN、AdaIN都是将已有的Normalization方法中的$\beta$和$\gamma$变成输入条件的函数,从而可以通过条件来控制生成的行为。
在Bert等Transformer模型中,主要的Normalization方法是Layer Normalization,所以很自然就能想到将对应的$\beta$和$\gamma$变成输入条件的函数,来控制Transformer模型的生成行为,这就是Conditional Layer Normalization的线索思路。(但目前还没有看到同样思路的工作出现,所以这算是笔者闭门造车出来的新鲜玩意了。)
对于已经预训练好的模型来说,已经有现成的、无条件的$\beta$和$\gamma$了,它们都是长度固定的向量。我们可以通过两个不同的变换矩阵,将输入条件变换到跟$\beta,\gamma$一样的维度,然后将两个变换结果分别加到$\beta$和$\gamma$上去。为了防止扰乱原来的预训练权重,两个变换矩阵可以全零初始化(单层神经网络可以用全零初始化,连续的多层神经网络才不应当用全零初始化),这样在初始状态,模型依然保持跟原来的预训练模型一致。
代码实现 #
直觉上,这种以文本生成为目的的finetune应该要用GPT等自回归预训练模型才能提升效果,但事实上,之前的文章《从语言模型到Seq2Seq:Transformer如戏,全靠Mask》已经表明,哪怕你加载Bert的预训练权重来做生成任务,表现依然良好。所以不管哪种Transformer-based的预训练模型,都可以考虑用来finetune做文本生成模型来。而本文还是以预训练Bert为基础模型进行实验。
至于代码,本文所描述的Conditional Layer Normalization技巧,也已经被集成到笔者所开发的bert4keras中了,现在基础函数build_transformer_model
新增了如下参数:
1、layer_norm_cond:如果该参数非None,则意味着它是一个张量,shape=[batch_size, cond_size],用来作为Layer Normalization的条件;
2、layer_norm_cond_size:如果该参数非None且layer_norm_cond为None,则意味着它是一个整数,自行构建一个shape=[batch_size, layer_norm_cond_size]的输入层作为Layer Normalization的条件;
3、layer_norm_cond_hidden_size:如果该参数非None,则意味着它是一个整数,用于先将输入条件投影到更低维空间,这是因为输入的条件可能维度很高,直接投影到hidden_size(比如768)的话,参数可能过多,所以可以先投影到更低维空间,然后升维;
4、layer_norm_cond_hidden_act:投影到更低维空间时的激活函数,如果为None,则不加激活函数(线性激活);
5、additional_input_layers:额外的输入层,如果外部传入了张量作为条件,则需要把条件张量所依赖的所有输入层都添加进来,作为输入层,才能构建最终的模型。
实验效果 #
介绍再多,其实还不如看例子来得实际。笔者做了两个实验来验证Conditional Layer Normalization的效果。一个是通过情感极性来控制文本生成,也就是情感分类的反问题,这直接通过类的Embedding来作为Layer Normalization的条件;另一个是图像描述生成(Image Caption),通过预训练的imagenet模型将图片编码为一个固定长度的向量作为Layer Normalization的条件。
这两个代码分别放在task_conditional_language_model.py和task_image_caption.py中。
情感文本生成 #
情感文本生成就是用的训练集是笔者之前收集整理的情感分类语料,将输入文本和标签反过来用即可。最后生成的时候按概率随机采样,从而能生成不同的文本。
部分输出:
正面采样:
[u'外观时尚、漂亮、性价比高。', u'外观漂亮,配置均衡,比较满意,性价比高,外观漂亮,性能较高。', u'我是在大学的时候看到这本书的,所以一直在买。书中的作者是林静蕾,她用自己的口吻写出了一个孩子成长中的心路历程,让我看到了她们成长中的不同之处,以及她们成长过程中的不同境界。让我很欣赏!', u'我想这是一本能够告诉读者什么是坏的,而不是教你怎样说话,告诉我什么是错。这里我推荐了《我要讲故事》,这本书是我很喜欢的一本书,我认为它的理由很多,但是,我相信我。如果你从中得到一些改进,或者你已经有了一个明智的决定。', u'我们一家五口住的是标间,大床房,大床的床很舒服;而我们在携程网上订了两套大床房,这个酒店的价格还是比较合理的;但是房间的隔音效果不太理想,有点响的声音;酒店门口的地铁在施工中,不方便;但是酒店的门口的出租车不知道是哪个车的,打车不是很方便;酒店外面的停']负面采样:
[u'不知道是不是因为电池不太好,不是我不喜欢。', u'看了评论才买的. 结果发现不是那么便宜, 价格也不便宜.', u'1、外壳不容易沾手印,不容易洗洗2、屏幕有点旧,不能下载铃声', u'我是7月6日订购了《杜拉拉升职记》并已通过银行付款,为什么订单下了两周多至今还未到货?是收货时间太快了,可能就这么过去了吧?', u'这本书我是在网上先看了一遍,后来我再看了一遍。感觉作者的文笔实在太烂了,特别是在写他的博客时特别别扭,写得很不专业,特别是他写股票时那个情绪调节的小男孩,简直就是自作聪明的样子,简直就是自作聪明的一种表现!']
Image Caption #
Image Caption以COCO数据集为例,这个数据集的图片场景比较丰富一些。另外2017年的challenger.ai也举办过一个图像中文描述生成竞赛,里边也包含了一个不错的数据集(读者自己自行想办法收集),不过图片的场景相对来说单调一些。
部分输出:
image_id: COCO_val2014_000000524611.jpg
url: http://images.cocodataset.org/val2014/COCO_val2014_000000524611.jpg
predict: a train that is sitting on the tracks.
references: [u'A train carrying chemical tanks traveling past a water tower.', u'Dual train tracks with a train on one of them and a water tower in the background.', u'a train some trees and a water tower ', u'Train on tracks with water tower for Davis Junction in the rear.', u'A train on a train track going through a bunch of trees.']image_id: COCO_val2014_000000202923.jpg
url: http://images.cocodataset.org/val2014/COCO_val2014_000000202923.jpg
predict: a baseball game in progress with the batter up to plate.
references: [u'Batter, catcher, and umpire anticipating the next pitch.', u'A baseball player holding a baseball bat in the game.', u'A baseball player stands ready at the plate.', u'Baseball players on the field ready for the pitch.', u'A view from behind a mesh fence of a baseball game.']
文章小结 #
提出了利用Conditional Layer Normalization来将外部条件融入到预训练模型中的思路,其直接应用就是条件文本生成,但其实也不单单可以用于生成模型,也可以用于分类模型等场景(外部条件可能是其他模态的信息,来辅助分类)。最后基于bert4keras给出了代码实现以及两个例子。
转载到请包括本文地址:https://kexue.fm/archives/7124
更详细的转载事宜请参考:《科学空间FAQ》
如果您还有什么疑惑或建议,欢迎在下方评论区继续讨论。
如果您觉得本文还不错,欢迎分享/打赏本文。打赏并非要从中获得收益,而是希望知道科学空间获得了多少读者的真心关注。当然,如果你无视它,也不会影响你的阅读。再次表示欢迎和感谢!
如果您需要引用本文,请参考:
苏剑林. (Dec. 14, 2019). 《基于Conditional Layer Normalization的条件文本生成 》[Blog post]. Retrieved from https://kexue.fm/archives/7124
@online{kexuefm-7124,
title={基于Conditional Layer Normalization的条件文本生成},
author={苏剑林},
year={2019},
month={Dec},
url={\url{https://kexue.fm/archives/7124}},
}
August 24th, 2021
能分享一份pytorch的代码吗
这你得问用pytorch的人。
January 28th, 2022
苏神,additional_input_layers这个参数在set_inputs中赋值给了self.inputs,但是在后续没看到使用这个参数,仅使用了layer_norm_cond这个参数?
既然是additional_input_layers,自然只需要交给self.inputs。
February 10th, 2022
感谢苏老师的分享,有个疑问,就是情感文本生成的那个例子中,模型的输入是啥呢
输入你是想要的情感标签。
December 17th, 2022
你好苏神,想问一下上面这个模型怎么fine-tune的呢?(小白不太确定BERT这种模型怎样做生成类下游任务,希望求教)
我的理解是:给BERT输入一个label,一个句子。然后label被编码到layer-normalization中,句子正常编码输入,对每个位置输入的单词进行处理,在BERT的最后一层的最顶部,通过softmax预测当前位置的输出,但是在下一个位置,仍然用原句子对应位置的单词做为输入进行处理。所有位置通过BERT预测的单词和原输入句子错开一位求loss,...。fine-tune的过程是这样吗?
在预测时,每个位置的输入就取自上一个位置的输出,直到预测出就停止。
预测:
输入label和“[CLS]”,预测第一个字;
输入label和“[CLS]+第一个字”,预测第二个字;
输入label和“[CLS]+第一个字+第二个字”,预测第三个字;
依此类推。
训练:
就是普通的条件语言模型训练方式,输入:label + “[CLS]原句子”,目标:“原句子[SEP]”
懂了,谢谢苏神解答。
还有一个疑惑,我思考为什么把控制条件编码到LN层中就可以实现可控的生成?对于这种办法实现可控的原理想不明白?我想到的解释是把控制信息送给神经网络,通过训练让网络学习到这种可控性?
如果是这样,那么把可控条件做类似token-embedding、segment-embedding一样,把控制信息编码加入到最开始的embedding层,理论上也可以实现“可控”?
你的理解没有错,理论上直接加在embedding也能实现条件生成。只不过不同的加入方式代表了不同的先验,可能存在一定的效果差异而已。