深度学习 – 张量的广播机制和复杂运算

作者 : admin 本文共2947个字,预计阅读时间需要8分钟 发布时间: 2024-06-5 共1人阅读

张量的广播机制(Broadcasting)是一种处理不同形状张量进行数学运算的方式。通过广播机制,PyTorch可以自动扩展较小的张量,使其与较大的张量形状兼容,从而进行元素级的运算。广播机制遵循以下规则:

  1. 如果张量维度不相同,在较小张量的形状前面加上1,直到两个张量的维度相同。
  2. 如果两个张量在某个维度的长度不相同,但其中一个张量在该维度的长度为1,那么在该维度上,较小长度的张量会被扩展为较大长度。
  3. 如果两个张量在任何维度上长度不同且均不为1,则无法进行广播,会引发错误。

广播机制的规则示例

规则1:在较小张量的形状前面加1
a = torch.tensor([1, 2, 3])
b = torch.tensor([[1], [2], [3]])
c = a + b
print(c)

运行结果

tensor([[2, 3, 4],
        [3, 4, 5],
        [4, 5, 6]])

解释a的形状是(3,), b的形状是(3,1)。在较小的张量前面加1变成(1,3)和(3,1),然后在第0维度上广播。

规则2:在某个维度的长度为1
a = torch.tensor([[1, 2, 3]])
b = torch.tensor([[4], [5], [6]])
c = a + b
print(c)

运行结果

tensor([[5, 6, 7],
        [6, 7, 8],
        [7, 8, 9]])

解释a的形状是(1,3), b的形状是(3,1)。a被广播到(3,3),b也被广播到(3,3)。

规则3:无法广播的情况
a = torch.tensor([1, 2, 3])
b = torch.tensor([[1, 2], [3, 4]])
try:
    c = a + b
except RuntimeError as e:
    print(e)

运行结果

The size of tensor a (3) must match the size of tensor b (2) at non-singleton dimension 1

解释a的形状是(3,), b的形状是(2,2),它们的形状不兼容,无法进行广播。

广播机制的详细示例

示例1:标量与多维张量相加
a = torch.tensor(5)
b = torch.tensor([[1, 2, 3], [4, 5, 6]])
c = a + b
print(c)

运行结果

tensor([[ 6,  7,  8],
        [ 9, 10, 11]])

解释:标量a被广播到与b形状匹配,变成(2,3)。

示例2:形状不一致但能广播
a = torch.tensor([1, 2, 3])
b = torch.tensor([[1], [2], [3]])
c = a + b
print(c)

运行结果

tensor([[2, 3, 4],
        [3, 4, 5],
        [4, 5, 6]])

解释a的形状是(3,), b的形状是(3,1)。a被广播到(3,3),b被广播到(3,3)。

示例3:不同维度的广播
a = torch.tensor([1, 2, 3])
b = torch.tensor([[[1]], [[2]], [[3]]])
c = a + b
print(c)

运行结果

tensor([[[2, 3, 4]],
        [[3, 4, 5]],
        [[4, 5, 6]]])

解释a的形状是(3,),b的形状是(3,1,1)。a被广播到(3,1,3),b被广播到(3,1,3)。

示例4:标量与高维张量的广播
a = torch.tensor(10)
b = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
c = a * b
print(c)

运行结果

tensor([[[10, 20],
         [30, 40]],

        [[50, 60],
         [70, 80]]])

解释:标量a被广播到与b的形状匹配。

示例5:不同形状的广播加法
a = torch.tensor([[1, 2], [3, 4], [5, 6]])
b = torch.tensor([10, 20])
c = a + b
print(c)

运行结果

tensor([[11, 22],
        [13, 24],
        [15, 26]])

解释a的形状是(3,2),b的形状是(2,)。b被广播到(3,2)。

张量的基本操作

示例1:基本运算
a = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
b = torch.tensor([[[2, 2], [2, 2]], [[2, 2], [2, 2]]])
c = a * b
print(c)

运行结果

tensor([[[ 2,  4],
         [ 6,  8]],

        [[10, 12],
         [14, 16]]])

解释:对ab中的每个元素进行乘法运算。

示例2:列表索引
a = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
b = a[0]
print(b)

运行结果

tensor([[1, 2],
        [3, 4]])

解释:选择张量a的第0个二维子张量。

示例3:范围索引
a = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
b = a[:, 0, :]
print(b)

运行结果

tensor([[1, 2],
        [5, 6]])

解释:选择张量a中所有的第0个二维子张量的所有元素。

示例4:布尔索引
a = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
b = a > 4
c = a[b]
print(c)

运行结果

tensor([5, 6, 7, 8])

解释:选择张量a中所有大于4的元素。

示例5:多维索引
a = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
b = a[1, 1, 1]
print(b)

运行结果

tensor(8)

解释:选择张量a的第二个三维子张量中的第二个二维子张量中的第二个元素。

示例6:形状操作(reshape)
a = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
b = a.reshape(4, 2)
print(b)

运行结果

tensor([[1, 2],
        [3, 4],
        [5, 6],
        [7, 8]])

解释:将张量a重塑为形状为(4, 2)的张量。

示例7:形状操作(squeeze)
a = torch.tensor([[[1, 2]], [[3, 4]], [[5, 6]]])
b = a.squeeze()
print(b)

运行结果

tensor([[1, 2],
 		[3, 4],
        [5, 6]])

解释:删除张量a中所有为1的维度。

示例8:形状操作(unsqueeze)
a = torch.tensor([[1, 2], [3, 4], [5, 6]])
b = a.unsqueeze(1)
print(b)

运行结果

tensor([[[1, 2]],
        [[3, 4]],
        [[5, 6]]])

解释:在张量a的第一维度增加一个维度。

示例9:形状操作(transpose)
a = torch.tensor([[[1, 2, 3], [4, 5, 6]]])
b = a.transpose(1, 2)
print(b)

运行结果

tensor([[[1, 4],
         [2, 5],
         [3, 6]]])

解释:交换张量a的第1维和第2维。

示例10:形状操作(permute)
a = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
b = a.permute(2, 0, 1)
print(b)

运行结果

tensor([[[1, 3],
         [5, 7]],

        [[2, 4],
         [6, 8]]])

解释:根据指定的顺序重新排列张量a的维度。

本站无任何商业行为
个人在线分享 » 深度学习 – 张量的广播机制和复杂运算
E-->