Простіше кажучи, 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
в одному з місць у кожному з кортезів форми. Використовуючи a -1
, ми лінуємося робити самі обчислення і швидше делегуємо завдання PyTorch зробити обчислення цього значення для фігури, коли він створює новий вид . Одна важлива річ , щоб відзначити , що ми можемо тільки використовувати один -1
в кортежі формі. Решта значень повинні бути явно надані нами. Else 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 ?!