命名張量運算元覆蓋率#
建立日期: 2019年10月08日 | 最後更新日期: 2025年06月08日
請先閱讀 命名張量 以瞭解命名張量的介紹。
本文件是關於名稱推斷的參考,這是一個定義命名張量如何
使用名稱提供額外的執行時自動正確性檢查
將名稱從輸入張量傳播到輸出張量
以下是支援命名張量的所有操作及其相關的名稱推斷規則的列表。
如果您在此處未找到所需的操作,但它有助於您的用例,請 搜尋是否已提交相關問題,如果沒有,請 提交一個問題。
警告
命名張量 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中,對於i在(-min(tensor.dim(), other.dim()) + 1, -1]範圍內的所有i,都必須滿足match(tensor.names[i], other.names[i])為真。檢查名稱:此外,所有命名維度必須從右側對齊。在匹配過程中,如果我們匹配到一個命名維度
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])為Truematch(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')
最後,還有許多矩陣乘法函式的融合 add 版本。例如 addmm() 和 addmv()。這些被視為 mm() 的名稱推斷與 add() 的名稱推斷相結合。
工廠函式#
工廠函式現在接受一個新的 names 引數,該引數將名稱與每個維度關聯起來。
>>> torch.zeros(2, 3, names=('N', 'C'))
tensor([[0., 0., 0.],
[0., 0., 0.]], names=('N', 'C'))
out函式和原地變體#
指定為 out= 的張量具有以下行為:
如果它沒有命名維度,那麼從操作中計算出的名稱將傳播到它。
如果它具有任何命名維度,那麼從操作中計算出的名稱必須與其現有名稱完全匹配。否則,操作將出錯。
所有原地方法都會修改輸入,使其名稱與名稱推斷計算出的名稱相等。例如:
>>> x = torch.randn(3, 3)
>>> y = torch.randn(3, 3, names=('N', 'C'))
>>> x.names
(None, None)
>>> x += y
>>> x.names
('N', 'C')