• pytorch的axis的理解


    import torch
    x = torch.arange(16).reshape(1,4,4)
    print(x)
    print('--------')
    a = x.sum(axis = 1,keepdim=True)
    a2 = x.sum(axis = 1,keepdim=False)
    a3 = x.sum(axis = 0,keepdim=True)
    a4 = x.sum(axis = 0,keepdim=False)
    a5 = x.sum(axis = 2,keepdim=True)
    print(a)
    print(a2)
    print('----------')
    print(a3)
    print(a4)
    print(a5)
    
     import torch
    x = torch.arange(16).reshape(4,4)
    print(x)
    print('--------')
    a = x.sum(axis = 1,keepdim=True)
    a2 = x.sum(axis = 1,keepdim=False)
    print(a)
    print(a2)
    print(x/a) 
    

    结合这个两个例子,详细的讲清楚不同情况下axis轴的变化
    理解PyTorch中张量的维度操作和沿特定轴的求和确实需要一点时间。让我们通过两个例子逐步解析这些操作,详细讲解不同情况下的轴变化。

    第一个例子

    import torch
    x = torch.arange(16).reshape(1, 4, 4)
    print(x)
    print('--------')
    a = x.sum(axis=1, keepdim=True)
    a2 = x.sum(axis=1, keepdim=False)
    a3 = x.sum(axis=0, keepdim=True)
    a4 = x.sum(axis=0, keepdim=False)
    a5 = x.sum(axis=2, keepdim=True)
    print(a)
    print(a2)
    print('----------')
    print(a3)
    print(a4)
    print(a5)
    
    初始张量
    tensor([[[ 0,  1,  2,  3],
             [ 4,  5,  6,  7],
             [ 8,  9, 10, 11],
             [12, 13, 14, 15]]])
    

    这是一个形状为 (1, 4, 4) 的张量。我们可以将其看作一个包含4x4矩阵的批次。

    沿轴1求和
    1. x.sum(axis=1, keepdim=True)

    沿轴1(即第二个维度,4的方向)求和,并保持维度。

    tensor([[[24, 28, 32, 36]]])
    

    形状变为 (1, 1, 4)

    1. x.sum(axis=1, keepdim=False)

    沿轴1求和,不保持维度。

    tensor([[24, 28, 32, 36]])
    

    形状变为 (1, 4)

    沿轴0求和
    1. x.sum(axis=0, keepdim=True)

    沿轴0(即第一个维度,1的方向)求和,并保持维度。

    tensor([[[ 0,  1,  2,  3],
             [ 4,  5,  6,  7],
             [ 8,  9, 10, 11],
             [12, 13, 14, 15]]])
    

    因为原始张量在轴0上只有一个元素,所以结果与原始张量相同,形状为 (1, 4, 4)

    1. x.sum(axis=0, keepdim=False)

    沿轴0求和,不保持维度。

    tensor([[ 0,  1,  2,  3],
            [ 4,  5,  6,  7],
            [ 8,  9, 10, 11],
            [12, 13, 14, 15]])
    

    形状变为 (4, 4)

    沿轴2求和
    1. x.sum(axis=2, keepdim=True)

    沿轴2(即第三个维度,4的方向)求和,并保持维度。

    tensor([[[ 6],
             [22],
             [38],
             [54]]])
    

    形状变为 (1, 4, 1)

    关键点
    • keepdim=True 会保持被求和的维度,结果的维度数不变,只是被求和的维度大小变为1。
    • keepdim=False 则会移除被求和的维度,结果的维度数减少1。

    第二个例子

    import torch
    x = torch.arange(16).reshape(4, 4)
    print(x)
    print('--------')
    a = x.sum(axis=1, keepdim=True)
    a2 = x.sum(axis=1, keepdim=False)
    print(a)
    print(a2)
    print(x/a)
    
    初始张量
    tensor([[ 0,  1,  2,  3],
            [ 4,  5,  6,  7],
            [ 8,  9, 10, 11],
            [12, 13, 14, 15]])
    

    这是一个形状为 (4, 4) 的张量。

    沿轴1求和
    1. x.sum(axis=1, keepdim=True)

    沿轴1(即第二个维度,4的方向)求和,并保持维度。

    tensor([[ 6],
            [22],
            [38],
            [54]])
    

    形状变为 (4, 1)

    1. x.sum(axis=1, keepdim=False)

    沿轴1求和,不保持维度。

    tensor([ 6, 22, 38, 54])
    

    形状变为 (4,)

    元素除以行和
    1. x / 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]])
    

    这是每个元素除以其对应行的和,结果为:

    tensor([[ 0/6,  1/6,  2/6,  3/6],
            [ 4/22,  5/22,  6/22,  7/22],
            [ 8/38,  9/38, 10/38, 11/38],
            [12/54, 13/54, 14/54, 15/54]])
    

    轴(axis)和维度变化总结

    • axis=0:沿第一个维度(行)操作,求和后剩下其他维度的和。
    • axis=1:沿第二个维度(列)操作,求和后剩下第一维度和第三维度的和。
    • axis=2:沿第三个维度(深度)操作,求和后剩下前两个维度的和。

    使用 keepdim=True 保持维度时,被求和的维度变为1。使用 keepdim=False 时,被求和的维度被移除。

    疑问:

    为啥reshape(1, 4, 4)这种的,行反而是列了,,只有reshape(4, 4)的时候,行才是行

    张量的结构

    先回顾一下基础概念:

    • 二维张量(矩阵):具有行和列。
    • 三维张量:有多个二维矩阵组成,可以看作是具有“深度”维度的矩阵堆叠。

    示例1:二维张量 (4, 4)

    import torch
    x = torch.arange(16).reshape(4, 4)
    print(x)
    

    输出:

    tensor([[ 0,  1,  2,  3],
            [ 4,  5,  6,  7],
            [ 8,  9, 10, 11],
            [12, 13, 14, 15]])
    

    这个张量的形状是 (4, 4),代表一个 4x4 的矩阵:

    • 是水平方向的:

      • 行0: [ 0, 1, 2, 3]
      • 行1: [ 4, 5, 6, 7]
      • 行2: [ 8, 9, 10, 11]
      • 行3: [12, 13, 14, 15]
    • 是垂直方向的:

      • 列0: [ 0, 4, 8, 12]
      • 列1: [ 1, 5, 9, 13]
      • 列2: [ 2, 6, 10, 14]
      • 列3: [ 3, 7, 11, 15]

    示例2:三维张量 (1, 4, 4)

    x = torch.arange(16).reshape(1, 4, 4)
    print(x)
    

    输出:

    tensor([[[ 0,  1,  2,  3],
             [ 4,  5,  6,  7],
             [ 8,  9, 10, 11],
             [12, 13, 14, 15]]])
    

    这个张量的形状是 (1, 4, 4),代表一个 1x4x4 的三维张量:

    • 第一个维度是 1,表示批次大小。
    • 第二个维度是 4,表示行数(每个矩阵的行)。
    • 第三个维度是 4,表示列数(每个矩阵的列)。

    沿轴求和的解释

    沿轴1(第二个维度)求和
    1. 对于二维张量 (4, 4)
    a = x.sum(axis=1, keepdim=True)
    print(a)
    

    输出:

    tensor([[ 6],
            [22],
            [38],
            [54]])
    
    • 轴1是行的方向,每行的元素求和:
      • [0, 1, 2, 3] => 0+1+2+3 = 6
      • [4, 5, 6, 7] => 4+5+6+7 = 22
      • [8, 9, 10, 11] => 8+9+10+11 = 38
      • [12, 13, 14, 15] => 12+13+14+15 = 54
    1. 对于三维张量 (1, 4, 4)
    a = x.sum(axis=1, keepdim=True)
    print(a)
    

    输出:

    tensor([[[24, 28, 32, 36]]])
    
    • 轴1是第一个矩阵的行方向。每行的元素求和:
      • [0, 1, 2, 3] + [4, 5, 6, 7] + [8, 9, 10, 11] + [12, 13, 14, 15]
      • 每列求和:24 = 0+4+8+12, 28 = 1+5+9+13, 32 = 2+6+10+14, 36 = 3+7+11+15

    为什么看起来“行变成了列”

    (1, 4, 4) 的三维张量中,第一维度表示的是批次大小,所以看起来每个4x4的矩阵在操作时依然是按二维的方式处理。但因为增加了一个批次维度,导致它在求和操作中表现出与二维张量不同的行为。

    具体来说:

    • 当沿轴1(第二个维度)求和时,我们对的是每个矩阵的行进行求和操作。
    • 而沿轴0(第一个维度)求和时,我们对批次维度进行求和操作。

    总结

    • 二维张量:行和列的概念是直观的。
    • 三维张量:批次维度引入后,行和列的操作看起来会不同,但其实依然是对每个二维矩阵进行操作。
    • 沿轴求和时,理解求和的维度是关键。
  • 相关阅读:
    【图像配准】基于surf算法实现图像配准附Matlab代码
    python3基础语法
    模型压缩-浅尝
    IDM短信发送接口设计说明
    代码随想录算法训练营第六十天 | 739. 每日温度 & 496.下一个更大元素 I
    Multihead Attention - 多头注意力
    LNMP架构概述及相关服务的搭建
    【C语言】单词拼写检查
    过五关,斩六将!「网易/美团/菜鸟」已拿offer【Java岗】
    gitlab访问报错: Whoops, GitLab is taking too much time to respond
  • 原文地址:https://blog.csdn.net/kiritobryant/article/details/140347088