动手学深度学习__张量

        就像向量是标量的推广,矩阵是向量的推广一样,我们可以构建具有更多轴的数据结构。 张量为我们提供了描述具有任意数量轴的 n 维数组的通用方法。 例如,向量是一阶张量,矩阵是二阶张量。例如图像以 n 维数组形式出现, 其中3个轴对应于高度、宽度,以及一个通道(channel), 用于表示颜色通道(R、G、B)

张量相加

将两个相同形状的矩阵相加,会在这两个矩阵上执行元素加法。推广到张量上也适用。

A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
B = A.clone()  # 通过分配新内存,将A的一个副本分配给B
print(A)
print(A + B)
# (tensor([[ 0.,  1.,  2.,  3.],
#          [ 4.,  5.,  6.,  7.],
#          [ 8.,  9., 10., 11.],
#          [12., 13., 14., 15.],
#          [16., 17., 18., 19.]]),
#  tensor([[ 0.,  2.,  4.,  6.],
#          [ 8., 10., 12., 14.],
#          [16., 18., 20., 22.],
#          [24., 26., 28., 30.],
#          [32., 34., 36., 38.]]))

张量相乘

两个矩阵的按元素乘法称为Hadamard积(Hadamard product)数学符号 \bigodot 。 对于矩阵B\in \mathbb{R}^{m\times n}, 其中第 i 行和第 j 列的元素是 b_{ij}。 矩阵A和B的Hadamard积为:

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)
print(a + X) 
print((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]))

降维

对任意张量计算其元素和,就可使其进行降维。一维张量举例,求和记为  \sum _{I=1}^{d}x_{i}

x = torch.arange(4, dtype=torch.float32)
x       # (tensor([0., 1., 2., 3.]) 
x.sum() # tensor(6.))

矩阵也可以使用 sum( ) 函数,求和记为 \sum_{i=1}^{m}\sum_{j=1}^{n} a_{ij} 。例如对A求和:

A.shape # (torch.Size([5, 4])
A.sum() # tensor(190.)

 默认情况下,调用求和函数会沿所有的轴降低张量的维度,使它变为一个标量。 我们还可以指定张量沿哪一个轴来通过求和降低维度。 以矩阵为例,为了通过求和所有行的元素来降维(轴0),我们可以在调用函数时指定axis=0。 由于输入矩阵沿0轴降维以生成输出向量,因此输入轴0的维数在输出形状中消失。

A_sum_axis0 = A.sum(axis=0)
A_sum_axis0       # tensor([40., 45., 50., 55.])
A_sum_axis0.shape # torch.Size([4])

指定axis=1将通过汇总所有列的元素降维(轴1)。因此,输入轴1的维数在输出形状中消失。

A_sum_axis1 = A.sum(axis=1)
A_sum_axis1       # tensor([ 6., 22., 38., 54., 70.])
A_sum_axis1.shape # torch.Size([5])

沿着行和列对矩阵求和,等价于对矩阵的所有元素进行求和。

A.sum(axis=[0, 1])  # SameasA.sum()
# tensor(190.)

可以这么理解,0代表行,1代表列,对轴0求和时,就是按行对列进行相加;对轴1求和时,就是按列对行进行相加;

 更简单的理解,原本torch.size([5, 4]),axis=0,那么就消去5,axis=1就消去4。

再比如原来是torch.size([2, 3, 4]),axis=0,那么就消去2,axis=1就消去3,axis=2就消去4。

计算张量平均值也可以达到降维效果,既可以调用mean函数,也可以将总和除以元素总数来计算平均值。

A.mean()            # tensor(9.5000)
A.sum() / A.numel() # tensor(9.5000)

当然计算平均值也可以指定轴

A.mean(axis=0)             # tensor([ 8.,  9., 10., 11.])
A.sum(axis=0) / A.shape[0] # tensor([ 8.,  9., 10., 11.])

非降维求和

同样也是求和,但是求和时保持原来的维度。

sum_A = A.sum(axis=1, keepdims=True)
# 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]])

当我们计算某一维度的累积量时,可以调用cumsum函数,此函数不会沿任何轴降低输入张量的维度。axis=0,下一行是上面所有行的累计求和。

A.cumsum(axis=0)
# tensor([[ 0.,  1.,  2.,  3.],
#         [ 4.,  6.,  8., 10.],
#         [12., 15., 18., 21.],
#         [24., 28., 32., 36.],
#         [40., 45., 50., 55.]])

点积

给定两个向量 x,y \in\mathbb{R}^{d}, 它们的点积 x\top y 是相同位置的按元素乘积的和:x\top y = \sum_{i=1}^{d}x_{i}y_{i}

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

矩阵-向量积

矩阵-向量积使用mv函数

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

矩阵-矩阵乘法

注意与Hadamard积区分,使用torch.mm(A, B)函数

范数

L_{2} 范数,向量元素平方和再开平方: \left \| X \right \|_{2}=\sqrt{\sum_{i=1}^{n}x_{i}^{2}}

u = torch.tensor([3.0, -4.0])
torch.norm(u)
# tensor(5.)

深度学习中,也会经常见到 L_{1} 范数,向量元素绝对值求和: \left \| X \right \|_{1}=\sum_{i=1}^{n}\left | x_{i} \right |

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值