日期:2023-04-24 01:32:52 来源:哔哩哔哩
教程简介及目录见: 从零实现BERT、GPT及Difussion类算法:文章简介及目录
本章完整源码见https://github.com/firechecking/CleanTransformer/blob/main/CleanTransformer/transformer.py
【资料图】
这一章将参考《attention is all you need》论文,实现Multi-head Attention、LayerNorm、TransformerBlock,有了这章的基础后,在下一章就可以开始搭建Bert、GPT等模型结构了
参考:https://arxiv.org/abs/1706.03762
Attention介绍(选读)
先简单介绍下一般性的Attention,如果已经了解的同学可以跳过
Attention字面意思是注意力,也就是让模型能够学习到一个权重,来将输入选择性的传入下一层
比较常用的操作如下:
首先假定输入tensor为q, k, v,其中
self-attention是attention的一个特例:q=k=v
以下给出基础attention的伪代码
Multi-head Attention基础原理
由以上论文截图可知,
所以实现步骤如下(可以和上文基础Attention对比着看):
对Q,K,V进行Linear:得到新的Q、K、V的size不变
Multi-Head拆分:
使用Q、K计算Weight(其中第二行是Transformer在attention基础上增加的一个scaling factor)
使用Weight和V,计算新的V
对V进行维度变换
Multi-head Attention实现代码
代码不是太复杂,结合上文和注释,应该能很容易看懂
参考
https://arxiv.org/abs/1607.06450
https://arxiv.org/abs/1607.06450
https://pytorch.org/docs/stable/generated/torch.nn.LayerNorm.html
https://blog.csdn.net/xinjieyuan/article/details/109587913
BatchNorm与LayerNorm的差异
batch normalization
对每一个输入,先在mini-batch上计算输入的均值、标准差,然后当前层的每个输入值使用均值、标准差进行正则计算
公式如下
先在mini-batch上计算出每个位置的均值、标准差,其中为mini-batch大小
然后对每个值应用变换
提示:这里之所以有下标i,是因为batch normalization是在batch内,对不同样本的相同位置进行归一
layer normalization
batch normalization是在batch内,对不同样本的相同位置进行归一;而layer normalization是在layer内,对同一个样本的不同位置进行归一
batch normalization不在整个mini-batch上计算均值、标准差,而是在当前层的当前样本计算输入的均值、标准差,然后对当前层的当前样本输入值使用均值、标准差进行正则计算(也可以理解为Layer Normalization是和batch无关,而是对每个样本单独处理)
公式如下
先在单个样本上计算出每一层的均值、标准差,其中为当前layer的大小hidden units数量
然后对每个值应用变换
Layer Normalization代码实现
代码如下
eps为一个较小值,是为了防止标准差std为0时,0作为除数
从上文公式看出,标准差是计算的均值后开根号,所以代码中有std = self._mean((x - mean).pow(2) + self.eps).pow(0.5),是复用了self._mean()的计算均值操作
为了和pytorch的LayerNorm保持一致,这里同样可以接受normalized_shape参数,表示Normalization要在哪几个维度上进行计算,可以结合_mean()函数中的代码进行理解
参考
https://arxiv.org/abs/1706.03762
Transformer原理
从《Attention Is All You Need》论文中这张图可以看出以下几点信息:
Encoder、Decoder基本相同,最大差别是Decoder上多了一层Multi-Head Attention
每一个TransformerBlock只由Multi-Head Attention、Add、LayerNorm、Linear这4种操作组合而成
在上文已经实现的Multi-Head Attention、LayerNorm基础上,再来实现TransformerBlock就很简单了
为进一步简化,在本章我们先只实现Encoder,并且省略掉mask等额外操作。到之后讲到GPT时再来实现Decoder以及更完善的TransformerBlock
Transformer代码实现
代码主要由attention+Add+Norm,以及FFW+Add+Norm这2个部分组成,其中ffw是两层全连接中间夹一个ReLU激活函数
从以上代码看出TransformerBlock还是非常简洁的,而Bert、GPT等模型就是对TransformerBlock的堆叠,这部分内容将放在下一章讲解
标签:
上一篇:【独家】梭边鱼是不是很脏_梭边鱼
下一篇:最后一页