当前位置:   article > 正文

VIT学习(二)_vit自注意力机制

vit自注意力机制

前言

        以下内容为小白学习vit内容记录,如理解有误,望帮助指出修正。基于Paddle框架学习,aistudio课程即可学习。此次记录课程里视觉问题中的注意力机制小节的学习内容


一、注意力机制

        课程中注意力机制从NLP的方向为我们举例,我直接从公式开始。假设有三个image token输入,输入在中间会经过一次权重矩阵维度(out = proj * x)相乘变化,随着proj权重矩阵维度的不一样输出的维度也会跟着变化。得到的结果(Vi)再与注意力权重(a1—a3)运算求和,这就是注意力机制。

二、VIT中的注意力

        

        为了模型的复杂性、深度更深(为了它更强),在简单的注意力机制上,变得复杂一些。依旧输入image tokens,一个输入不只经过一次权重矩阵,而是经过三个,得到(v1、k1、q1),注意力权重经过K 、Q的点积得出。在计算X1的注意力时,C1 = a1 * v1 + a2 * v2 + a3 * v3 (注意力计算公式),此时注意力权重使用自己的q1与其他的K 做点积得到用于计算X1的注意力权重(a1、a2、a3)。同理X2,注意力权重使用X2的q2与其他的K做点积得到用于计算X2的注意力权重,再将权重带入公式就可以对每一个patch image进行计算(如下图展示)。

        Wq、Wk、Wv是权重矩阵,是可学习的。

        image token经过权重矩阵后,就开始计算每一个token的注意力。

 

        这里对注意力权重再做了一次计算,在原来点积后的结果除于根号下Dk(dk是embedding的数值,如果是Multi--Head self attention,dk是embedding // num_head的数值),再经过softmax的结果,用于最后注意力计算时的注意力权重。

二、Multi--Head self attention

        课程中对于Multi--Head self attention的讲解,结合代码展示的代码感觉不是很相符合。课上的理解就是把原来的image token经过的权重矩阵,复制几个维度一致的矩阵(矩阵权重不一致)这样就可以产生多个的qkv去计算注意力,对多个qkv计算的注意力经过一个权重矩阵变化得到最后的结果。

         后来看了一个大佬写的解释感觉更符合实际代码过程。把原来计算的qkv均分成多个,一组一组的qkv去计算注意力(步骤和前面的过程一致)。大佬文章(下图取自大佬的文章)

三、attention代码

      代码是自己看完视频参考写的,如果有误可以指出修改。

  1. import paddle
  2. import paddle.nn
  3. class Atten(paddle.nn.Layer):
  4. def __init__(self,embed_dim,head_dim,dropout=0.):
  5. super(Atten, self).__init__()
  6. self.head_dim = embed_dim//self.head_dim
  7. self.qkv = paddle.nn.Linear(embed_dim,int(3*embed_dim))
  8. self.dropout = paddle.nn.Dropout(dropout)
  9. self.scale = self.head_dim ** -0.5
  10. self.proj = paddle.nn.Linear(embed_dim,embed_dim)
  11. self.softmax = paddle.nn.Softmax(-1)
  12. def forward(self,x):
  13. batchsize,num_patch,embedding_dim = x.shape
  14. qkv = self.qkv(x)
  15. #[4, 16, 288]
  16. qkv = qkv.reshape((batchsize,num_patch,3,embedding_dim//self.head_dim,-1)).transpose((2,0,4,1,3))
  17. q,k,v = qkv[0],qkv[1],qkv[2]
  18. attn = paddle.matmul(q, k, transpose_y=True)
  19. attn = self.scale * attn
  20. attn = self.softmax(attn)
  21. attn = self.dropout(attn)
  22. out = paddle.matmul(attn, v)
  23. out = out.transpose([0, 2, 1, 3])
  24. out = out.reshape([batchsize, num_patch, -1])
  25. out = self.proj(out)
  26. out = self.dropout(out)
  27. return out
  28. def main():
  29. ## [batchsize,num_patch,dim_embed]
  30. t = paddle.randn((4,16,96))
  31. model = Atten(96,8)
  32. out = model(t)
  33. print(out.shape)
  34. if __name__ =='__main__':
  35. main()

总结

        正在入门深度学习,其中的理解与解释比较牵强,后面会不断学习此课程,学习记录。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小桥流水78/article/detail/764283
推荐阅读
相关标签
  

闽ICP备14008679号