内容
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)
* 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)。
以下是重要的参数,记录下来,为后面的章节做准备。
文章出处登录后可见!