《动手学深度学习(Dive into Deeplearning)》(第二版)——第二章 _2.3 线性代数

《动手学深度学习(Dive into Deeplearning)》(第二版)——第二章 _2.3 线性代数

  • 第二章 预备知识
    • § 前情回顾
    • § 2.3 线性代数
      • 2.3.1 标量
      • 2.3.2 向量
      • 2.3.3 矩阵
      • 2.3.4 张量
      • 2.3.5 张量算法的基本性质
      • 2.3.6 降维
      • 2.3.7 点积
      • 2.3.8 矩阵-向量积
      • 2.3.9 矩阵-矩阵乘法
      • 2.3.10 范数
      • 2.3.12 总结
      • *课后练习*

第二章 预备知识

§ 前情回顾

  之前我们学习了数据的预处理方法——删除和插值。而向量矩阵这些知识我相信朋友们在线性代数的学习中都学习过了,如果你有些遗忘了,那么让我们简单的回顾一下线性代数部分的一些知识。
  这一节内容较多,希望大家耐心过一遍,为后面的学习做准备。


§ 2.3 线性代数

  线性代数可以说是机器学习中最重要的数学基础之一了,我认为学好这部分知识非常重要,如果有的朋友对这部分还不是很熟悉,可以去回顾一下教材或是听听网课。下面我们将介绍线性代数中的基本数学对象、算术和运算,并用数学符号和相应的代码实现来表示它们。


2.3.1 标量

  严格来说,我们称仅包含一个数值的叫 标量 (scalar)。如果要将此华氏度值转换为更常用的摄氏度,则可以计算表达式 c = 5 9 ( f − 32 ) { c=\frac{5}{9}(f−32)} c=95(f32) ,并将 f f f 赋为 52 。在此等式中,每一项( 5 、 9 和 32 5 、 9 和 32 5932 )都是标量值。符号 c 和 f c 和 f cf 称为 变量(variables),它们表示未知的标量值。

  我们采用小写字母表示标量变量,用 R \mathbb{R} R 表示所有(连续)实数标量的空间。标量由只有一个元素的张量表示,接下来我们实例化两个标量,并使用它们执行一些熟悉的算术运算,即加法,乘法,除法和指数:

import torch

x = torch.tensor([3.0])
y = torch.tensor([2.0])

x + y, x * y, x / y, x**y
(tensor([5.]), tensor([6.]), tensor([1.5000]), tensor([9.]))

2.3.2 向量

  其实最直观的理解,可以把向量看作由标量值组成的列表,我们将这些标量成为 元素(elements)或是分量(components)。向量时常作为机器学习中的输入和输出。在数学表示中,我们经常将向量记为粗体、小写的符号。

  • 我们通过一维张量处理向量。一般来说,张量可以具有任意长度,取决于机器的内存限制。
x = torch.arange(4)
x
tensor([0, 1, 2, 3])
  • 可以通过下标来索引向量中的任一元素。在数学中,向量可以写为:
    X = [ x 1 x 2 ⋮ x n ] {X= \begin{bmatrix} {x_{1}}\\ {x_{2}}\\ {\vdots}\\ {x_{n}}\\ \end{bmatrix} } X=x1x2xn
    其中 x 1 , … , x n x_1,…,x_n x1,,xn 是向量的元素。在代码中,我们通过张量的索引来访问任一元素。
x[3]
tensor(3)
  • 向量的长度通常称为向量的 维度(dimension)。len函数可以访问张量的长度:
len(x)
4
  • 形状(shape)是一个元组,列出了张量沿每个轴的长度(维数),而对于只有一个轴的张量,形状只有一个元素,因此当用张量表示一个向量(只有一个轴)时,我们也可以通过 shape 属性访问向量的长度:
x.shape
torch.Size([4])

2.3.3 矩阵

  向量是将标量从零阶推广到一阶,矩阵是将向量从一阶推广到二阶。而矩阵我们通常用粗体、大写字母表示,代码中是两个轴的张量。

  在数学表示法中,我们使用 A ∈ R m × n \mathbf{A}\in{\mathbb{R^{m×n}}} ARm×n 来表示矩阵 A \mathbf{A} A,其由 m m m 行和 n n n 列的实值标量组成。直观地,我们可以将任意矩阵 A ∈ R m × n \mathbf{A}\in{\mathbb{R^{m×n}}} ARm×n视为一个表格,其中每个元素 a i j a_{ij} aij 属于第 i i i 行第 j j j 列,它的形状是 ( m , n ) (m,n) (m,n) m × n m \times n m×n
A = [ a 11 a 12 ⋯ a 1 n a 21 a 22 ⋯ a 2 n ⋮ ⋮ ⋱ ⋮ a m 1 a m 2 ⋯ a m n ] \mathbf{A}= \begin{bmatrix} {a_{11}}&{a_{12}}&{\cdots}&{a_{1n}}\\ {a_{21}}&{a_{22}}&{\cdots}&{a_{2n}}\\ {\vdots}&{\vdots}&{\ddots}&{\vdots}\\ {a_{m1}}&{a_{m2}}&{\cdots}&{a_{mn}}\\ \end{bmatrix} A=a11a21am1a12a22am2a1na2namn

  • 当我们构建向量的时候,可以通过 resahpe 函数指定两个分量 m 和 n m 和 n mn 来创建一个形状为 m × n m \times n m×n的矩阵:
A = torch.arange(20).reshape(5, 4)
A
tensor([[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11],
        [12, 13, 14, 15],
        [16, 17, 18, 19]])
  • 我们有时候经常会想要翻转轴,交换矩阵的行列称为矩阵的 转置 (transpose)。对于矩阵 A \mathbf{A} A 的转置,数学上记为 A ⊤ \mathbf{A}^\top A 。对于任意的 i 和 j i 和 j ij,都有 b i j = a j i b_{ij}=a_{ji} bij=aji。因此转置后的结果为:
    A ⊤ = [ a 11 a 21 ⋯ a m 1 a 12 a 22 ⋯ a m 2 ⋮ ⋮ ⋱ ⋮ a 1 n a 2 n ⋯ a m n ] \mathbf{A}^\top= \begin{bmatrix} {a_{11}}&{a_{21}}&{\cdots}&{a_{m1}}\\ {a_{12}}&{a_{22}}&{\cdots}&{a_{m2}}\\ {\vdots}&{\vdots}&{\ddots}&{\vdots}\\ {a_{1n}}&{a_{2n}}&{\cdots}&{a_{mn}}\\ \end{bmatrix} A=a11a12a1na21a22a2nam1am2amn
A.T
tensor([[ 0,  4,  8, 12, 16],
        [ 1,  5,  9, 13, 17],
        [ 2,  6, 10, 14, 18],
        [ 3,  7, 11, 15, 19]])
  • 对称矩阵是方矩阵中的一种特殊类型,该矩阵和它的转置相等, A = A T \mathbf{A}=\mathbf{A^{T}} A=AT,我们定义一个对称矩阵 B \mathbf{B} B,并于它的转置进行比较:
B = torch.tensor([[1, 2, 3], [2, 0, 4], [3, 4, 5]])
B, B == B.T
(tensor([[1, 2, 3],
         [2, 0, 4],
         [3, 4, 5]]),
 tensor([[True, True, True],
         [True, True, True],
         [True, True, True]]))

2.3.4 张量

  我们可以构建更多轴的数据结构,张量为我们提供了描述具有任意数量轴的 n n n维数组的通用方法。张量通常用特殊的大写字母表示,索引机制与矩阵类似。
  张量对于我们处理图像非常重要,图像以 n 维数组形式出现,其中3个轴对应于高度、宽度,以及一个通道(channel)轴,用于堆叠颜色通道(红色、绿色和蓝色),也即RGB三通道。我们随意构建一个张量:

X = torch.arange(24).reshape(2, 3, 4)
X
array([[[ 0.,  1.,  2.,  3.],
        [ 4.,  5.,  6.,  7.],
        [ 8.,  9., 10., 11.]],

       [[12., 13., 14., 15.],
        [16., 17., 18., 19.],
        [20., 21., 22., 23.]]])

2.3.5 张量算法的基本性质

  • 任何按元素的一元运算都不会改变其操作数的形状。同样,给定具有相同形状的任意两个张量,任何按元素二元运算的结果都将是相同形状的张量。例如张量相加:
A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
B = A.clone()		# 通过分配新内存,将A的一个副本分配给B
A, A + B
(array([[ 0.,  1.,  2.,  3.],
        [ 4.,  5.,  6.,  7.],
        [ 8.,  9., 10., 11.],
        [12., 13., 14., 15.],
        [16., 17., 18., 19.]]),
 array([[ 0.,  2.,  4.,  6.],
        [ 8., 10., 12., 14.],
        [16., 18., 20., 22.],
        [24., 26., 28., 30.],
        [32., 34., 36., 38.]]))
  • 两个矩阵的按元素乘法称为 哈达玛积(Hadamard product)(数学符号 ⊙ ⊙ ),矩阵 B ∈ R m × n \mathbf{B}\in{\mathbb{R^{m×n}}} BRm×n。矩阵 A \mathbf{A} A 和矩阵 B \mathbf{B} B 的哈达玛积为:
    A ⊙ B = [ a 11 b 11 a 12 b 12 ⋯ a 1 n b 1 n a 21 b 21 a 22 b 22 ⋯ a 2 n b 2 n ⋮ ⋮ ⋱ ⋮ a m 1 b m 1 a m 2 b m 2 ⋯ a m n b m n ] \mathbf{A ⊙B}= \begin{bmatrix} {a_{11}b_{11}}&{a_{12}b_{12}}&{\cdots}&{a_{1n}b_{1n}}\\ {a_{21}b_{21}}&{a_{22}b_{22}}&{\cdots}&{a_{2n}b_{2n}}\\ {\vdots}&{\vdots}&{\ddots}&{\vdots}\\ {a_{m1}b_{m1}}&{a_{m2}b_{m2}}&{\cdots}&{a_{mn}b_{mn}}\\ \end{bmatrix} AB=a11b11a21b21am1bm1a12b12a22b22am2bm2a1nb1na2nb2namnbmn
A * B
tensor([[  0.,   1.,   4.,   9.],
        [ 16.,  25.,  36.,  49.],
        [ 64.,  81., 100., 121.],
        [144., 169., 196., 225.],
        [256., 289., 324., 361.]])
  • 将张量乘以或加上一个标量不会改变张量的形状,其中张量的每个元素都将与标量相加或相乘:
a = 2
X = torch.arange(24).reshape(2, 3, 4)
a + X, (a * X).shape
(tensor([[[ 2,  3,  4,  5],
          [ 6,  7,  8,  9],
          [10, 11, 12, 13]],

         [[14, 15, 16, 17],
          [18, 19, 20, 21],
          [22, 23, 24, 25]]]),
 torch.Size([2, 3, 4]))

2.3.6 降维

  • 数学中,我们使用 ∑ \sum 符号表示求和,长度为 d d d的向量中的元素和记为 ∑ i = 1 d x i \sum_{i=1}^{d}x_{i} i=1dxi, 我们可以用sum函数对向量求和:
x = torch.arange(4, dtype=torch.float32)
x, x.sum()
(tensor([0., 1., 2., 3.]), tensor(6.))
  • 我们也可以表示任意形状张量的元素和,矩阵 A \mathbf{A} A 中的元素和记为
    ∑ i = 1 m ∑ j = 1 n a i j \sum_{i=1}^{m}\sum_{j=1}^{n}a_{ij} i=1mj=1naij
    形状和元素和用代码表示:
A.shape, A.sum()
(torch.Size([5, 4]), tensor(190.))
  • 默认情况下,调用求和函数会沿所有的轴降低张量的维度,使它变为一个标量。 我们还可以指定张量沿哪一个轴来通过求和降低维度。以矩阵为例,为了通过求和所有行的元素来降维(轴0),我们可以在调用函数时指定axis=0。可以直观地理解为,指定的轴为哪一个,输出后的形状就会缺少该轴的维数:
指定轴为轴0时
A_sum_axis0 = A.sum(axis=0)
A_sum_axis0, A_sum_axis0.shape
(tensor([40., 45., 50., 55.]), torch.Size([4]))
指定轴为轴1时
A_sum_axis1 = A.sum(axis=1)
A_sum_axis1, A_sum_axis1.shape
(tensor([ 6., 22., 38., 54., 70.]), torch.Size([5]))
沿着行列矩阵求和
A.sum(axis=[0, 1])
tensor(190.)
  • 平均值(mean和average)。我们也可以通过将总和除以元素总数来计算平均值:
A.mean(), A.sum() / A.numel()
(tensor(9.5000), tensor(9.5000))
  • 而且计算平均值的函数也可以沿指定轴降低张量的维度:
A.mean(axis=0), A.sum(axis=0) / A.shape[0]
(tensor([ 8.,  9., 10., 11.]), tensor([ 8.,  9., 10., 11.]))
  • 同时,我们也能够不降低维度得到最后的结果,利用其中的 keepdims 参数保持维度:
sum_A = A.sum(axis=1, keepdims=True)
sum_A
tensor([[ 6.],
        [22.],
        [38.],
        [54.],
        [70.]])
  • sum_A 仍然保持两个维度,我们通过广播将A除以 sum_A:
A / sum_A
tensor([[0.0000, 0.1667, 0.3333, 0.5000],
        [0.1818, 0.2273, 0.2727, 0.3182],
        [0.2105, 0.2368, 0.2632, 0.2895],
        [0.2222, 0.2407, 0.2593, 0.2778],
        [0.2286, 0.2429, 0.2571, 0.2714]])
  • 沿某个轴计算 A 元素的累积总和,比如 axis=0(按行计算),我们可以调用 cumsum 函数,此函数不会沿任何轴降低输入张量的维度:
A, A.cumsum(axis=0)
(tensor([[ 0.,  1.,  2.,  3.],
         [ 4.,  5.,  6.,  7.],
         [ 8.,  9., 10., 11.],
         [12., 13., 14., 15.],
         [16., 17., 18., 19.]]),
 tensor([[ 0.,  1.,  2.,  3.],
         [ 4.,  6.,  8., 10.],
         [12., 15., 18., 21.],
         [24., 28., 32., 36.],
         [40., 45., 50., 55.]]))

2.3.7 点积

  现在我们来介绍最基本的操作之一—— 点积(Dot Product)。给定两个向量 x , y ∈ R d \mathbf{x},\mathbf{y}\in{\mathbb{R^{d}}} x,yRd,他们的点积 x ⊤ y \mathbf{x}^\top\mathbf{y} xy 是相同位置的按元素乘积的和:
x ⊤ y = ∑ i = 1 d x i y i \mathbf{x}^\top\mathbf{y}=\sum_{i=1}^{d}x_{i}y_{i} xy=i=1dxiyi

y = torch.ones(4, dtype=torch.float32)
x, y, torch.dot(x, y)
(tensor([0., 1., 2., 3.]), tensor([1., 1., 1., 1.]), tensor(6.))

或者:

torch.sum(x * y)
tensor(6.)

2.3.8 矩阵-向量积

  了解了点积,我们再来看看矩阵-向量积。我们定义 A ∈ R m × n \mathbf{A}\in\mathbb{R}^{m\times n} ARm×n 和向量 x ∈ R n \mathbf{x}\in\mathbb{R}^{n} xRn。矩阵 A \mathbf{A} A 采用行向量表示:
A = [ a 1 ⊤ a 2 ⊤ ⋮ a m ⊤ ] \mathbf{A}= \begin{bmatrix} {\mathbf{a}_{1}^\top}\\ {\mathbf{a}_{2}^\top}\\ {\vdots}\\ {\mathbf{a}_{m}^\top}\\ \end{bmatrix} A=a1a2am
其中每个 a i ⊤ ∈ R n \mathbf{a}_{i}^\top\in\mathbb{R}^{n} aiRn 都是行向量,表示矩阵的第 i i i 行。而对于矩阵向量积 A x \mathbf{Ax} Ax 的表示为:
A x = [ a 1 ⊤ a 2 ⊤ ⋮ a m ⊤ ] x = [ a 1 ⊤ x a 2 ⊤ x ⋮ a m ⊤ x ] \mathbf{Ax}= \begin{bmatrix} {\mathbf{a}_{1}^\top}\\ {\mathbf{a}_{2}^\top}\\ {\vdots}\\ {\mathbf{a}_{m}^\top}\\ \end{bmatrix}\mathbf{x}= \begin{bmatrix} {\mathbf{a}_{1}^\top\mathbf{x}}\\ {\mathbf{a}_{2}^\top\mathbf{x}}\\ {\vdots}\\ {\mathbf{a}_{m}^\top\mathbf{x}}\\ \end{bmatrix} Ax=a1a2amx=a1xa2xamx
  在神经网络的求解中,我们经常会使用到矩阵向量积进行每一层的复杂计算。代码中我们使用张量表示,使用 .mv 函数。值得注意的是,此时矩阵 A \mathbf{A} A 的列数必须与 x 的长度相同。

A.shape, x.shape, torch.mv(A, x)
(torch.Size([5, 4]), torch.Size([4]), tensor([ 14.,  38.,  62.,  86., 110.]))

2.3.9 矩阵-矩阵乘法

  有了前面的了解,对于矩阵-矩乘法的理解就更加不成问题。我们先定义两个矩阵 A ∈ R m × k \mathbf{A}\in\mathbb{R}^{m\times k} ARm×k B ∈ R k × n \mathbf{B}\in\mathbb{R}^{k\times n} BRk×n
A = [ a 11 a 12 ⋯ a 1 k a 21 a 22 ⋯ a 2 k ⋮ ⋮ ⋱ ⋮ a m 1 a m 2 ⋯ a m k ] , B = [ b 11 b 12 ⋯ b 1 n b 21 b 22 ⋯ b 2 n ⋮ ⋮ ⋱ ⋮ b k 1 b k 2 ⋯ b k n ] \mathbf{A}= \begin{bmatrix} {a_{11}}&{a_{12}}&{\cdots}&{a_{1k}}\\ {a_{21}}&{a_{22}}&{\cdots}&{a_{2k}}\\ {\vdots}&{\vdots}&{\ddots}&{\vdots}\\ {a_{m1}}&{a_{m2}}&{\cdots}&{a_{mk}}\\ \end{bmatrix}, \mathbf{B}= \begin{bmatrix} {b_{11}}&{b_{12}}&{\cdots}&{b_{1n}}\\ {b_{21}}&{b_{22}}&{\cdots}&{b_{2n}}\\ {\vdots}&{\vdots}&{\ddots}&{\vdots}\\ {b_{k1}}&{b_{k2}}&{\cdots}&{b_{kn}}\\ \end{bmatrix} A=a11a21am1a12a22am2a1ka2kamk,B=b11b21bk1b12b22bk2b1nb2nbkn
然后二者的点积为矩阵 C \mathbf{C} C
C = A B = [ a 1 ⊤ a 2 ⊤ ⋮ a m ⊤ ] [ b 1 b 2 ⋯ b n ] = [ a 1 ⊤ b 1 a 1 ⊤ b 2 ⋯ a 1 ⊤ b n a 2 ⊤ b 1 a 2 ⊤ b 2 ⋯ a 2 ⊤ b n ⋮ ⋮ ⋱ ⋮ a m ⊤ b 1 a m ⊤ b 2 ⋯ a m ⊤ b n ] , \mathbf{C}= \mathbf{AB}= \begin{bmatrix} {\mathbf{a}_{1}^\top}\\ {\mathbf{a}_{2}^\top}\\ {\vdots}\\ {\mathbf{a}_{m}^\top}\\ \end{bmatrix} \begin{bmatrix} {\mathbf{b}_{1}}&{\mathbf{b}_{2}}&{\cdots}&{\mathbf{b}_{n}}\\ \end{bmatrix} =\begin{bmatrix} {\mathbf{a}_{1}^\top\mathbf{b}_{1}}&{\mathbf{a}_{1}^\top\mathbf{b}_{2}}&{\cdots}&{\mathbf{a}_{1}^\top\mathbf{b}_{n}}\\ {\mathbf{a}_{2}^\top\mathbf{b}_{1}}&{\mathbf{a}_{2}^\top\mathbf{b}_{2}}&{\cdots}&{\mathbf{a}_{2}^\top\mathbf{b}_{n}}\\ {\vdots}&{\vdots}&{\ddots}&{\vdots}\\ {\mathbf{a}_{m}^\top\mathbf{b}_{1}}&{\mathbf{a}_{m}^\top\mathbf{b}_{2}}&{\cdots}&{\mathbf{a}_{m}^\top\mathbf{b}_{n}}\\ \end{bmatrix}, C=AB=a1a2am[b1b2bn]=a1b1a2b1amb1a1b2a2b2amb2a1bna2bnambn,
由代码表示,两矩阵相乘我们使用 .mm 函数:

B = torch.ones(4, 3)
torch.mm(A, B)
tensor([[ 6.,  6.,  6.],
        [22., 22., 22.],
        [38., 38., 38.],
        [54., 54., 54.],
        [70., 70., 70.]])

注意:

  • 矩阵-矩阵乘法不应与前面的“哈达玛积”混淆;
  • 两矩阵相乘 A B \mathbf{AB} AB ,必须保证矩阵 A \mathbf{A} A 的列数和矩阵 B \mathbf{B} B 的行数相等。

2.3.10 范数

  关于范数的介绍,大家可以看看作者的讲解——范数,这里就总结常见的几种。

  • 在深度学习中,我们更经常地使用 L 2 L_{2} L2范数 的平方。 L 2 L_{2} L2范数是向量元素平方和的平方根:
    ∣ ∣ x ∣ ∣ 2 = ∑ i = 1 n x i 2 ||\mathbf{x}||_{2}=\sqrt{\sum_{i=1}^{n}x_{i}^{2}} x2=i=1nxi2
u = torch.tensor([3.0, -4.0])
torch.norm(u)
tensor(5.)
  • L 1 L_{1} L1范数 ,它表示为向量元素的绝对值之和:
    ∣ ∣ x ∣ ∣ 1 = ∑ i = 1 n ∣ x i ∣ ||\mathbf{x}||_{1}=\sum_{i=1}^{n}|x_{i}| x1=i=1nxi
torch.abs(u).sum()
tensor(7.)
  • L 1 L_{1} L1 范数和 L 2 L_{2} L2 范数都是更一般的 L p L_{p} Lp 范数的特例:
    ∣ ∣ x ∣ ∣ p = ( ∑ i = 1 n ∣ x i ∣ p ) 1 p ||\mathbf{x}||_{p}=(\sum_{i=1}^{n}|x_{i}|^{p})^{\frac{1}{p}} xp=(i=1nxip)p1
  • 矩阵的佛罗贝尼乌斯范数 (Frobenius norm)是矩阵元素的平方和的平方根:
    ∣ ∣ x ∣ ∣ F = ∑ i = 1 m ∑ j = 1 n x i j 2 ||\mathbf{x}||_{F}=\sqrt{\sum_{i=1}^{m}\sum_{j=1}^{n}x_{ij}^{2}} xF=i=1mj=1nxij2
torch.norm(torch.ones((4, 9)))
tensor(6.)

2.3.12 总结

  • 标量、向量、矩阵和张量是线性代数中的基本数学对象。
  • 向量泛化自标量,矩阵泛化自向量。
  • 标量、向量、矩阵和张量分别具有零、一、二和任意数量的轴。
  • 一个张量可以通过sum和mean沿指定的轴降低维度。
  • 两个矩阵的按元素乘法被称为他们的哈达玛积。它与矩阵乘法不同。
  • 在深度学习中,我们经常使用范数,如 L1 范数、 L2 范数和弗罗贝尼乌斯范数。
  • 我们可以对标量、向量、矩阵和张量执行各种操作。

课后练习

  • 证明一个矩阵 A 的转置的转置是 A : ( A ⊤ ) ⊤ = A (A^⊤)^⊤=A (A)=A
  • 给出两个矩阵 A 和 B , 显示转置的和等于和的转置: A ⊤ + B ⊤ = ( A + B ) ⊤ A^⊤+B^⊤=(A+B)^⊤ A+B=(A+B)
  • 几个问题:
    1. 给定任意方矩阵 A , A + A ⊤ A , A+A^⊤ AA+A 总是对称的吗?为什么?
    2. 我们在本节中定义了形状(2,3,4)的张量X。len(X)的输出结果是什么?
    3. 对于任意形状的张量X,len(X)是否总是对应于X特定轴的长度?这个轴是什么?
    4. 运行A/A.sum(axis=1),看看会发生什么。你能分析原因吗?
    5. 当你在曼哈顿的两点之间旅行时,你需要在坐标上走多远,也就是说,就大街和街道而言?你能斜着走吗?
    6. 考虑一个具有形状(2,3,4)的张量,在轴0,1,2上的求和输出是什么形状?
    7. 向linalg.norm函数提供3个或更多轴的张量,并观察其输出。对于任意形状的张量这个函数计算得到什么?

这一节就到这了,我们下一节再见~~

你可能感兴趣的:(《动手学深度学习》自学之路,python,机器学习,深度学习,算法)