天天看點

pytorch reshape_Pytorch之contiguous函數

pytorch reshape_Pytorch之contiguous函數
1 先看看官方中英文doc:
torch
           
1.1 contiguous() → Tensor
Returns a contiguous tensor containing the same data as self tensor. If self tensor is contiguous, this function returns the self tensor.
           
1.2 contiguous() → Tensor
傳回一個記憶體連續的有相同資料的tensor,如果原tensor記憶體連續,則傳回原tensor;
           
2 pytorch contiguous的使用

contiguous一般與transpose,permute,view搭配使用:使用transpose或permute進行次元變換後,調用contiguous,然後方可使用view對次元進行變形(如:tensor_var.contiguous().view() ),示例如下:

x 
           

具體原因有兩種說法:

1 transpose、permute等次元變換操作後,tensor在記憶體中不再是連續存儲的,而view操作要求tensor的記憶體連續存儲,是以需要contiguous來傳回一個contiguous copy;

2 次元變換後的變量是之前變量的淺拷貝,指向同一區域,即view操作會連帶原來的變量一同變形,這是不合法的,是以也會報錯;---- 這個解釋有部分道理,也即contiguous傳回了tensor的深拷貝contiguous copy資料;

3 contiguous函數分析,參考CSDN部落格

在pytorch中,隻有很少幾個操作是不改變tensor的内容本身,而

隻是重新定義下标與元素的對應關系

。換句話說,這種操作

不進行資料拷貝和資料的改變,變的是中繼資料

,這些操作是:

narrow
           

舉個栗子,在使用transpose()進行轉置操作時,

pytorch并不會建立新的、轉置後的tensor

,而是

修改了tensor中的一些屬性(也就是中繼資料),使得此時的offset和stride是與轉置tensor相對應的

,而

轉置的tensor和原tensor的記憶體是共享的

為了證明這一點,我們來看下面的代碼:

x 
           

可以看到,

改變了x的元素的值的同時,y的元素的值也發生了變化;

也即,經過上述操作後得到的tensor,它

内部資料的布局方式和從頭開始建立一個正常的tensor的布局方式是不一樣的

!于是就有contiguous()的用武之地了。

在上面的例子中,

x是contiguous的,但y不是(因為内部資料不是通常的布局方式)

。注意:不要被contiguous的字面意思“連續的”誤解,

tensor中資料還是在記憶體中一塊區域裡,隻是布局的問題

當調用contiguous()時,會強制拷貝一份tensor,讓它的布局和從頭建立的一模一樣;

一般來說這一點不用太擔心,如果你沒在需要調用contiguous()的地方調用contiguous(),運作時會提示你:

RuntimeError
           

隻要看到這個錯誤提示,加上contiguous()就好啦~

4 其他 4.1 is_contiguous()函數 is_contiguous() → bool
Returns True if self tensor is contiguous in memory in C order.
           
is_contiguous() → bool
如果該tensor在記憶體中是連續的則傳回True;
           

pytorch裡面的

contiguous() 是以 C 為順序儲存在記憶體裡面

,如果不是,則傳回一個以 C 為順序儲存的tensor:

tensor_var
           

一些可能導緻不是以 C 為順序儲存的可能為:

import 
           
4.2 view()、reshape()函數的差異

在pytorch 0.4中,增加了torch.reshape(),與 numpy.reshape() 的功能類似,大緻相當于 tensor.contiguous().view(),這樣就省去了對tensor做view()變換前,調用contiguous()的麻煩;

5 參考

https://blog.csdn.net/gdymind/article/details/82662502​blog.csdn.net PyTorch - contiguous()​stackoverflow.com

pytorch reshape_Pytorch之contiguous函數