深度学习中的张量概念
张量本质
张量,就是不同维度数量的矩阵。
二维矩阵在代码的表示中与二维数组差不多,通常是这样的:M = [[1, 2], [1, 2]]
这就是一个两行两列的矩阵。同时也是一个形状为(2, 2)的张量。
所以,形状为(1, 2, 3, 4)的张量,就是一个四维矩阵,其拥有:
- 一个元素
- 上面那个元素中分别含有两个子元素
- 上面那两个子元素中分别含有三个子子元素
- 上面那三个子子元素中分别含有四个数值
广播
使形状不一致(维度数量对不上)的张量进行强制运算
广播规则:从右向左对齐维度,缺失的维度自动补1,大小为1的维度自动复制扩展(也就是说,A + B,如果A缺失了这个维度,那么这个维度的形状会与B的形状一致,而不是1)
- A.shape = (3, 4), B.shape = (4,) → B 自动广播为 (1, 4) → (3, 4)。
- A.shape = (2, 1, 5), B.shape = (3, 5) → B 广播为 (1, 3, 5) → (2, 3, 5)。
这种广播规则在实际运算中的意义是,假设现在有一个二维数组[a, b],而其与一个一维数组[c]进行求和等运算。将该一维数组扩充为[a, c],是用于确保a个数量下的b个元素,可以与同样a个数量下的c个元素进行运算
以注意力运算为例,张量是如何进行运算的
首先设:Q = [batch_size, num_heads, seq_len, head_dim]
这里要结合一下背景信息,即在注意力计算过程中这些维度所代表的实际意义。
- 首先,batch_size是由Trainer初始化时传入的参数。他代表一次性读入显存内的样本数量。如果为1,就代表一次只往显存内读入一条数据。这样一来,第一维度的不同数字代表这一批信息里的第几条样本。第三个维度就是不同样本的序列长度
- 其次,头。头是从CNN延伸过来的一种东西,不同的卷积核在顺序递归(注意力的位置编码解决了顺序问题)的时间步上扫描矩阵,来获取不同维度的信息。含有注意力头的张量运算使得提取序列维度信息的行为可以并行化,不同的头可以提取不同的维度信息。
- 然后,序列长度,这部分就是输入的句词。我将其理解为每个元素就是token,这个维度的形状是多少,就代表有多少token
- 最后,每头维度。768个维度不可能去设置768个头,12个头,每头分担64个维度即可。
如果只聚焦最后两个维度,可以发现,就是一个 大小seq_len * head_dim的二维矩阵,处在(r, c)位置的数值就代表,在序列中第r个token的第c个维度所代表的含义。
在Transformer文章中的公式常看到,是直接QK^T的形式,这里的运算其实就是最后两个维度进行的运算。
如果排除所有的冗余信息,现在就假设只有10个token,10个维度,这么少的数据,是不需要再分批次,再分每个头的维度,就是[Q_len, head_dim] * [head_dim, K_len] 的矩阵相乘,结果是[Q_len, K_len]的矩阵,可以想象,每行是单token,每列也是单token,坐标对应的值,就是他们的相似程度。
所以,运算的本质就是最后两个维度在矩阵乘法,当样本数量变多,token序列增长,维度增加,需要进行分批次、分头这种操作,这两个维度应运而生,只是为了他们方便计算而已
更多推荐
所有评论(0)