具名張量運算符覆蓋範圍¶
請先閱讀 具名張量 以取得具名張量的簡介。
此文件是有關名稱推斷的參考,名稱推斷是一個定義具名張量如何
使用名稱來提供額外的自動執行階段正確性檢查
將名稱從輸入張量傳播到輸出張量
以下是所有支援具名張量的運算及其相關名稱推斷規則的清單。
如果您在此處未看到列出的操作,但它有助於您的使用案例,請搜尋是否已提交問題,如果沒有,請提交一個問題。
警告
具名張量 API 是一個實驗性的 API,可能會發生變更。
API |
名稱推論規則 |
---|---|
請參閱文件 |
|
請參閱文件 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
|
無 |
|
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
請參閱文件 |
|
無 |
|
無 |
|
|
無 |
無 |
|
|
請參閱文件 |
|
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
|
無 |
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
|
|
無 |
|
對齊遮罩以符合輸入,然後從輸入張量統一名稱 |
|
請參閱文件 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
|
無 |
無 |
|
無 |
|
請參閱文件 |
|
無 |
|
無 |
|
請參閱文件 |
|
請參閱文件 |
|
無 |
|
無 |
|
僅允許不改變形狀的調整大小 |
|
僅允許不改變形狀的調整大小 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
無 |
|
請參閱文件 |
|
無 |
|
無 |
|
保留輸入名稱¶
所有逐點一元函數都遵循此規則,以及其他一些一元函數。
檢查名稱:無
傳播名稱:輸入張量的名稱會傳播到輸出。
>>> x = torch.randn(3, 3, names=('N', 'C'))
>>> x.abs().names
('N', 'C')
移除維度¶
所有縮減運算,例如sum()
,都會透過縮減所需的維度來移除維度。其他運算,例如select()
和squeeze()
,也會移除維度。
無論何時可以將整數維度索引傳遞給運算子,也可以傳遞維度名稱。 接受維度索引列表的函數也可以接受維度名稱列表。
檢查名稱:如果將
dim
或dims
作為名稱列表傳入,請檢查這些名稱是否存在於self
中。傳播名稱:如果輸入張量的維度由
dim
或dims
指定,且不存在於輸出張量中,則這些維度對應的名稱不會出現在output.names
中。
>>> x = torch.randn(1, 3, 3, 3, names=('N', 'C', 'H', 'W'))
>>> x.squeeze('N').names
('C', 'H', 'W')
>>> x = torch.randn(3, 3, 3, 3, names=('N', 'C', 'H', 'W'))
>>> x.sum(['N', 'C']).names
('H', 'W')
# Reduction ops with keepdim=True don't actually remove dimensions.
>>> x = torch.randn(3, 3, 3, 3, names=('N', 'C', 'H', 'W'))
>>> x.sum(['N', 'C'], keepdim=True).names
('N', 'C', 'H', 'W')
統一來自輸入的名稱¶
所有二元算術運算都遵循此規則。廣播運算仍然從右側進行位置廣播,以保持與未命名張量的相容性。若要按名稱執行顯式廣播,請使用 Tensor.align_as()
。
檢查名稱:所有名稱必須從右側進行位置匹配。也就是說,在
tensor + other
中,對於(-min(tensor.dim(), other.dim()) + 1, -1]
中的所有i
,match(tensor.names[i], other.names[i])
必須為 true。檢查名稱:此外,所有命名的維度必須從右側對齊。在匹配期間,如果我們將命名的維度
A
與未命名的維度None
匹配,則A
不得在具有未命名維度的張量中出現。傳播名稱:統一來自兩個張量的右側名稱對,以產生輸出名稱。
例如,
# tensor: Tensor[ N, None]
# other: Tensor[None, C]
>>> tensor = torch.randn(3, 3, names=('N', None))
>>> other = torch.randn(3, 3, names=(None, 'C'))
>>> (tensor + other).names
('N', 'C')
檢查名稱
match(tensor.names[-1], other.names[-1])
為True
match(tensor.names[-2], tensor.names[-2])
為True
因為我們在
tensor
中將None
與'C'
匹配,請檢查以確保'C'
不存在於tensor
中(它不存在)。檢查以確保
'N'
不存在於other
中(它不存在)。
最後,輸出名稱使用 [unify('N', None), unify(None, 'C')] = ['N', 'C']
計算。
更多範例
# Dimensions don't match from the right:
# tensor: Tensor[N, C]
# other: Tensor[ N]
>>> tensor = torch.randn(3, 3, names=('N', 'C'))
>>> other = torch.randn(3, names=('N',))
>>> (tensor + other).names
RuntimeError: Error when attempting to broadcast dims ['N', 'C'] and dims
['N']: dim 'C' and dim 'N' are at the same position from the right but do
not match.
# Dimensions aren't aligned when matching tensor.names[-1] and other.names[-1]:
# tensor: Tensor[N, None]
# other: Tensor[ N]
>>> tensor = torch.randn(3, 3, names=('N', None))
>>> other = torch.randn(3, names=('N',))
>>> (tensor + other).names
RuntimeError: Misaligned dims when attempting to broadcast dims ['N'] and
dims ['N', None]: dim 'N' appears in a different position from the right
across both lists.
注意
在最後兩個範例中,都可以通過名稱對齊張量,然後執行加法。使用 Tensor.align_as()
按名稱對齊張量,或使用 Tensor.align_to()
將張量對齊到自訂維度排序。
排列維度¶
某些運算,例如 Tensor.t()
,會排列維度的順序。維度名稱附加到個別維度,因此它們也會被排列。
如果運算符採用位置索引 dim
,它也可以將維度名稱作為 dim
。
檢查名稱:如果
dim
作為名稱傳遞,請檢查它是否存在於張量中。傳播名稱:以與要排列的維度相同的方式排列維度名稱。
>>> x = torch.randn(3, 3, names=('N', 'C'))
>>> x.transpose('N', 'C').names
('C', 'N')
收縮維度¶
矩陣乘法函數遵循此規則的某些變體。讓我們首先瀏覽 torch.mm()
,然後推廣批量矩陣乘法的規則。
對於 torch.mm(tensor, other)
檢查名稱:無
傳播名稱:結果名稱為
(tensor.names[-2], other.names[-1])
。
>>> x = torch.randn(3, 3, names=('N', 'D'))
>>> y = torch.randn(3, 3, names=('in', 'out'))
>>> x.mm(y).names
('N', 'out')
矩陣乘法本質上對兩個維度執行點積,將它們摺疊。當兩個張量進行矩陣相乘時,收縮的維度會消失,並且不會出現在輸出張量中。
torch.mv()
、torch.dot()
的工作方式類似:名稱推斷不檢查輸入名稱,並刪除點積中涉及的維度
>>> x = torch.randn(3, 3, names=('N', 'D'))
>>> y = torch.randn(3, names=('something',))
>>> x.mv(y).names
('N',)
現在,讓我們看看 torch.matmul(tensor, other)
。假設 tensor.dim() >= 2
且 other.dim() >= 2
。
檢查名稱:檢查輸入的批次維度是否對齊且可廣播。有關輸入對齊的含義,請參閱 統一來自輸入的名稱。
傳播名稱:結果名稱通過統一批次維度並刪除收縮的維度來獲得:
unify(tensor.names[:-2], other.names[:-2]) + (tensor.names[-2], other.names[-1])
。
範例
# Batch matrix multiply of matrices Tensor['C', 'D'] and Tensor['E', 'F'].
# 'A', 'B' are batch dimensions.
>>> x = torch.randn(3, 3, 3, 3, names=('A', 'B', 'C', 'D'))
>>> y = torch.randn(3, 3, 3, names=('B', 'E', 'F'))
>>> torch.matmul(x, y).names
('A', 'B', 'C', 'F')
最後,有許多 matmul 函數的融合 add
版本。也就是說,addmm()
和 addmv()
。這些被視為組合的名稱推斷,例如,mm()
和 add()
的名稱推斷。
工廠函數¶
工廠函數現在採用一個新的 names
參數,該參數將名稱與每個維度關聯。
>>> torch.zeros(2, 3, names=('N', 'C'))
tensor([[0., 0., 0.],
[0., 0., 0.]], names=('N', 'C'))
out 函數和 in-place 變體¶
指定為 out=
張量的張量具有以下行為
如果它沒有命名的維度,則從操作計算出的名稱會傳播到它。
如果它有任何命名的維度,則從操作計算出的名稱必須與現有名稱完全相等。否則,該操作會出錯。
所有原地 (in-place) 方法都會修改輸入,使其名稱等於從名稱推斷計算出的名稱。例如:
>>> x = torch.randn(3, 3)
>>> y = torch.randn(3, 3, names=('N', 'C'))
>>> x.names
(None, None)
>>> x += y
>>> x.names
('N', 'C')