0

我对步幅的理解是跳到轴的下一部分所需的步数。因此,如果您迈出了一大步,(3,1)您需要采取 3 步才能到达下一行,并采取 1 步才能到达下一列(假设第一个轴是行,第二个轴是列)。

然而,当我索引到一个 pytorch 张量时,b[1:, 1:]形状(3,3)从第一行和第一列截断,然后查询它的步幅,我得到(3,1)的不是(2,1).

为什么会这样?

import unittest
import torch
class TestChapter3(unittest.TestCase):
    def setUp(self):
        self.a = torch.tensor(list(range(9)))
        self.b = self.a.view(3,3)
        self.c = self.b[1:, 1:]

    def test_index_of_view(self):
        print(self.c)
        self.assertEqual(self.c.size(), torch.Size([2, 2]))
        self.assertEqual(self.c.storage_offset(), 4)
        self.assertEqual(self.c.stride(), (2, 1)) # self.c.stride() is actually (3,1)


if __name__ == "__main__":
    unittest.main()
4

1 回答 1

1

张量仍然使用与和self.c相同的底层数据存储。它们都只是同一个存储上的不同视图。self.aself.b

self.c.storage_offset()告诉您视图从哪里self.c开始(传递第一整行和第二行的第一个元素 = 总共 4 个元素),但数据仍作为一个长数组存储在内存中。

由于底层存储仍然相同,向下一行的内存地址仍然是3*sizeof(float)字节或三个元素,这就是self.c.stride()[0]所说的。

在您的示例中,我们有:

self.a = (visible=[0, 1, 2, 3, 4, 5, 6, 7, 8], data=[0, 1, 2, 3, 4, 5, 6, 7, 8])
self.b = (visible=[
    [0, 1, 2], 
    [3, 4, 5], 
    [6, 7, 8]
], data=[0, 1, 2, 3, 4, 5, 6, 7, 8])
self.c = (visible=[

       [4, 5], 
       [7, 8]
], data=[4, 5, 6, 7, 8])

是的,6最后一个数据数组中的不是一个错误。最后一个数据数组只是引用的同一内存self.a的偏移视图。self.b

于 2020-07-17T12:23:10.930 回答