또는 에서 torch.Tensor.view()
영감을 얻은 간단하게 새로운보기를 만듭니다.numpy.ndarray.reshape()
numpy.reshape()
새로운 모양이 원래 텐서의 모양과 호환되는 한 텐서 을 .
구체적인 예를 사용하여 이것을 자세히 이해합시다.
In [43]: t = torch.arange(18)
In [44]: t
Out[44]:
tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17])
이 t
모양 텐서 를 사용하면 다음 모양에 대해서만(18,)
새 보기를 만들 수 있습니다.
(1, 18)
또는 동등 (1, -1)
하거나 또는 동등 하거나 또는 동등 하거나 또는 동등 하거나 또는 동등 하거나 또는 동등 또는(-1, 18)
(2, 9)
(2, -1)
(-1, 9)
(3, 6)
(3, -1)
(-1, 6)
(6, 3)
(6, -1)
(-1, 3)
(9, 2)
(9, -1)
(-1, 2)
(18, 1)
(18, -1)
(-1, 1)
위의 모양 튜플에서 이미 알 수 있듯이 모양 튜플의 요소 (예 : 등) 의 곱셈은 항상 원래 텐서의 요소 수 (예 2*9
에서 3*6
)와 같아야합니다18
.
관찰해야 할 또 다른 사항 -1
은 각 모양 튜플의 장소 중 하나에서를 사용했다는 것 입니다. 를 사용함으로써 -1
, 우리는 계산 자체를 수행하는 데 게으르고 오히려 새로운 뷰를 만들 때 셰이프에 대한 해당 값의 계산을 수행하기 위해 작업을 PyTorch에 위임합니다 . 주목해야 할 한 가지는 셰이프 튜플에서 하나만 사용할 수 있다는 것 -1
입니다. 나머지 값은 당사에서 명시 적으로 제공해야합니다. 다른 PyTorch는 다음을 던져 불평합니다 RuntimeError
.
RuntimeError : 하나의 차원 만 유추 할 수 있습니다
따라서 위에서 언급 한 모든 모양으로 PyTorch는 항상 원래 텐서 의 새로운보기 를 반환합니다.t
. 이것은 기본적으로 요청 된 새로운 뷰 각각에 대해 텐서의 보폭 정보 만 변경한다는 것을 의미합니다.
아래는 텐서의 보폭이 각각의 새로운 뷰로 어떻게 바뀌는 지 보여주는 몇 가지 예입니다 .
# stride of our original tensor `t`
In [53]: t.stride()
Out[53]: (1,)
이제 우리는 새로운 견해에 대한 진전을 보게 될 것입니다 .
# shape (1, 18)
In [54]: t1 = t.view(1, -1)
# stride tensor `t1` with shape (1, 18)
In [55]: t1.stride()
Out[55]: (18, 1)
# shape (2, 9)
In [56]: t2 = t.view(2, -1)
# stride of tensor `t2` with shape (2, 9)
In [57]: t2.stride()
Out[57]: (9, 1)
# shape (3, 6)
In [59]: t3 = t.view(3, -1)
# stride of tensor `t3` with shape (3, 6)
In [60]: t3.stride()
Out[60]: (6, 1)
# shape (6, 3)
In [62]: t4 = t.view(6,-1)
# stride of tensor `t4` with shape (6, 3)
In [63]: t4.stride()
Out[63]: (3, 1)
# shape (9, 2)
In [65]: t5 = t.view(9, -1)
# stride of tensor `t5` with shape (9, 2)
In [66]: t5.stride()
Out[66]: (2, 1)
# shape (18, 1)
In [68]: t6 = t.view(18, -1)
# stride of tensor `t6` with shape (18, 1)
In [69]: t6.stride()
Out[69]: (1, 1)
이것이 바로 그 view()
기능 의 마술입니다 . 새로운 형태의 한, 새로운 시각 각각에 대한 (원래) 텐서의 보폭을 변경합니다. 뷰는 원래의 형상과 호환된다.
보폭 튜플에서 관찰 할 수있는 또 다른 흥미로운 점은 0 번째 위치의 요소 값 이 모양 튜플 의 1 번째 위치의 요소 값과 동일하다는 것 입니다.
In [74]: t3.shape
Out[74]: torch.Size([3, 6])
|
In [75]: t3.stride() |
Out[75]: (6, 1) |
|_____________|
이 때문입니다:
In [76]: t3
Out[76]:
tensor([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17]])
보폭은 (6, 1)
그 0에 따라 다음 요소로 하나 개의 요소에서 갈 말한다 일 우리가해야 할, 차원 이동 또는 6 조치를 취합니다. (즉에서 이동 0
로 6
. 하나는 6 단계를 수행하는,)하지만 1의 다음 요소로 하나 개의 요소에서 이동 번째 (예에서 이동하는 차원, 우리는 단지 하나의 단계를 필요 2
로 3
).
따라서 보폭 정보는 계산을 수행하기 위해 메모리에서 요소에 액세스하는 방법의 핵심입니다.
이 함수는 뷰를 반환하며 torch.Tensor.view()
새 모양이 원래 텐서 모양과 호환되는 한 사용하는 것과 정확히 같습니다 . 그렇지 않으면 사본을 반환합니다.
그러나 다음과 같이 torch.reshape()
경고합니다.
호환 가능한 보폭을 가진 연속 입력 및 입력은 복사하지 않고 재구성 할 수 있지만 복사 대보기 동작에 의존해서는 안됩니다.
reshape
-PyTorch에서 왜 그렇게 부르지 않았 습니까?