Informer pytorch 代码解读(1)Encoder

Informer pytorch 代码解读(1)Encoder,第1张

目录

0.对整体的架构进行分析

整个架构和Transformer是差不多的,但是Encoder层有堆叠,对Encoder进行分析发现,他整个部分的结构大体分为

(1)白色的部分,稀疏注意力的计算。


(2)蓝色的卷积层,进行信息的提取。


1.整个Informer的部分的代码如下主要由三个部分组成

(1)红色部分是词编码

(2)绿色部分是Encoder

(3)蓝色部分是Decoder​

2.对于encoder

3.Conv_layer部分


0.对整体的架构进行分析 整个架构和Transformer是差不多的,但是Encoder层有堆叠,对Encoder进行分析发现,他整个部分的结构大体分为 (1)白色的部分,稀疏注意力的计算。


(2)蓝色的卷积层,进行信息的提取。


 对Encoder部分进行展开如下图。


1.整个Informer的部分的代码如下主要由三个部分组成 (1)红色部分是词编码 (2)绿色部分是Encoder (3)蓝色部分是Decoder 2.对于encoder

红色部分的代码时EncoderLayer层,也就是主要的attention的计算层。


绿色部分是卷积层,主要是进行信息的提取和维度的变短。


 

 

 

查看Encoder包括的attn_layer的信息,发现attn_layer就是一个EncoderLayer,而一个EncoderLayer还包括一个注意力的计算和两个卷积层,以及两个标准化层和dropout层,两个卷积是512 - 2048 - 512 所以一个EncoderLayer层对于向量来说维度是不变的,在接下来也会有体现。


但是Encoder还包括一个额外的卷积层也就是上图的绿色的部分,经过绿色的卷积层维度会变化 ,在接下来的代码中也会有体现。


一个Encoder包括两个EncoderLayer和一个卷积层,这个卷积层的数量是比EncoderLayer层的数量少一个的。


 

 这时候传入的x的维度是(32,96,512),来计算attention。


 进入atten.py来进行详细的计算

 到达红色部分的时候query和keys以及values的尺度都是由

(32,96,512)-》(32,96,8,64)规范的格式是(32,96,H,d model / H)也就进行了分多头

 这里传入的queries,keys以及values都是(32,96,8,64)的维度的。


而经过transpose过后的都是(32,8,96,64)维度的。


因为这里传入的都是encoder的输入,所以queries和keys都是一样的,所以L_Q和L_K也都是一样的,都是96的长度。


U_part是对L_K进行log得到的是25,u是对L_Q进行log,得到的也是25。


 接下来进行到了红色的这部分也就是前期的log以及queries和keys的准备工作都完成了,下面开始进行prob_QK的计算。


传入的数据:

scores_top, index = self._prob_QK(queries, keys, sample_k=U_part, n_top=u),queries和keys都是原始的queries和keys,而sample_K是抽样出来为了计算n_top的K,sample_K是为了n_top来服务的。


 接下来进入prob_QK的计算工作,前面都是在为了prob_QK的计算做参数的准备。


这里传入的Q,K的维度都是(32,8,96,64)

(1) K_expand = K.unsqueeze(-3).expand(B, H, L_Q, L_K, E) 这一步得到K_expand,是(32,8,96,96,64)的维度的
(2) index_sample = torch.randint(L_K, (L_Q, sample_k)) 这一步得到的index_sample的维度是(96,25)的维度
(3) K_sample = K_expand[:, :, torch.arange(L_Q).unsqueeze(1), index_sample, :],这里不知道用的什么原理,传入的index_sample是一个随机的数组,但是将这个index_sample传入了这个K_expand的第三个维度,将一个二维的传入了第三个维度,使用jupter发现,只是利用了这个的维度来进行sample,并没有说利用里面的数据来对K_expand进行产生实质的影响。


这里出来的K_sample的维度是(32,8,96,25,64) (4) Q_K_sample = torch.matmul(Q.unsqueeze(-2), K_sample.transpose(-2, -1)).squeeze(-2)在这里,Q.unsqueeze(-2) 使得Q由(32,8,96,64)=(32,8,96,1,64)K_sample.transpose(-2, -1),使得K_sample由(32,8,96,25,64)变成了(32,8,96,64,25)进行matmul之后变成了(32,8,96,1,25),然后squeeze(-2)后变成了(32,8,96,25)所以最后乘出来的Q_K_sample就变成了(32,8,96,25)而如果利用原始的Q和K进行相乘应该是(32,8,96,64)的,所以还需要进行下一步的处理。


(5) M = Q_K_sample.max(-1)[0] - torch.div(Q_K_sample.sum(-1), L_K)     M_top = M.topk(n_top, sorted=False)[1] Q_reduce = Q[torch.arange(B)[:, None, None], torch.arange(H)[None, :, None], M_top, :]经过这步之后, * torch.div()方法将输入的每个元素除以一个常量,然后返回一个新的修改过的张量   * M_top = 32 * 8 *25 topK是得到前k个以及其索引然后得到reduce后的Q,也就是Q_reduce(6) Q_K = torch.matmul(Q_reduce, K.transpose(-2, -1)) 得到乘出来的稀疏的Q_K,这个Q_K是(32,8,25,96)维度的。


(3)对应的图如下,发现,只是利用了他的维度??并没有对a里面的数据产生影响 

 

 接下来进入到绿色的部分,传入的是values和L_Q,也就是原始的编码和96这个长度。


 

cumsum的用法如下:

 

 

这里context_in, V, scores, index, L_Q, attn_mask的维度,分别是:
context_in:(32,8,96,64)
V:(32,8,96,64)
scores:(32,8,25,96)
index:(32,8,25)
L_Q:{int} 96 
attn_mask:None
(1)attn = torch.softmax(scores, dim=-1),这一步是对之前的scores进行softmax,经过softmax的矩阵的维度还是(32,8,25,96)
(2)context_in[torch.arange(B)[:, None, None],
           torch.arange(H)[None, :, None],
           index, :] = torch.matmul(attn, V).type_as(context_in)

        *(tensor1.type_as(tensor2)将1的数据类型转换为2的数据类型,这里的输出的context_in的                        维度是(32,8,96,64)。


到了这里,这个

out = out.transpose(2,1).contiguous(),out的维度是(32,8,96,64),再下一步。


out = out.view(B, L, -1),到了这里,这个out的维度就是(32,96,512)的维度的了。


 再接下来就出到了EncoderLayer层的这个红色部分,

(1)x = x + self.dropout(new_x) 这个nex_x是做过稀疏矩阵相乘的attention,而x是原来的词编码,所以这一步类似于残差神经网络?
(2)这一步将x进行标准化得到(标准化的x)和y,然后对y进行卷积,激活和卷积,再将(标准化的x)和(卷积后的y-》激活的y-》卷积的y)和(标准化的x)进行相加得到(x+y)然后再将(x+y)进行标准化后进行输出。


y = x = self.norm1(x) #y (32,96,512) y = self.dropout(self.activation(self.conv1(y.transpose(-1,1)))) #(32,2048,96) y = self.dropout(self.conv2(y).transpose(-1,1)) #(32,96,512) return self.norm2(x+y), attn

3.Conv_layer部分

接下来又进入到了Encoder层,到了conv_layer的部分,

 到了这一层的ConvLayer层,输入的x的维度是(32,96,512)经过卷积后的x输出的维度是(32,48,512),所以经过这一层卷积是将x的维度变短了一半。


 经过Encoder这一个class的return的x的维度是(32,48,512)

 然后就到了Informer层的部分,红色部分是执行过的东西。


这里enc_out的输出的维度是(32,48,512)。


对比之前的词向量的输入,(32,96,512)在第二个维度上减少了一半。


总结一下,即经过稀疏注意力层(32,96,512)->(32,96,512)而经过卷积层则变成了(32,48,512)。


 这里是重要的参数,记录一下为下面的部分做准备。


 

 

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/577789.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-11
下一篇 2022-04-11

发表评论

登录后才能评论

评论列表(0条)

保存