type
Page
status
Invisible
date
Dec 25, 2025
slug
summary
动手深度学习v2课程
tags
机器学习
深度学习
category
icon
password
我们可以使用切片表示法将操作的结果分配给先前分配的数组,例如
Y[:] = <expression>。
为了说明这一点,我们首先创建一个新的矩阵Z,其形状与另一个Y相同,
使用zeros_like来分配一个全的块。n维数组,也称为张量(tensor)。无论使用哪个深度学习框架,它的张量类(Pytorch和TensorFlow中为
Tensor)都与Numpy的ndarry类似。但深度学习框架又比Numpy的ndarray多一些重要功能: 首先,GPU很好地支持加速计算,而NumPy仅支持CPU计算; 其次,张量类支持自动微分。2.1.1 入门
张量表示一个由数值组成的数组,这个数组可能有多个维度。 具有一个轴的张量对应数学上的向量(vector); 具有两个轴的张量对应数学上的矩阵(matrix); 具有两个轴以上的张量没有特殊的数学名称。
有时,我们希望使用全0、全1、其他常量,或者从特定分布中随机采样的数字来初始化矩阵。 我们可以创建一个形状为(2,3,4)的张量,其中所有元素都设置为0。代码如下:
有时我们想通过从某个特定的概率分布中随机采样来得到张量中每个元素的值。
例如,当我们构造数组来作为神经网络中的参数时,我们通常会随机初始化参数的值。
以下代码创建一个形状为(3,4)的张量。
其中的每个元素都从均值为0、标准差为1的标准高斯分布(正态分布)中随机采样。
我们还可以[通过提供包含数值的Python列表(或嵌套列表),来为所需张量中的每个元素赋予确定值]。
在这里,最外层的列表对应于轴0,内层的列表对应于轴1。
2.1.2 运算符
想在数据上执行数学运算,就需要用到运算符,其中最简单且实用的操作是按元素运算。
在数学表示法中,我们将通过符号来表示一元标量运算符(只接收一个输入)。
这意味着该函数从任何实数()映射到另一个实数。同样,我们通过符号表示二元标量运算符,这意味着该函数接收两个输入,并产生一个输出。给定同一形状的任意两个向量和和二元运算符,我们可以得到向量。具体计算方法是,其中、和分别是向量、和中的元素。在这里,我们通过将标量函数升级为按元素向量运算来生成向量值
对于任意具有相同形状的张量,常见的标准算术运算符(
+、-、*、/和**)都可以被升级为按元素运算。我们可以在同一形状的任意两个张量上调用按元素操作。除了按元素计算外,我们还可以执行线性代数运算,包括向量点积和矩阵乘法。 我们将在2.3 线性代数 中解释线性代数的重点内容。
可以把张量连结在一起,只需要提供张量列表并指明根据哪个轴连结。
还可以使用逻辑运算符构造二元张量
对张量中所有元素求和,则会产生一个单元素张量
2.1.3 广播机制
在上面的部分中,我们看到了如何在相同形状的两个张量上执行按元素操作。
在某些情况下,即使形状不同,我们仍然可以通过调用
广播机制(broadcasting mechanism)来执行按元素操作。
这种机制的工作方式如下:
- 通过适当复制元素来扩展一个或两个数组,以便在转换之后,两个张量具有相同的形状;
- 对生成的数组执行按元素操作。
在大多数情况下,我们将沿着数组中长度为1的轴进行广播,如下例子:
由于a和b分别是和矩阵,如果相加,它们的形状不匹配。
我们将两个矩阵广播为一个更大的矩阵,如下所示:矩阵
a将复制列,
矩阵b将复制行,然后再按元素相加。2.1.4 索引和切片
与python数组的操作类似。
如果想为多个元素赋一个相同的值,只需要索引想要赋值的元素,然后为它们赋值。
2.1.5 节省内存
运行一些操作可能会导致为新结果分配内存。
例如,如果我们用
Y = X + Y,我们将取消引用Y指向的张量,而是指向新分配的内存处的张量。在下面的例子中,我们用Python的
id()函数演示了这一点,
它给我们提供了内存中引用对象的确切地址。
运行Y = Y + X后,我们会发现id(Y)指向另一个位置。
这是因为Python首先计算Y + X,为结果分配新的内存,然后使Y指向内存中的这个新位置。这样的操作对于我们来说是不期望的,原因如下:
- 首先,我们不想总是不必要地分配内存。在机器学习中,我们可能有数百兆的参数,并且在一秒内多次更新所有参数。通常情况下,我们希望原地执行这些更新;
- 如果我们不原地更新,其他引用仍然会指向旧的内存位置,这样我们的某些代码可能会无意中引用旧的参数。
我们可以使用切片表示法将操作的结果分配给先前分配的数组,例如
Y[:] = <expression>。
为了说明这一点,我们首先创建一个新的矩阵Z,其形状与另一个Y相同,
使用zeros_like来分配一个全的块。如果后续计算中没有重复使用
X,我们也可以使用X[:] = X + Y或X += Y来减少操作的内存开销。2.1.6 转化为其他Python对象
将深度学习框架定义的张量转换为NumPy张量(
ndarray)很容易,反之也同样容易。
torch张量和numpy数组将共享它们的底层内存,就地操作更改一个张量也会同时更改另一个张量。要将大小为1的标量转换为Python标量,可以调用
item函数或Python的内置函数。小结
深度学习存储和操作数据的主要接口是张量(维数组)。它提供了各种功能,包括基本数学运算、广播、索引、切片、内存节省和转换其他Python对象。
