• CogView中的单层TransformerLayer


    入门小菜鸟,希望像做笔记记录自己学的东西,也希望能帮助到同样入门的人,更希望大佬们帮忙纠错啦~侵权立删。

    目录

    一、原理

    1、LayerNorm

    2、self attention

    3、残差结构的引入

    4、MLP

    二、代码解析

     1、__init__

    (1)参数设定

    (2)对输出输入层

     (3)Self attention模块初始化

    (4)约束的方法定义——LayerNorm

    (5)MLP定义

    2、forward

    (1)第一层:对输入进行LayerNorm处理

    (2)第二层:自我注意力机制

    (3)第三层:Third LayerNorm

    (4)第四层

    (5)输出层:第二个残差结构


    一、原理

     输入层:hidden state,shape为(b, s, h);最终输出也是(b,s,h);

    若输入有记忆层,则对他进行LayerNorm处理,并送进self attention中发挥作用;

    1、LayerNorm

    简单而言,LayerNorm就是针对每条样本,对每条样本的所有特征做归一化。为的是让当前层的参数稳定下来,避免梯度消失或者梯度爆炸,方便后面的继续学习。

    公式:(其中\epsilon防止分母为0)

    y=\frac{x-E[x]}{\sqrt{\operatorname{Var}[x]+\epsilon}}

    2、self attention

    详见CogView中的Self attention_tt丫的博客-CSDN博客

    3、残差结构的引入

    可以看看深度学习之Resnet详解|CSDN创作打卡_tt丫的博客-CSDN博客_resnet学习中对残差结构的介绍。

    用于解决深度网络的退化问题。

    4、MLP

    详见CogView中的MLP_tt丫的博客-CSDN博客


    二、代码解析

     1、__init__

    (1)参数设定

    1. class GPT2ParallelTransformerLayer(torch.nn.Module):
    2. """A single layer transformer for GPT2.
    3. We use the following notation:
    4. h: hidden size
    5. n: number of attention heads
    6. b: batch size
    7. s: sequence length
    8. Transformore layer takes input with size [b, s, h] and returns an
    9. output of the same size.
    10. Arguments:
    11. hidden_size: The hidden size of the self attention.
    12. num_attention_heads: number of attention head in the self
    13. attention.
    14. attention_dropout_prob: dropout probability of the attention
    15. score in self attention.
    16. output_dropout_prob: dropout probability for the outputs
    17. after self attention and final output.
    18. layernorm_epsilon: epsilon used in layernorm to avoid
    19. division by zero.
    20. init_method: initialization method used for the weights. Note
    21. that all biases are initialized to zero and
    22. layernorm weight are initialized to one.
    23. output_layer_init_method: output layers (attention output and
    24. mlp output) initialization. If None,
    25. use `init_method`.
    26. """
    27. def __init__(self,
    28. hidden_size,
    29. num_attention_heads,
    30. attention_dropout_prob,
    31. output_dropout_prob,
    32. layernorm_epsilon,
    33. init_method,
    34. output_layer_init_method=None,
    35. query_window=128,
    36. key_window_times=6,
    37. scale_normalization=True
    38. ):
    39. super(GPT2ParallelTransformerLayer, self).__init__()
    • hidden_size:自我注意力模块的隐藏大小(嵌入向量的维度);
    • num_attention_heads:自我注意力模块中attention head的数量;
    • attention_dropout_prob:注意力模块中注意力得分被dropout的概率;
    • output_dropout_prob:输出层后的输出被dropout的概率;
    • layernorm_epsilon:在layernform中用于避免被零除的ε(用于防止分母为0);
    • init_method:用于权重的初始化方法(所有偏差均初始化为0,分层形式权重初始化为1);
    • output_layer_init_method:输出层(注意力输出和mlp输出)初始化方法定义。若为None,则用init_method方法;
    • query_window:稀疏处理中的滑动窗口大小;
    • key_window_times:可用于稀疏处理中窗口数目;
    • scale_normalization:是否调用LayerNorm类给第3,4层网络的参数进行一个缩放处理(为了让权重小一点);

    (2)对输出输入层

    对输出层:若output_layer_init_method为None则对输出层权重用init_method方法初始化;

    对输入层:调用LayerNorm类对其进行LayerNorm处理;

    1. # Set output layer initialization if not provided.
    2. if output_layer_init_method is None:
    3. output_layer_init_method = init_method
    4. # Layernorm on the input data.
    5. self.input_layernorm = LayerNorm(hidden_size, eps=layernorm_epsilon)

    LayerNorm类——对网络权重参数进行类归一化并且进一步变小

    1. #对输入的值除以输入中最大绝对值的1/8
    2. class LayerNorm(FusedLayerNorm):
    3. def __init__(self, *args, **kwargs):
    4. super().__init__(*args, **kwargs)
    5. def forward(self, x):
    6. return super().forward(x / (x.abs().max().detach()/8))

    这里引用了apex.normalization.fused_layer_norm中的FusedLayerNorm类,然后forward再对输入的所有值除以输入中最大绝对值的1/8(具体解释见apex.normalization.fused_layer_norm — Apex 0.1.0 documentation

     (3)Self attention模块初始化

    调用GPT2ParallelSelfAttention类进行初始化

    1. # Self attention.
    2. self.attention = GPT2ParallelSelfAttention(
    3. hidden_size,
    4. num_attention_heads,
    5. attention_dropout_prob,
    6. output_dropout_prob,
    7. init_method,
    8. output_layer_init_method=output_layer_init_method,
    9. query_window=query_window,
    10. key_window_times=key_window_times)

    (4)约束的方法定义——LayerNorm

    1. # Layernorm on the input data.
    2. self.post_attention_layernorm = LayerNorm(hidden_size,
    3. eps=layernorm_epsilon)#调用LayerNorm进行权重值的约束
    4. self.scale_normalization = scale_normalization
    5. #是否约束第三,四层网络层的权重
    6. if scale_normalization:
    7. self.third_layernorm = LayerNorm(hidden_size,
    8. eps=layernorm_epsilon)
    9. self.fourth_layernorm = LayerNorm(hidden_size,
    10. eps=layernorm_epsilon)

    (5)MLP定义

    1. # MLP
    2. self.mlp = GPT2ParallelMLP(
    3. hidden_size,
    4. output_dropout_prob,
    5. init_method,
    6. output_layer_init_method=output_layer_init_method)

    2、forward

    1. def forward(self, hidden_states, ltor_mask, pivot_idx=None, is_sparse=0, mem=None):
    2. # hidden_states: [b, s, h] 上一层的输出作为这一层的输入
    3. # ltor_mask: [1, 1, s, s] attention mask矩阵

    (1)第一层:对输入进行LayerNorm处理

    1. # Layer norm at the begining of the transformer layer.
    2. layernorm_output1 = self.input_layernorm(hidden_states)
    3. mem = self.input_layernorm(mem) if mem is not None else None#对记忆模块也进行LayerNorm处理

    (2)第二层:自我注意力机制

    输出大小[b, s, h]

    1. # Self attention.
    2. attention_output = self.attention(layernorm_output1, ltor_mask, pivot_idx, is_sparse, mem)

    (3)第三层:Third LayerNorm

    判断是否对第二层网络层输出的权重进行LayerNorm处理,形成第三层

    1. # Third LayerNorm
    2. if self.scale_normalization:
    3. attention_output = self.third_layernorm(attention_output)

    (4)第四层

    首先构建残差网络:将输出和输入相加作为 output

    1. # Residual connection.
    2. layernorm_input = hidden_states + attention_output

    再对其做LayerNorm处理

    1. # Layer norm post the self attention.
    2. layernorm_output = self.post_attention_layernorm(layernorm_input)

    最后来一波MLP,即做非线性运算变幻,h -> 4*h -> h

    1. # MLP.
    2. mlp_output = self.mlp(layernorm_output)

    判断是否对第四层网络层的权重进行LayerNorm处理

    1. # Fourth LayerNorm
    2. if self.scale_normalization:
    3. mlp_output = self.fourth_layernorm(mlp_output)

    (5)输出层:第二个残差结构

    1. # Second residual connection.
    2. output = layernorm_input + mlp_output
    3. return output

    欢迎大家在评论区批评指正,谢谢大家~

  • 相关阅读:
    电脑查看打印机ip地址的三种方法
    SpringCloud Alibaba - Seata 部署 TC 服务,并集成微服务
    QT常见概念-1
    mybatisplus代码生成覆盖
    deque(双端数组)——STL
    可以说:未来10年这个行业依然值得进,天花板很高,月薪至少3W
    可靠性工程师的发展之路
    Spring【IOC+AOP】待完善....勿看
    compose——布局居中
    windows进程管理相关命令
  • 原文地址:https://blog.csdn.net/weixin_55073640/article/details/126526276