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(第一个维度)求和时,我们对批次维度进行求和操作。

总结

  • 二维张量:行和列的概念是直观的。
  • 三维张量:批次维度引入后,行和列的操作看起来会不同,但其实依然是对每个二维矩阵进行操作。
  • 沿轴求和时,理解求和的维度是关键。

相关推荐

  1. pytorchaxis理解

    2024-07-11 15:38:02       33 阅读
  2. 理解pytorch系列:transpose是怎么实现

    2024-07-11 15:38:02       54 阅读
  3. 理解pytorch系列:布尔索引是怎么实现

    2024-07-11 15:38:02       57 阅读
  4. 理解pytorch系列:contiguous是怎么实现

    2024-07-11 15:38:02       53 阅读
  5. 理解pytorch系列:整型索引是怎么实现

    2024-07-11 15:38:02       67 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-11 15:38:02       103 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-11 15:38:02       110 阅读
  3. 在Django里面运行非项目文件

    2024-07-11 15:38:02       92 阅读
  4. Python语言-面向对象

    2024-07-11 15:38:02       99 阅读

热门阅读

  1. 搭建基于 ChatGPT 的问答系统

    2024-07-11 15:38:02       27 阅读
  2. C语言 将两个字符串连接起来,不用strcat函数

    2024-07-11 15:38:02       24 阅读
  3. ES6 Generator函数的语法 (七)

    2024-07-11 15:38:02       23 阅读
  4. git的下载流程,及使用方法,官网地址怎么找?

    2024-07-11 15:38:02       27 阅读
  5. 线程冲突案例演示

    2024-07-11 15:38:02       32 阅读
  6. WPF-C# byte[]转ImageSource常用方法

    2024-07-11 15:38:02       35 阅读
  7. 【ubuntu22.04 安装软件报错】

    2024-07-11 15:38:02       26 阅读
  8. Redis 7.x 系列【24】哨兵模式配置项

    2024-07-11 15:38:02       19 阅读
  9. C语言9 指针

    2024-07-11 15:38:02       30 阅读