【问题标题】:What does layout = torch.strided mean?layout = torch.strided 是什么意思?
【发布时间】:2019-11-01 16:43:28
【问题描述】:

在浏览 pytorch 文档时,我在许多函数中遇到了一个术语 layout = torch.strided。谁能帮助我了解它在哪里使用以及如何使用。描述说这是返回张量的所需布局。布局是什么意思,布局有多少种?

torch.rand(*sizes, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)

【问题讨论】:

    标签: python multidimensional-array pytorch tensor numpy-ndarray


    【解决方案1】:

    布局是指内存在该张量中组织元素的方式,我认为目前有两种类型的布局来存储张量 一个是torch.strided,另一个是torch.sparse_coo

    strid 表示元素以非常密集的方式一个接一个地排列,想想一个 strided 的部队,正方形,所以每个士兵实际上都有邻居。

    虽然对于 sparse_coo 我认为应该处理稀疏矩阵,但我不确定确切的存储结构,但我猜它只是存储非零元素的索引和值

    这两种类型需要分开,因为对于稀疏矩阵,不需要以密集形式一个一个地排列元素,因为非零元素可能需要一百步才能到达下一个非零元素

    【讨论】:

      【解决方案2】:

      strides 是在给定维度中从一个元素到下一个元素所需的步数(或跳转)。在计算机内存中,数据线性存储在连续的内存块中。我们查看的只是一个(重新)呈现。

      让我们以张量为例来理解这一点:

      # a 2D tensor
      In [62]: tensor = torch.arange(1, 16).reshape(3, 5) 
      
      In [63]: tensor  
      Out[63]: 
      tensor([[ 1,  2,  3,  4,  5],
              [ 6,  7,  8,  9, 10],
              [11, 12, 13, 14, 15]])
      

      有了这个张量,步幅是:

      # get the strides
      In [64]: tensor.stride() 
      Out[64]: (5, 1)
      

      这个结果元组(5, 1) 说的是:

      • 要沿着第 0th 维度/轴(Y 轴)遍历,假设我们要跳转16,我们应该采取5 步(或跳跃)
      • 要沿着第一个st 维度/轴(X 轴)遍历,假设我们要跳转78,我们应该采取1 步(或跳跃)

      元组中5 & 1 的顺序(或索引)表示维度/轴。您还可以将您想要跨度的维度作为参数传递:

      # get stride for axis 0
      In [65]: tensor.stride(0) 
      Out[65]: 5
      
      # get stride for axis 1
      In [66]: tensor.stride(1) 
      Out[66]: 1
      

      有了这样的理解,我们可能要问为什么在创建张量时需要这个额外参数?答案是出于效率原因。 (我们如何才能最有效地存储/读取/访问(稀疏)张量中的元素?)。

      使用稀疏张量(大多数元素只是零的张量),所以我们不想存储这些值。我们只存储非零值及其索引。使用所需的形状,其余的值可以用零填充,从而产生所需的稀疏张量。


      如需进一步阅读,以下文章可能会有所帮助:


      P.S:我猜torch.layout 文档中有一个错字

      Strides 是一个整数列表 ...

      tensor.stride() 返回的复合数据类型是元组,而不是列表。

      【讨论】:

        【解决方案3】:

        为了快速理解,layout=torch.strided 对应 dense 张量,layout=torch.sparse_coo 对应 sparse 张量。

        换个角度,我们可以和torch.tensor.view一起理解。 可以查看张量表明它是连续的。如果我们改变张量的视图,步幅会相应改变,但数据将保持不变。更具体地说,view返回一个新的张量,数据相同但形状不同,stridesview兼容,表示如何访问内存中的数据。

        例如

        In [1]: import torch
        In [2]: a = torch.arange(15)
        
        In [3]: a.data_ptr()
        Out[3]: 94270437164688
        
        In [4]: a.stride()
        Out[4]: (1,)
        
        In [5]: a = a.view(3, 5)
        
        In [6]: a.data_ptr() # share the same data pointer
        Out[6]: 94270437164688
        
        In [7]: a.stride() # the stride changes as the view changes
        Out[7]: (5, 1)
        

        另外torch.strided的思路和numpy中的strides基本一致。 查看这个问题以获得更详细的理解。 How to understand numpy strides for layman?

        【讨论】:

          【解决方案4】:

          根据官方pytorch文档here

          torch.layout 是一个对象,表示一个内存布局 火炬.张量。目前,我们支持 torch.strided(密集张量)和 对torch.sparse_coo(稀疏COO 张量)提供实验性支持。

          torch.strided 表示密集张量,是内存布局 是最常用的。每个跨步张量都有一个关联的 torch.Storage,保存其数据。这些张量提供 存储的多维、跨步视图。步幅是一个列表 整数:第 k 个步幅表示必要的内存跳跃 在第 k 维中从一个元素移动到下一个元素 张量。这个概念使得执行许多张量成为可能 高效运营。

          例子:

          >>> x = torch.Tensor([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
          >>> x.stride()
          (5, 1)
          
          >>> x.t().stride()
          (1, 5)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-05-13
            • 1970-01-01
            • 2011-08-12
            • 2017-06-11
            • 2018-03-05
            • 2023-03-27
            • 1970-01-01
            相关资源
            最近更新 更多