本文思路来源于苏建林大佬的Conditional Layer Normalization,本人整理消化后写的笔记。

如果你有两个相似的任务,比如文本生成,但是要根据指令生成积极的和消极的文本,那么怎么做?如果创建两个模型分别生成就会消耗更多的资源,有没有办法使用一个模型,对其中进行一点更改从而使我们可以规定模型的生成方向呢?答案是有的。

那就是本文的Conditional Layer Normalization(下简称CLN)。模型大概结构如下:

作为对比,这里贴上Layer Normalization(下简称LN)结构:

这里我们可以看到,相比LN,CLN多了两个c和β、γ之间的关联,而c就是对模型的输入,来控制模型输出的方向。c的维度可以和x维度不一致(因为只是简单的输出方向控制,并不需要那么高维度),但是由于需要和x进行计算,仍然需要适配x的768维度,需要使用一层神经网络进行一次变换。而我们可以将其初始化为0,从而在一开始不对原生bert进行任何更改(单层神经网络可以初始化为0,而多层不可以)。

我们观察加了CLN(以c为128维为例)之后的模型结构,相比LN的原生bert,我们发现所有的LN参数变多了:

__________________________________________________________________________________________________
Embedding-Norm (LayerNormalizat (None, None, 768)    198144      Embedding-Position[0][0]
                                                                 reshape[0][0]

由之前的1536(768+768)变为了198144。

由于 β、γ 没有任何变化,还是1536个参数,我们可以分析一下这多出来的196608是从哪来的。

由于我们需要对 β、γ 进行相同的变换,因此参数个数也是相同的,我们分析的参数格式可以进一步缩小为98304个。

而我们之前提到,需要将c的128维度升到768维,如果不考虑bias偏置,只做矩阵变换(没有偏置的单层神经网络实际上就是矩阵变换),恰好是768*128=98304个参数。

我们可以观察代码验证我们的猜想(实际上,我是从代码反向验证上面的参数推理的):

首先是输入,c_in负责输入标签(也就是本例中的情感方向),经过一个embedding后获得我们需要的128维度向量,随后reshape掉一个维度(embedding输出三个维度[batch_size,input_length,output_dim],我们需要两个[batch_size, 128])

c_in = Input(shape=(1,))
c = Embedding(num_classes, 128)(c_in)
c = Reshape((128,))(c)
# Bert模型
model = build_transformer_model(
    config_path,
    checkpoint_path,
    application='lm',
    keep_tokens=keep_tokens,  # 只保留keep_tokens中的字,精简原字表
    layer_norm_cond=c,
    additional_input_layers=c_in,
)

我们现在获得了c向量,然后我们就需要验证我们的参数猜想是否正确了。

我们找到了LN中的build部分:

    def build(self, input_shape):
        super(LayerNormalization, self).build(input_shape)
        if self.conditional:
            shape = (input_shape[0][-1],)
        else:
            shape = (input_shape[-1],)
        if self.center:
            self.beta = self.add_weight(
                shape=shape, initializer='zeros', name='beta'
            )
        if self.scale:
            self.gamma = self.add_weight(
                shape=shape, initializer='ones', name='gamma'
            )
        if self.conditional:
            if self.hidden_units is not None:
                self.hidden_dense = Dense(
                    units=self.hidden_units,
                    activation=self.hidden_activation,
                    use_bias=False,
                    kernel_initializer=self.hidden_initializer
                )
            if self.center:
                self.beta_dense = Dense(
                    units=shape[0], use_bias=False, kernel_initializer='zeros'
                )
            if self.scale:
                self.gamma_dense = Dense(
                    units=shape[0], use_bias=False, kernel_initializer='zeros'
                )

我们可以看到,再初始化了bert和gamma后(center和scale默认都是True),继续初始化了beta_dense和gamma_dense,初始化为shape[0],不使用偏置。而input_shape则是NL的输入,为768维度(CNL只是添加中间过程,并不改变NL输入输出,所以为768).

通过这种方式,我们就可以在LN上进行一些偏移,让模型能够输出不同方向的结果。

结果还算不错:

正面采样:
[
    u'外观时尚、漂亮、性价比高。',
    u'外观漂亮,配置均衡,比较满意,性价比高,外观漂亮,性能较高。',
    u'我是在大学的时候看到这本书的,所以一直在买。书中的作者是林静蕾,她用自己的口吻写出了一个孩子成长中的心路历程,让我看到了她们成长中的不同之处,以及她们成长过程中的不同境界。让我很欣赏!',
    u'我想这是一本能够告诉读者什么是坏的,而不是教你怎样说话,告诉我什么是错。这里我推荐了《我要讲故事》,这本书是我很喜欢的一本书,我认为它的理由很多,但是,我相信我。如果你从中得到一些改进,或者你已经有了一个明智的决定。',
    u'我们一家五口住的是标间,大床房,大床的床很舒服;而我们在携程网上订了两套大床房,这个酒店的价格还是比较合理的;但是房间的隔音效果不太理想,有点响的声音;酒店门口的地铁在施工中,不方便;但是酒店的门口的出租车不知道是哪个车的,打车不是很方便;酒店外面的停'
]
负面采样:
[
    u'不知道是不是因为电池不太好,不是我不喜欢。',
    u'看了评论才买的. 结果发现不是那么便宜, 价格也不便宜.',
    u'1、外壳不容易沾手印,不容易洗洗2、屏幕有点旧, 不能下载铃声',
    u'我是7月6日订购了《杜拉拉升职记》并已通过银行付款,为什么订单下了两周多至今还未到货?是收货时间太快了,可能就这么过去了吧?',
    u'这本书我是在网上先看了一遍,后来我再看了一遍。感觉作者的文笔实在太烂了,特别是在写他的博客时特别别扭,写得很不专业,特别是他写股票时那个情绪调节的小男孩,简直就是自作聪明的样子,简直就是自作聪明的一种表现!'
]

但是我不禁思考,为什么有效呢?苏建林大佬并没有给出解释,我自己思考了一会,感觉就类似于,模型本身是中庸的,通过在LN上进行扰动,使模型的参数输出在中庸左右移动,从而就会产生不同方向的结果。

但是从我仅跑一个epoch来看,效果依然不错,模型生成语句比较连贯(夸bert),采样方向比较精准(夸CLN),而速度上由于新增参数并不多,结构上也不复杂,因此相对bert(LN)没有明显减慢:

正面采样:
['感觉上作传统改进的精灵好!',
'感觉太充实了,没进逛。门口有广场,我喜欢。如果不是需要走马路,就必须很考虑。爽。',
 '性能好,配置上还可以,可以对环境简单控制,速度很快,用起来很舒服,有一款系统面面光驱都可以使用吧',
'介绍书中,一种不是不好,个人的观点地观念,并且也陈述了对于孩子横的解读而只有很严格和严谨的讲解才是清晰了。学习、做事过程的很简单简单、幼稚;可想说是,从孩子的心理编织出的时间。',
'. muamar: vdiv的一篇书,关于于tpc的文章呢,挺精彩的,现在开始读了一点以前的分析的时候的小一短段,总体略感一些,leang我想,handi不会是ン,160《环保符号》. . . . . . . . 携程最为有效的一些客人投诉告诉你们售后:1900元^ _ ; ;']
负面采样:
['也许这两位她写本比较喜欢,大概只是郁闷地说:①你不会曾读那么多词吧~ 呵呵,这样情境没有什么推荐和看。',
'酒店确实挺不错,其中地下总体有点个别建议,其次到当当的时候掏出电脑,直接拍了一下就费了些下三亚的照片,离德里海港近些,以后再不去泰德乐。',
 '我觉得reitslieve的seamark markagen not not workmark in you office this and good me youryve, you have lock住inulit. . reinforce, do do trere you take to the other rechelit-melvin+wiseoooler, are why room set in. mendodoposted',
'摸了一阵子才开始在我们手中看团队的人。巴地马混水道和天一笔账。果然把译写成酒店。忽然看到网上列出的很多牌子照片的香懑木木。下次还是希望买深度适性的好电脑吧。',
'买回来后发现这本书是男生读的, 完全是虐心, 心中很的无奈, 也有很多动摇, 好像书是有情色的一样, 后来发现自己就懒得出书看, 也就只买了一本, 现在已经纸张松软、有感觉.']

2 条评论

Shalltear · 2023-02-24 11:07

Google Chrome 110.0.0.0 Google Chrome 110.0.0.0 Mac OS X  10.15.7 Mac OS X 10.15.7
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36

请问hidden_dense作用是什么啊

    Sniper · 2023-02-25 14:40

    Google Chrome 110.0.0.0 Google Chrome 110.0.0.0 Mac OS X  10.15.7 Mac OS X 10.15.7
    Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36

    128->768

发表回复

Avatar placeholder

您的电子邮箱地址不会被公开。 必填项已用*标注