BN和LN

Batch Normalization

  1. BN的参数计算是以一个mini batch为组的,每一层的输出$Z= R^{batch\_size,hidden\_size}$在进激活函数之前,针对每一个神经元,即每一个输出$Z_i = R^{batch\_size,1}$做统计归一。统计指标为每个batch的输出的一个维度的均值和方差,对应的会有两个hidden_size维的向量:

    $$\mu_{ Z_i} = \frac{1}{batch\_size} \sum\limits^{batch\_size}_{j=1} Z_{i,j} $$

    $$\sigma_{Z_i}=\sqrt{\frac{1}{batch\_size}\sum\limits_{j=1}^{batch\_size}(\mu_{Z_i} - Z_i)^2} $$

  2. BN的更新
    BN得到两个参数向量后会对该层的输出$Z$做变换,即更新该层的输出到一个合理的分布上。更新分两步,1. 变换到一个均值为0方差为1的分布上(针对的是每一维度)。2. 再做一次平移和缩放操作,这一步是通过一个线性变换得到的,平移参数可学习。两步更新后再过激活函数。

    $$ Z'_i = \frac {Z_i - \mu_{Z_i}}{\sigma_{Z_i}} $$

    $$ Z''_i = gZ'_i+b $$

  3. BN特点:

    • 所有的操作都是在一个维度上进行的,参数的计算依赖于batch_size
    • 倾向于认为同一位置的特征的同一维度的信息应该具有相同的分布,也可以认为同一位置的特征具有相同分布。
    • 因为参数和batch_size相关,batch_size太小会带来分布和整体不一致的问题。故train的batch_size不适宜太小,且需尽量打散,以保证分布和整体接近。
    • 在infer阶段和train阶段会有不一样的策略。infer阶段往往只有一个样本,再去求参数,明显不可行,所以一般会在train阶段迭代的更新$\mu和\sigma$参数,以估计所有训练样本的参数,且存下来,作为infer阶段使用的参数。

Layer Normalization

  1. LN的计算是在单个样本级别上做的normlize。对每一层的输出$Z= R^{batch\_size,hidden\_size}$ 在激活之前,针对每一个样本$Z_j = R^{1,hidden_size}$求参数$\mu 和\sigma$,求取方式和BN类似,只是方向不同。最终batch_size个样本得到batch_size组参数。
  2. LN的更新,依据每个样本的参数逐个更新各个样本的每一维度。然后做同样的缩放和平移。平移参数和缩放参数可学习。
  3. LN特点:

    1. 所有的操作都是在单个样本上计算的,所以不依赖于batch_size,所以不用存储$\mu和\sigma$参数到infer阶段。train和infer一致。
    2. 倾向于认为一个样本内部的所有feature是相似的,可以直接在样本内各个维度上norm。这一假设在nlp任务中比较得到明显。一个句子的各个特征就是各个字词处理后得到的,基本是相似的。但假如输入特征是类似年龄,性别,身高这种多个不同特征concat起来的,再直接求样本内部的norm,由于各个feature的分布不一样,就会存在很大的问题。

对比

  1. BN不太适合NLP任务中的不定长类任务。

    1. 不定长的样本,在靠后位置的有效样本会变少,相当于变相的batch_size在变小。
    2. 在RNN类的循环网络中,越往后相当于样本越长,有效样本越少,BN效果会变差。
    3. 在infer阶段如果一个很长的样本在train阶段没有见过,则会找不到对应的参数。
  2. LN比较适合NLP任务

    1. 变长样本处理起来无问题。
    2. 一个样本的各个特征一般是比较相似的,如一个句子的特征是各个字,concat后,各个维度的分布也是一致的。
    3. 在TF,pytoch等的实现中,LN一般是针对最内层的向量内部做norm参数。如[batch_size,seq_len,hidden_size]这样的一个输出,在LN时,是针对最内层的hidden_size个神经元求参,更是不会和padding的feature起冲突。而BN相当于在一个[batch_size*seq_len,hidden_size]的矩阵上做BN,这时求均值方差时会把padding的样本也算进去。
我来评几句
登录后评论

已发表评论数()

相关站点

热门文章