L4.3 一張圖裡同時有紋理、物件和整個場景,一個固定大小的核怎麼辦?
起點:一個核只看得到一個尺度
同一個東西換個位置出現,要怎麼讓模型知道那還是同一個東西? 的整個實驗都在同一個尺度上:線是 個像素長,核是 ,一層就看得完。
真實的資料不是這樣。一張照片裡同時有紋理(幾個像素的週期性)、物件(幾十個像素)、和整個場景的構圖(整張圖)。而「這是貓還是狗」這個判斷可能需要同時用到毛的質感和耳朵的形狀,兩者差了兩個數量級的尺度。
一個 的核只看 個像素。要看得更遠只有一條路:疊。疊 層之後,最終的輸出受到多大一塊輸入的影響?這塊區域叫接受域(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)層到 ,而平的堆疊要 層。 而且計算量還更少——第 次降取樣之後,每一層的位置數只剩原來的 (二維)。兩件事同時變好,所以降取樣不是一個折衷,它在「看得遠」這個目標上是純賺。
代價是什麼。 降取樣把相鄰的幾個值合成一個。一個在兩三個取樣點的尺度上變化的東西——一條細線、一個邊界的確切位置、一段高頻紋理——在合併之後就不見了。
而且它回不來。 升取樣(把一個值複製成兩個、或內插)只能造出「在這個尺度上平滑」的東西,它沒有任何資訊可以用來重建那些細節。這不是實作不夠好,是資訊已經被刪掉了。
所以問題變成:這個代價要不要付?
- 如果輸出是低維的(一個類別、一個分數),那細節本來就要被丟掉,降取樣只是提早做了這件事。這就是分類網路的形狀:一路降到底。
- 如果輸出和輸入一樣大而且需要細節(分割的邊界、去噪後的影像、生成的圖),那丟掉就是致命的——你要輸出的正是那些被刪掉的東西。
第二種情況的解法只有一個形狀:讓細節不要經過那個瓶頸。編碼側一路降取樣去取得大的接受域,解碼側一路升回來,而每一層的細節從編碼側直接橫跨過去接到對應的解碼層。那條橫跨的連線就是 skip connection,而那個形狀畫出來是一個 U。
降取樣毀掉的到底是什麼
上面說「高頻回不來」是定性的。把它量出來。
做法很單純:拿一個純頻率的訊號(長度 的餘弦),做一次 平均池化再用最近鄰升回原長度,然後問兩件事——同一個頻率剩下多少振幅,以及整條訊號還差多遠。
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
最後一列是乾淨的零。 週期剛好是兩個取樣點的成分()在 平均之後每一組都變成 ——完全消失,不是變小。
中間幾列是實務上真正會遇到的區域。 週期 個取樣點還剩 ,週期 個剩 ,週期 個只剩 。也就是說,只要一個特徵的尺度小於大約五、六個取樣點,一次降取樣就會吃掉它一半以上。
而右邊那一欄說得更直接:週期 個取樣點的訊號,降一次再升回來,整體誤差已經是 。降兩次就是在對已經模糊的東西再模糊一次。
降取樣不是把細節壓縮,是把細節刪掉;升取樣造得出平滑的東西,造不出被刪掉的東西。
這張表也給了一個可以直接用的設計規則。 要保留一個尺度為 個像素的特徵,降取樣的總倍數不能超過大約 。細胞邊界寬 個像素?那一層都不能降——或者就必須用 skip 把它繞過去。
注意表裡有一列不是單調的,而那是混疊
仔細看會發現 (週期 )的保留振幅是 ,比 (週期 )的 還高。這不是量測誤差。
原因是混疊(aliasing):降取樣不只是把高頻變弱,它還把高頻搬到別的頻率去。 在 降取樣之後正好落在新取樣率的奈奎斯特頻率上,於是它的能量以一個特殊的方式保留下來;而 的能量有一部分被搬到 那裡去,變成一個原本不存在的低頻成分。
右邊那一欄(整體重建誤差 對 )就沒有這個非單調——因為它把「搬到別處去」也算成誤差。
實務上的後果是:降取樣之前通常要先低通濾波(先模糊再取樣),否則高頻會偽裝成低頻混進來。這也是為什麼在生成模型裡,單純用 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
三種行為完全不同。無殘差在收縮(,因為 是壓縮的);殘差在膨脹(,因為每一層都在往上加東西);加了 LayerNorm 之後是精確的常數 ——那正是 LayerNorm 的定義在做的事。
再看梯度能不能傳回去(第一層與最後一個隱藏層的梯度大小比, 表示兩端一樣強):
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
看深度 那一列:無殘差是 (前面的層收到的梯度只有後面的十四分之一),殘差是 (只差兩倍)。殘差把梯度的路徑從「每一層都要乘一次」變成「有一條直達的路」——因為 ,那個 讓梯度可以不經過任何權重矩陣就傳到前面。
最後看真的訓練得起來嗎:
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)
梯度精確地正比於 (第三欄四位數完全相同)。也就是說,權重越大、梯度越小,所以相對的更新量 自動維持穩定。這正是「正規化讓學習率比較好調」這個經驗的機制:它把一個原本要人工對齊的尺度變成自動的。
正規化買的是「對尺度免疫」,賣的是「梯度裡關於尺度的那一部分」;在尺度本來就沒失控的時候,那是純付出。
所以這兩件事的關係不是「都加上去比較安全」。 殘差解決梯度路徑,正規化解決尺度漂移。真實的深網路兩個都需要,因為它們在寬度、深度、非線性、學習率都放大之後,殘差造成的成長會真的失控。但在這個 寬、、小學習率的 toy 上,第二個問題不存在,於是只剩成本。
這件事在自己的專案上怎麼判斷:量一次每一層輸出的 RMS。如果它隨深度穩定,正規化大概只是在收費;如果它像上表那樣一路爬到幾十幾百,那就是它要解決的問題。
接受域、頻率、深度:三個旋鈕
互動 demo:降取樣次數、skip、深度、接法四個旋鈕,對應三個互相獨立的問題。
回到情境:一個 U 形要怎麼設計
把三節的結論合成一組可以照做的決定。
- 先算你需要多大的接受域。 這是一個關於任務的問題:判斷要用到的最遠的兩個東西相隔多少個像素?算出來之後,用第一節的兩張表決定「疊深」與「降取樣」怎麼配。
- 再算你能降幾次。 用第二節的規則:要保留尺度為 的特徵,總降取樣倍數不要超過 。如果這兩個數字打架(要看得很遠,又要保留很細的東西),那就是需要 U 形的訊號——降下去取得脈絡,用 skip 把細節帶回來。
- 決定 skip 接什麼、怎麼接。 串接保留兩邊的完整資訊但讓通道數變多;相加比較省但要求兩邊的語意可以直接疊加。輸出需要精確定位(分割、去噪、生成)時,通常串接比較穩。
- 深度超過大約二三十層才需要煩惱殘差。 第四節的表在深度 以下三種接法完全沒有差別。
- 正規化要看訊號有沒有在漂。 量一次各層的 RMS 再決定,不要當成預設配備——第五節那個 就是預設加上去的代價。
這一切依賴什麼。 一,資料真的有多尺度結構;如果沒有(例如所有有用的模式都是同一個大小),一個平的堆疊更簡單也更好。二,降取樣的對象要是空間上平滑的;對於本來就沒有「相鄰」概念的輸入,降取樣沒有意義。三,第四、五節的數字是在一個 寬的 堆疊上量的——深度的門檻和正規化的必要性都會隨寬度、非線性與學習率而變,所以那兩個結論要在自己的設定上重量一次,而重量的方法就在上面第 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.(本篇第五節那個尺度免疫性質的出處與推導。)