我对步幅的理解是跳到轴的下一部分所需的步数。因此,如果跨度为(3,1)
,则需要3个步骤才能到达下一行,而又需要1个步骤才能到达下一列(假设第一个轴为行,第二个轴为列)。
但是,当我索引到火炬张量时,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()
答案 0 :(得分:1)
self.c
张量仍使用与self.a
和self.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
所引用的同一内存的偏移视图。