張量檢視¶
PyTorch 允許張量成為現有張量的檢視。檢視張量与其基礎張量共用相同的底層資料。支援檢視可避免明確的資料複製,因此允許我們進行快速且記憶體效率高的重塑、切片和逐元素運算。
例如,若要取得現有張量t的檢視,您可以呼叫t.view(...)。
>>> t = torch.rand(4, 4)
>>> b = t.view(2, 8)
>>> t.storage().data_ptr() == b.storage().data_ptr()  # `t` and `b` share the same underlying data.
True
# Modifying view tensor changes base tensor as well.
>>> b[0][0] = 3.14
>>> t[0][0]
tensor(3.14)
由於檢視与其基礎張量共用底層資料,因此如果您編輯檢視中的資料,也會反映在基礎張量中。
通常,PyTorch 運算會傳回新的張量作為輸出,例如add()。但在檢視運算的情況下,輸出是輸入張量的檢視,以避免不必要的資料複製。建立檢視時不會發生資料移動,檢視張量只會變更其解譯相同資料的方式。取得連續張量的檢視可能會產生非連續張量。使用者應更加注意,因為連續性可能會對效能產生隱含影響。transpose()是一個常見的範例。
>>> base = torch.tensor([[0, 1],[2, 3]])
>>> base.is_contiguous()
True
>>> t = base.transpose(0, 1)  # `t` is a view of `base`. No data movement happened here.
# View tensors might be non-contiguous.
>>> t.is_contiguous()
False
# To get a contiguous tensor, call `.contiguous()` to enforce
# copying data when `t` is not contiguous.
>>> c = t.contiguous()
如需參考,以下是 PyTorch 中檢視運算的完整清單
- 基本切片和索引運算,例如 - tensor[0, 2:, 1:7:2]會傳回基礎- tensor的檢視,請參閱下面的注意事項。
- view_as_real()
- split_with_sizes()
- indices()(僅限稀疏張量)
- values()(僅限稀疏張量)
注意
透過索引存取張量的內容時,PyTorch 會遵循 Numpy 的行為,即基本索引會傳回檢視,而進階索引會傳回複本。透過基本或進階索引進行的指派都是就地進行的。請參閱Numpy 索引文件中的更多範例。
還值得一提的是一些具有特殊行為的運算
- reshape()、- reshape_as()和- flatten()可以傳回檢視或新的張量,使用者程式碼不應依賴它是檢視還是新的張量。
- 如果輸入張量已經是連續的,則 - contiguous()會傳回自身,否則會透過複製資料來傳回新的連續張量。
如需更詳細的 PyTorch 內部實作說明,請參閱ezyang 關於 PyTorch 內部結構的部落格文章。