
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() → boolReturns 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/82662502blog.csdn.net PyTorch - contiguous()stackoverflow.com