張量表示
張量就是一個多維的數字陣列,是流經每個神經網路的通用資料結構。單一個數字是 0 維張量(純量),一個串列是 1 維(向量),一張表是 2 維(矩陣),把它們堆疊起來就得到 3 維、4 維乃至更高維。在視覺中,影像與網路內部的中間「激活值」自然就是張量:一張彩色影像是一個 3 維數字方塊(高乘寬乘色彩通道),一批影像則是一個 4 維方塊。視覺模型所計算的一切,都是把一個張量轉換成另一個張量。
一批特徵圖慣例上是一個 4 階張量,軸為 N 乘 C 乘 H 乘 W:N 是批次大小(一起處理多少張影像),C 是通道數(RGB 輸入為 3;內部特徵圖則為數十到數千,每個學到的濾波器一個),H 與 W 是空間的高與寬。每個軸有一個大小,其乘積是元素總數;張量還帶有資料型別 dtype(float32、float16 或 bfloat16、int8)與裝置 device(CPU 或 GPU)。PyTorch 預設這種通道在前的 NCHW 順序;TensorFlow 預設通道在後的 NHWC,而硬體核心(以及量化或推論路徑)常偏好 NHWC,這在移植模型時是常見的混淆來源。
在底層,張量是一塊扁平的記憶體加上形狀與步幅(strides);步幅說明沿每個軸移動一格要跨過多少個元素,這使轉置、reshape 或 view、切片、與廣播(broadcasting)這類運算能成為便宜的「視圖」,在不複製的情況下重新詮釋同一塊記憶體。這就是為何轉置可以是免費的、但後續運算可能會強迫複製以讓資料連續(contiguous)。廣播(自動把較小張量的形狀擴張以匹配較大者,例如把形狀為 C 的逐通道偏置加到一個 N 乘 C 乘 H 乘 W 的張量上)是讓逐元素數學變得簡潔的規則;不相符的形狀卻悄悄被廣播,是常見的錯誤。
追蹤張量形狀是建構視覺模型的日常工作。一個卷積把 N 乘 C_in 乘 H 乘 W 映到 N 乘 C_out 乘 H' 乘 W';池化縮小 H 與 W;攤平或全域池化在稠密頭之前把空間軸塌縮掉;視覺 Transformer 把影像重塑成一串區塊詞元(patch tokens),即一個 N 乘 L 乘 D 的張量(L 個維度為 D 的詞元),以餵入注意力。除了網格之外,點雲、網格(mesh)、NeRF 取樣、與影片(多加一個時間軸,N 乘 C 乘 T 乘 H 乘 W)也都是張量。精通形狀,以及其乘積所隱含的 GPU 記憶體,是最實用的張量技能。
陷阱:無聲的形狀錯誤。廣播可能讓運算不報錯地執行卻算錯東西(例如 (N,1) 與 (1,N) 不符,產生一個 N 乘 N 的張量);而忘了批次維度、或把 NCHW 與 NHWC 混用,會造成形狀錯誤或影像錯亂。請大方地印出形狀;它們就是深度學習裡的「型別」。