深度学习张量的秩、轴和形状
秩、轴和形状是在深度学习中我们最关心的张量属性。
- 秩
- 轴
- 形状
秩、轴和形状是在深度学习中开始使用张量时我们最关心的三个属性。这些概念相互建立,从秩开始,然后是轴,最后构建到形状,所以请注意这三个概念之间的关系。
秩、轴和形状都与我们在前一篇文章中讨论的索引概念密切相关。如果你还没有看过那篇文章,我强烈建议你去查看。让我们从基础开始,介绍张量的秩。
张量的秩
张量的 秩 指的是张量内部存在的维度数量。假设我们被告知有一个秩为 2 的张量。这意味着以下所有情况:
- 我们有一个矩阵
- 我们有一个二维数组
- 我们有一个二维张量
我们在这里引入 秩 这个词,因为它在深度学习中常用来指代给定张量内部存在的维度数量。这是不同研究领域使用不同词汇来指代同一概念的另一个例子。不要让它迷惑你!
秩和索引
张量的秩告诉我们需要多少个索引来访问(引用)张量数据结构中包含的特定数据元素。
张量的秩告诉我们需要多少个索引来引用张量中的特定元素。
让我们通过查看张量的轴来进一步理解秩的概念。
张量的轴
如果我们有一个张量,我们想要引用特定的 维度,我们在深度学习中使用 轴 这个词。
张量的轴是张量的特定维度。
如果我们说一个张量是一个秩为 2 的张量,我们的意思是张量有 2 个维度,或者等效地,张量有两个轴。
元素被说成存在于轴上或沿着轴运行。这种 运行 受到每个轴长度的限制。让我们现在看看轴的长度。
轴的长度
每个轴的长度告诉我们沿着每个轴有多少个索引可用。
假设我们有一个名为 t
的张量,我们知道第一个轴的长度为三,而第二个轴的长度为四。
由于第一个轴的长度为三,这意味着我们可以沿着第一个轴索引三个位置,如下所示:
t[0]
t[1]
t[2]
所有这些索引都是有效的,但我们不能超过索引 2
。
由于第二个轴的长度为四,我们可以沿着第二个轴索引四个位置。这对于第一个轴的每个索引都是可能的,所以我们有
t[0][0]
t[1][0]
t[2][0]
t[0][1]
t[1][1]
t[2][1]
t[0][2]
t[1][2]
t[2][2]
t[0][3]
t[1][3]
t[2][3]
张量轴的例子
让我们看一些例子来巩固这一点。我们将考虑与之前相同的张量 dd
:
> dd = [
[1,2,3],
[4,5,6],
[7,8,9]
]
沿着第一个轴的每个元素都是一个数组:
> dd[0]
[1, 2, 3]
> dd[1]
[4, 5, 6]
> dd[2]
[7, 8, 9]
沿着第二个轴的每个元素都是一个数字:
> dd[0][0]
1
> dd[1][0]
4
> dd[2][0]
7
> dd[0][1]
2
> dd[1][1]
5
> dd[2][1]
8
> dd[0][2]
3
> dd[1][2]
6
> dd[2][2]
9
请注意,对于张量,最后一个轴的元素始终是数字。其他每个轴都将包含 n 维数组。这在我们的例子中可以看到,但这个概念是通用的。
张量的秩告诉我们张量有多少个轴,而这些轴的长度引导我们到一个非常重要的概念,即张量的 形状。
张量的形状
张量的 形状 由每个轴的长度决定,所以如果我们知道给定张量的形状,那么我们知道每个轴的长度,这告诉我们沿着每个轴有多少个索引可用。
张量的形状给出了张量每个轴的长度。
让我们再次考虑之前相同的张量 dd
:
> dd = [
[1,2,3],
[4,5,6],
[7,8,9]
]
为了处理这个张量的形状,我们将创建一个 torch.Tensor
对象,如下所示:
> t = torch.tensor(dd)
> t
tensor([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
])
> type(t)
torch.Tensor
现在,我们有一个 torch.Tensor
对象,所以我们可以要求查看张量的 shape
:
> t.shape
torch.Size([3,3])
这使我们能够看到张量的形状是 3 x 3
。请注意,在 PyTorch 中,张量的大小和形状是一回事。
3 x 3
的形状告诉我们,这个秩为二的张量的每个轴的长度都是 3
,这意味着我们沿着每个轴有三个索引可用。现在,让我们看看为什么张量的形状如此重要。
张量的形状很重要
张量的形状很重要有几个原因。第一个原因是形状允许我们从概念上思考,甚至可视化张量。更高秩的张量变得更加抽象,形状给我们提供了一些具体的东西来思考。
形状还编码了关于轴、秩,因此索引的所有相关信息。
此外,我们在编程神经网络时必须经常执行的一种操作称为 重塑。
随着我们的张量流经网络,在网络内部的不同点期望有不同的形状,作为神经网络程序员,我们的任务是理解输入的形状,并有能力根据需要进行重塑。
重塑张量
在我们查看重塑张量之前,回想一下我们如何重塑我们开始时的术语列表:
形状 6 x 1
- 数字
- 标量
- 数组
- 向量
- 二维数组
- 矩阵
形状 2 x 3
- 数字,数组,二维数组
- 标量,向量,矩阵
形状 3 x 2
- 数字,标量
- 数组,向量
- 二维数组,矩阵
每组术语都代表了相同的底层数据,只是形状不同。这只是一个小例子,以激发重塑的概念。
从这个动机中得到的重要的收获是,形状改变了术语的分组,但没有改变底层术语本身。
让我们再次看看我们的例子张量 dd
:
> t = torch.tensor(dd)
> t
tensor([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
])
这个 torch.Tensor
是一个秩为 2
的张量,形状为 [3,3]
或 3 x 3
。
现在,假设我们需要将 t
重塑为形状 [1,9]
。这将给我们第一个轴上一个数组和第二个轴上九个数字:
> t.reshape(1,9)
tensor([[1, 2, 3, 4, 5, 6, 7, 8, 9]])
> t.reshape(1,9).shape
torch.Size([1, 9])
现在,关于重塑值得注意的一点是,形状中组件值的乘积必须等于张量中元素的总数。
例如:
- 3 * 3 = 9
- 1 * 9 = 9
这确保了在重塑后,张量数据结构内有足够的位置来包含所有原始数据元素。
重塑改变了形状,但没有改变底层的数据元素。
这只是对张量重塑的简单介绍。在将来的文章中,我们将更详细地介绍这个概念。
总结
这为张量提供了一个介绍。现在我们应该对张量和用于描述它们的术语,如秩、轴和形状有了很好的理解。很快,我们将看到在 PyTorch 中创建张量的各种方式。