同一个batch内要padding到一样长度,不同batch之间可以不一样

这一点不仅仅针对 Transformer,对于 (绝大多数) NLP模型都是这样的

同一个batch内要padding到一样长度神经网络

内部大都是矩阵的运算,batch训练,需要矩阵输入因此一个batch要padding到一样的长度,才能形成一个矩阵,像

[[1,2],
 [3,4,5]]

它并不是一个矩阵,矩阵需要每个维度的长度一样才行

不同batch之间可以不一样

一般batch个句子经过embedding层之后,它的维度会变成
[batch_size, seq_length, embedding_size],

不同batch之间padding的长度可以不一样,是因为神经网络模型的参数与 seq_length 这个维度并不相关。

下面从两类常见的模型 RNN/LSTM 和 Transformer 去细致的解释这个问题:

RNN/LSTM

对于RNN/LSTM 等循环神经网络,
seq_length 这个维度只决定 RNN/LSTM 循环计算多少步,而不会影响模型的参数,如下图:
在这里插入图片描述

所以你可能会发现,Pytorch中的 RNN/LSTM 默认是 [seq_length, batch_size, embedding_size] 形式的输入,和常见的 [batch_size, seq_length, embedding_size] 的数据维度形式不一样,因为 RNN/LSTM 每一步处理的其实是 [batch_size, embedding_size] 的数据,然后循环处理 seq_length 次。

关于更细节的 LSTM 内部结构,可以参考:https://zhuanlan.zhihu.com/p/64613239

Transformer

对于Transformer,它的 Self-Attention ,主要参数是 Q K V 三个参数矩阵,每个参数矩阵的维度是 (hidden_size, hidden_size),其中,hidden_size 就等于 embedding_size,所以Q K V 参数矩阵的维度也就是 (embedding_size, embedding_size),这样可以保证从 embedding 到最后输出维度都保持一致。

输入batch个句子中的每一个token,都是乘以同一个 Q K V参数矩阵,再去做 Self-Attention ,所以参数量和参数维度都是和 seq_length 无关的。

另外,在Transformer中,除Q K V 参数矩阵外,其中的 feed forward net, add & norm 都是直接作用在单个token上的,就是有 seq_length 个 token,就作用多少次,当然本质一个矩阵相乘就可以了。

下面是举例 Q 参数矩阵和 FFN 前向线性层的参数定义,可以看到都不会涉及 seq_length 的维度,当然,也不会涉及 batch_size 这个维度,所以一次输入1个句子和 n 个句子都是一样的:

self.query = nn.Linear(config.hidden_size, self.all_head_size)  # query参数矩阵
​
self.dense = nn.Linear(config.hidden_size, config.hidden_size)  # 前向线性层

作者:海晨威
链接:https://www.zhihu.com/question/439438113/answer/2093730877
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐