G1.5 實作:平移後,CNN 的答案真的一起移了嗎?
本篇重用1 篇
從公式回到張量
G1 已經推導 convolution 的平移共享。現在要檢查程式中的每一個操作是否仍符合假設,而不是只看到模型名稱就接受結果。
先使用長度 的週期訊號。訓練 input 是隨機訊號,target 是自己與左鄰居的平均:
這個 target 本身 translation-equivariant,而且可以用局部 kernel 計算。我們用它測試架構與學習,不把隨機訊號的 loss 當成真實影像效能。
準備與執行
本課的實作使用 Python 3.10 以上與 PyTorch 2.x,CPU 就可以計算。請在自己的 Python 環境安裝 PyTorch,再下載 gdl_labs.py。環境目錄與下載的第三方套件不要加入網站的 Git repository。
python -m pip install torch
python gdl_labs.py --unit 1 --steps 40
檔案包含可重用的模型與 Trainer。模型、loss 與資料來源由外部指定;換資料時保留對稱一致的 tensor interface,不需要修改 training loop。
from gdl_labs import Trainer
trainer = Trainer(model, loss, lr=0.003)
history = trainer.fit(batch_fn, steps=40)
# batch_fn() returns ((model_input_1, model_input_2, ...), target)
CNN 的介面與測試
from gdl_labs import TranslationCNN, defect
import torch
model = TranslationCNN(in_channels=1, out_channels=1, padding='circular')
x = torch.randn(8, 1, 32) # batch, channel, position
model.eval()
actual = model(torch.roll(x, 5, dims=-1))
expected = torch.roll(model(x), 5, dims=-1)
print(defect(actual, expected))
這裡使用完整週期格點,torch.roll 是可逆的位置重排。Defect 用 absolute max norm:,不是正文對資料平均的 ;兩者比較同樣兩條路,但 aggregation 不同。
在 float32 下,誤差通常接近零或浮點精度。這在隨機初始化也應成立;訓練降低的是 task loss,不是先破壞再修復共享規則。
程式也測試同樣長度的一般 dense layer。它沒有共享約束,通常有非零 defect;這只是一個未訓練 baseline 的一致性比較,不能由此宣稱 CNN 一定有更好的所有 task accuracy。
哪些修改應該讓結果改變?
把 padding 改成 zero padding,再用 torch.roll 測試。這時 image action 仍是週期重排,但模型的 boundary 不是週期,兩者的假設不一致,差異常出現在邊緣。
加入 stride 後,請分開測輸入平移 格與 格。前者不能一般性地對應粗格點整數平移;後者應對應 output 平移 格,並且仍要採相容 boundary。
若想比較 augmentation,請固定 train/test split、參數或計算預算,另列 task loss。不能用一個 dense random initialization 的 defect,代替 augmentation 的泛化實驗。
作業
保留同一份訊號,完成三組測試:circular padding、zero padding、stride 。每組列出 input action、output action、task loss 與 absolute max defect;再用 G1 的哪一個等號不再適用,解釋結果。
加分部分:在測試中只保留離邊界足夠遠的位置,觀察 zero-padding 差異與網路 receptive field 的關係。先算 receptive field,再選 interior,不要看完結果才挑區域。
課堂提問
為什麼 CNN 的 defect 可以在訓練前就很小,但 task loss 卻很大?
先想一想,再展開看整理後的答案
Defect 由共享與相容 action 保證,任意合法參數都可以成立。Task loss 則要求 kernel 學會指定的平均 target;兩者不是同一個目標。
動手看一次
改變平移與 stride,對照下方的兩條計算路。實作中的 symmetry test 做的也是這個比較,不只是檢查 loss。