L4.3 一張圖裡同時有紋理、物件和整個場景,一個固定大小的核怎麼辦?
一個核只看得到一個尺度
上一篇的卷積只看一小塊,照片卻同時有細節與整體。看地圖時也一樣:縮小能看出整條路,放大才看清街口。模型能不能同時保留這兩種資訊?
真實的資料不是這樣。一張照片裡同時有紋理(幾個像素的週期性)、物件(幾十個像素)、和整個場景的構圖(整張圖)。而「這是貓還是狗」這個判斷可能需要同時用到毛的質感和耳朵的形狀,兩者差了兩個數量級的尺度。
一個 核看的是邊長 的區域。先考慮最直接的做法:stride 1、無 dilation 地疊 層。理論上輸出可能受哪一塊輸入影響?這是接受域(receptive field),邊長為
時:
depth 1 RF = 5
depth 2 RF = 9
depth 4 RF = 17
depth 8 RF = 33
depth 16 RF = 65
depth 32 RF = 129
接受域隨深度線性成長。 要看到相隔 個位置的兩件事,要疊 層——而且那 層每一層都在原始解析度上跑,每一層都是全尺寸的計算。
一個 的核要看到相隔 個位置,得疊 層;
只要每兩層把解析度砍半, 層就能看到 ——
那被砍掉的東西去哪裡了?
課堂提問Q1
降取樣(把解析度砍半)讓接受域便宜了非常多。先算清楚便宜多少,再問代價:被丟掉的具體是什麼資訊?而它回得來嗎?
先想一想,再展開看整理後的答案
先算便宜多少。 降取樣之後,同樣一個 的核在原始座標上覆蓋的範圍加倍了。所以接受域的成長從「每層加 」變成「每層加 目前的 stride」,而 stride 每降一次就乘二。實測(每兩層降一次):
depth 1 RF = 5 (stride 1)
depth 2 RF = 9 (stride 2)
depth 4 RF = 25 (stride 4)
depth 6 RF = 57 (stride 8)
depth 8 RF = 121 (stride 16)
depth 10 RF = 249 (stride 32)這張表假設每第二個 卷積使用 stride 2。一般可逐層算 、: 是原始座標中的接受域, 是輸出相鄰位置在原圖的間距。通道數固定時,較小特徵圖可省計算;若通道同時增加,總成本還要另外算。
代價是什麼。 降取樣把相鄰的幾個值合成一個。一個在兩三個取樣點的尺度上變化的東西——一條細線、一個邊界的確切位置、一段高頻紋理——在合併之後就不見了。
而且它回不來。 升取樣(把一個值複製成兩個、或內插)只能造出「在這個尺度上平滑」的東西,它沒有任何資訊可以用來重建那些細節。這不是實作不夠好,是資訊已經被刪掉了。
所以問題變成:這個代價要不要付?
- 如果輸出是低維的(一個類別、一個分數),那細節本來就要被丟掉,降取樣只是提早做了這件事。這就是分類網路的形狀:一路降到底。
- 如果輸出和輸入一樣大而且需要細節(分割的邊界、去噪後的影像、生成的圖),那丟掉就是致命的——你要輸出的正是那些被刪掉的東西。
一個自然的嘗試是:讓高解析度細節另有一條路,不必全部經過瓶頸。編碼側取得大範圍資訊,解碼側逐步升回解析度,同時接入編碼側對應層的特徵;這就是 U-Net 的長 skip connection。它是常用設計,不是唯一可行架構。
降取樣毀掉的到底是什麼
上面說「高頻回不來」是定性的。把它量出來。
做法很單純:拿一個純頻率的訊號(長度 的餘弦),做一次 平均池化再用最近鄰升回原長度,然後問兩件事——同一個頻率剩下多少振幅,以及整條訊號還差多遠。
f 週期(取樣點) 保留下來的同頻振幅 整體重建誤差
1 64.0 0.9976 0.0491
2 32.0 0.9904 0.0980
4 16.0 0.9619 0.1951
8 8.0 0.8536 0.3827
12 5.3 0.6913 0.5556
16 4.0 0.7071 0.7071
24 2.7 0.1464 0.9239
31 2.1 0.0024 0.9988
32 2.0 0.0000 1.0000
最後一列是乾淨的零。 週期剛好是兩個取樣點的成分()在 平均之後每一組都變成 ——完全消失,不是變小。
這張表量的是指定 sinusoid 經過這個平均濾波與降取樣之後的變化。不同頻率受影響不同,但不能把它改說成所有五、六像素以下的特徵都會損失一半;訊號形狀、相位與採樣方式也重要。
而右邊那一欄說得更直接:週期 個取樣點的訊號,降一次再升回來,整體誤差已經是 。降兩次就是在對已經模糊的東西再模糊一次。
平均池化可能讓不同輸入變成同一個輸出;只靠這個輸出,不能唯一還原原本細節。升取樣可以猜細節,但不是找回已保留的證據。
這張表只測一種池化、升取樣與正弦訊號,不能推出通用的 門檻。實際設計要檢查細節是否在通道、skip 或其他表示中保留;降低空間解析度不必然刪掉所有資訊,例如把像素重排到通道可以是可逆的。
注意表裡有一列不是單調的,而那是混疊
仔細看會發現 (週期 )的保留振幅是 ,比 (週期 )的 還高。這不是量測誤差。
降取樣會讓部分不同頻率在新格點上難以區分,這叫混疊;升取樣又可能產生影像頻率。還要分清傅立葉振幅與投影到原餘弦的係數,並注意相位與奈奎斯特頻率的特殊情況。 比 高,不能把它稱為原本不存在的低頻。這張表不適合直接推出普遍的頻率衰減門檻。
右邊那一欄(整體重建誤差 對 )就沒有這個非單調——因為它把「搬到別處去」也算成誤差。
實務上的後果是:降取樣之前通常要先低通濾波(先模糊再取樣),否則高頻會偽裝成低頻混進來。這也是為什麼在生成模型裡,單純用 stride-2 的升降取樣容易產生棋盤狀的假紋理,而加上平滑就好很多。
圖說: 降取樣擴大原始座標中的接受域;平均池化可能丟失細節,因此高解析度資訊需要另外保留。
那條橫跨的線
Q1 已經把 skip connection 的動機推出來了:如果輸出需要細節,細節就不能經過瓶頸。
但要把這件事和另一個常被混在一起的東西分開。深度學習裡有兩種「skip」,它們解決的是完全不同的問題:
- U-Net 的 skip(長跳接):從編碼側第 層接到解碼側對應的第 層,通常是串接(concatenate)。它解決的是資訊被降取樣刪掉的問題,跨越的是整個瓶頸。
- 殘差連接(短跳接):,跨越一兩層,通常是相加。它解決的是深度本身讓網路難以訓練的問題。
兩者都叫 skip,但一個是為了資訊、一個是為了梯度。下一節處理第二個。
深度本身的代價
把網路疊深有一個獨立於接受域的問題:它會變得訓練不起來。這件事在 同一張地圖從不同地方出發:損失曲面與初始化 已經用 gain 掃過一次;這裡換一個角度,直接量深度。
設定:一個 的 tanh 堆疊,深度從 到 ,三種接法——無殘差()、殘差()、殘差後接 LayerNorm。Adam 、1200 步、三個 seed 取中位數。
先看初始化時每一層輸出的大小(深度 ):
L1 L4 L8 L16 L32
無殘差 0.2418 0.2265 0.1695 0.1513 0.0928
殘差 0.2418 0.5845 1.2501 2.5496 4.3765
殘差+LN 0.2418 1.0000 1.0000 1.0000 1.0000
表中的量級不同,但不能只靠這張表唯一辨認原因。Ba、Kiros 與 Hinton [3] 的 LayerNorm,先對指定特徵維度計算平均 與變異數 :
只有在忽略 、未使用可學 affine 縮放等特定情況,標準化後的變異數才恰好為 1;實務值接近 1 並非所有 LN 輸出都精確等於 1。
再看梯度能不能傳回去(第一層與最後一個隱藏層的梯度大小比, 表示兩端一樣強):
depth 4 無殘差 2.87e-01 殘差 1.41e+01 殘差+LN 2.71e-02
depth 8 無殘差 7.05e-01 殘差 5.61e+00 殘差+LN 6.59e-02
depth 16 無殘差 7.60e-02 殘差 1.18e+00 殘差+LN 1.74e-01
depth 32 無殘差 6.47e-02 殘差 7.64e-01 殘差+LN 1.38e-01
depth 64 無殘差 7.33e-02 殘差 4.97e-01 殘差+LN 1.29e-01
在深度 這一列,殘差的前後梯度比更接近 1。它的局部 Jacobian 是 ,因此多了直接傳遞的分支;但總梯度仍可能受到其他分支抵消或放大。這張表支持這次設定有改善,不保證所有殘差網路都不會梯度消失。
最後看真的訓練得起來嗎:
depth 8 無殘差 0.0000 殘差 0.0000 殘差+LayerNorm 0.0000
depth 16 無殘差 0.0000 殘差 0.0000 殘差+LayerNorm 0.0000
depth 32 無殘差 0.7399 殘差 0.0000 殘差+LayerNorm 0.0000
depth 64 無殘差 0.9915 殘差 0.0000 殘差+LayerNorm 0.9096
深度 那一列就是整個殘差連接存在的理由:同一個容量、同一個資料、同一個最佳化器,沒有殘差的版本停在 (幾乎等於「輸出常數」的水準),有殘差的版本降到 。
殘差不是讓網路變強,是讓已經存在的容量變得訓練得到。
展開細節為什麼「 加上一個小修正」是一個好的預設行為
把一層寫成 。若特別將殘差分支初始化得很小,它接近恆等映射;但很多小修正相加仍可能累積,不保證疊一百層後整體也很接近恆等。
這件事有兩個好處。
一,起點是一個合理的函數。 一個無殘差的深網路在初始化時算出來的東西,和輸入幾乎沒有關係(上表的 :訊號已經被壓掉大半)。殘差網路的起點是「把輸入原樣送出去」,那至少是一個有意義的函數,而訓練從那裡開始只需要學修正。
二,加深不會變差。 如果第 層學到 ,那整個網路就退化成 層。所以「更深」在假設空間上包含「更淺」——這在無殘差的堆疊上是不成立的,因為每一層都必須做點什麼。
代價是上表中間那一行:輸出的大小隨深度成長(),因為每一層都在往上加。真實的架構用兩種方式處理它——在殘差分支上乘一個小係數(例如 或一個學出來的接近零的初值),或在每一層之後做正規化。下一節是後者。
刻意違反:正規化不是免費的保險
前一節的最後一列有一個沒有被解釋的數字:深度 ,殘差是 ,殘差加 LayerNorm 是 。
加了正規化反而訓練不起來。這和「正規化讓深網路更好訓練」這個常見說法是反的,所以需要解釋。
線索在梯度比那張表:殘差在深度 是 ,殘差加 LN 是 ——LN 讓梯度比變差了。原因是 LayerNorm 在每一層都把訊號投影到一個固定的尺度上,而那個投影會把梯度裡「改變整體大小」的成分消掉(見下面那個精確的量測)。在這個特定的 toy 上,殘差造成的那個成長本來就沒有失控到需要處理,而 LN 的那點損失就變成純虧。
但 LayerNorm 也真的在做一件很具體、很有價值的事。 量出來:
W 乘以 0.01 : max|LN(XWc) - LN(XW)| = 6.853e-03
W 乘以 1.00 : max|LN(XWc) - LN(XW)| = 0.000e+00
W 乘以 100.00 : max|LN(XWc) - LN(XW)| = 6.874e-07
一層的輸出對自己權重的大小完全免疫。 把 放大一百倍,正規化之後的輸出一模一樣( 是浮點誤差; 那個 是 造成的,把 調小它也會消失)。
而這件事對梯度的後果是精確的:
W 乘以 0.1 : 對 W 的梯度範數 = 178.238 (× c = 17.824)
W 乘以 1.0 : 對 W 的梯度範數 = 17.824 (× c = 17.824)
W 乘以 10.0 : 對 W 的梯度範數 = 1.782 (× c = 17.824)
對孤立的 ,忽略 且 時,正向輸出對 不變,相應梯度按 縮放。但權重範數同時乘 ,所以固定步長的相對更新量按 改變,不是自動固定。加入 bias、非線性或殘差後,也要重新檢查這個尺度關係。
正規化買的是「對尺度免疫」,賣的是「梯度裡關於尺度的那一部分」;在尺度本來就沒失控的時候,那是純付出。
所以這兩件事的關係不是「都加上去比較安全」。 殘差解決梯度路徑,正規化解決尺度漂移。真實的深網路兩個都需要,因為它們在寬度、深度、非線性、學習率都放大之後,殘差造成的成長會真的失控。但在這個 寬、、小學習率的 toy 上,第二個問題不存在,於是只剩成本。
這件事在自己的專案上怎麼判斷:量一次每一層輸出的 RMS。如果它隨深度穩定,正規化大概只是在收費;如果它像上表那樣一路爬到幾十幾百,那就是它要解決的問題。
接受域、頻率、深度:三個設定
互動 demo:降取樣次數、skip、深度、接法四個設定,對應三個互相獨立的問題。
一個 U 形要怎麼設計
把三節的結論合成一組可以照做的決定。
- 先算你需要多大的接受域。 這是一個關於任務的問題:判斷要用到的最遠的兩個東西相隔多少個像素?算出來之後,用第一節的兩張表決定「疊深」與「降取樣」怎麼配。
- 再算你能降幾次。 用第二節的規則:要保留尺度為 的特徵,總降取樣倍數不要超過 。如果這兩個數字打架(要看得很遠,又要保留很細的東西),那就是需要 U 形的訊號——降下去取得脈絡,用 skip 把細節帶回來。
- 決定 skip 接什麼、怎麼接。 串接保留兩邊的完整資訊但讓通道數變多;相加比較省但要求兩邊的語意可以直接疊加。輸出需要精確定位(分割、去噪、生成)時,通常串接比較穩。
- 檢查梯度路徑。 toy 的深度門檻不是通用門檻;各層梯度、更新量與訓練表現要一起看。
- 比較正規化的具體版本。 pre-norm、post-norm、affine 與步長都會影響結果;單看 RMS 不能確定加不加 LN。
這一切依賴什麼。 一,資料真的有多尺度結構;如果沒有(例如所有有用的模式都是同一個大小),一個平的堆疊更簡單也更好。二,降取樣的對象要是空間上平滑的;對於本來就沒有「相鄰」概念的輸入,降取樣沒有意義。三,第四、五節的數字是在一個 寬的 堆疊上量的——深度的門檻和正規化的必要性都會隨寬度、非線性與學習率而變,所以那兩個結論要在自己的設定上重量一次,而重量的方法就在上面第 4、5 點。
檢查理解
參考文獻
- Ronneberger, O., Fischer, P. & Brox, T. U-Net: Convolutional Networks for Biomedical Image Segmentation. MICCAI 2015.(編碼–解碼加長跳接的原始設計,以及它為什麼在需要精確定位的任務上是必要的。)
- He, K., Zhang, X., Ren, S. & Sun, J. Deep Residual Learning for Image Recognition. CVPR 2016.(殘差連接、以及「更深不該更差」這個論證。)
- Ba, J., Kiros, J. & Hinton, G. Layer Normalization. 2016.(本篇第五節那個尺度免疫性質的出處與推導。)