Skip to content

CS231N A2 導讀:BatchNorm、Dropout、CNN、PyTorch 與 RNN Captioning

2026年9月30日1 分鐘
TL;DRCS231N Spring 2026 的 A2 佔總成績 18%,五個 notebook 從手寫 BatchNorm/LayerNorm、Dropout、卷積與池化的 forward/backward,一路走到 PyTorch 的三層抽象,最後用 PyTorch 在 COCO 上做 RNN 影像描述。轉折點在 Q4:前三題的梯度要自己推,Q5 起交給 autograd,再用數值梯度檢查驗證。官方投影片提醒這是三份作業裡最長的一份。

🌏 English version

版本說明:作業依據 CS231N Spring 2026 的 Assignment 2 頁面與可下載的 assignment2.zip(2026-09-30 下載,notebook 與 cs231n/ 模組逐一打開核對)。對應的課堂錄影請用 Spring 2025 YouTube 播放清單,2026 錄影只放在 Canvas,限修課生;兩個年份的內容可能不同。存取等級 A3:題目頁與起始碼全公開;拿不到的是 Gradescope 自動評分、Ed 公告(包括第 9 講提到的 notebook 修正說明)與成績。本文只整理題目在練什麼,不給解答。

系列位置:上一篇 L7:循環神經網路與影像描述|下一篇 L8:Attention、Transformer 與 ViT|系列總覽

A1 讓你用 numpy 手寫出一個全連接網路。A2 接著問兩件事:網路變深以後,怎麼讓它還訓練得動?什麼時候該把手寫的反向傳播交給框架?

五道題剛好排成一條從「自己推梯度」到「交給 PyTorch」的斜坡。作業總頁把 A2 定為總成績的 18%,是三份作業裡權重最高的一份。第 9 講投影片第 2 頁也提醒:A2 是三份裡最長的,截止後緊接著期中考與專題 milestone,要早點開始。

這份作業長什麼樣子

題目Notebook你要改的檔案對應講次
Q1 Batch NormalizationBatchNormalization.ipynbcs231n/layers.py、classifiers/fc_net.pyL6
Q2 DropoutDropout.ipynbcs231n/layers.py、classifiers/fc_net.pyL6
Q3 卷積網路ConvolutionalNetworks.ipynbcs231n/layers.py、classifiers/cnn.pyL5、L6
Q4 PyTorch on CIFAR-10PyTorch.ipynbnotebook 本身4/24 PyTorch review session
Q5 RNN 影像描述RNN_Captioning_pytorch.ipynbcs231n/rnn_layers_pytorch.py、classifiers/rnn_pytorch.pyL7

作業頁寫的截止時間是 2026 年 5 月 8 日(週五)晚上 11:59(PST)。第 8 講投影片第 2 頁寫的是「due 5/7」,兩者差一天,以作業頁為準。

另外有一個對不上的地方要先講:作業總頁列的 A2 主題是「Batch Normalization, Dropout, Convolutional Nets, Network Visualization, Image Captioning with RNNs」,裡面有 Network Visualization、沒有 PyTorch。但作業頁與 zip 裡實際的第四題是 PyTorch,沒有任何可視化 notebook。本文以作業頁與起始碼為準。

整份作業在 Colab 上跑。做完前五個 notebook 後執行 collect_submission.ipynb,它會打包 a2_code_submission.zip,並把所有 notebook 轉成一份 a2_inline_submission.pdf,兩個檔案一起交到 Gradescope。作業頁特別提醒:notebook 的執行順序要是由上到下,否則自動評分可能出錯,必要時用「Restart and Run All」重跑。

Q1:BatchNorm 與 LayerNorm

場景:A1 的全連接網路疊到五、六層以後,初始化稍微沒調好就訓練不動。

Notebook 開頭引用 Ioffe & Szegedy 2015 的假設:網路深處每一層看到的特徵分布,會隨著前面的權重更新一直漂移,讓訓練變難。BatchNorm 的做法是在網路裡插入正規化層,訓練時用 minibatch 估計平均與變異數,測試時改用訓練期間累積的 running average。

你要在 layers.py 裡寫出:

  1. batchnorm_forward:訓練模式與測試模式要分開處理。
  2. batchnorm_backward:照計算圖一步一步反傳。
  3. batchnorm_backward_alt:在紙上把梯度化簡後的版本。Notebook 拿 sigmoid 類比:sigmoid 的 backward 可以逐步反傳,也可以先在紙上化簡成一個簡單公式,BatchNorm 也能這樣化簡。
  4. 把 BatchNorm 接進 FullyConnectedNet,接著比較有、沒有 BatchNorm 的深層網路。

之後的兩個實驗各配一題 inline question:改變權重初始化的尺度,觀察有、沒有 BatchNorm 的差別;改變 batch size,觀察 BatchNorm 的表現如何跟著變。

BatchNorm backward 的起點(notebook 給的定義)

Notebook 在 alternative backward 一節先寫出 forward 的四個式子,讓你從這裡開始化簡:

μ   = (1/N) Σ_k x_k
v   = (1/N) Σ_k (x_k − μ)²
σ   = sqrt(v + ε)
y_i = (x_i − μ) / σ

難點在於 μ 和 σ 都依賴整個 batch,所以每個 x_i 的梯度會經由三條路徑回來:直接經過 y_i、經過 μ、經過 v。第一版照計算圖把三條路徑分開算,第二版把它們合併成一條式子。

後半段換成 Layer Normalization(Ba、Kiros 與 Hinton):它對每一筆資料自己的所有特徵做正規化,不依賴 batch。你要寫 layernorm_forward/layernorm_backward,再做一次 batch size 實驗。這一段的兩題 inline question 很適合自我檢查:

  • 四種影像前處理裡,哪一種類似 BatchNorm、哪一種類似 LayerNorm?
  • 在什麼情況下 LayerNorm 可能效果不好?(選項是很深的網路、特徵維度很小、正則化項很大)

Q2:Dropout

Dropout.ipynb 比較短。你要寫 dropout_forward 與 dropout_backward,接進 FullyConnectedNet,最後做一個正則化實驗:比較有、沒有 dropout 時的訓練與驗證準確率。

這題的 inline question 值得先想再寫:inverted dropout 如果不除以 p,會發生什麼事?答案跟訓練與測試兩種模式的輸出期望值有關。

Q3:卷積網路

這是 A2 手寫梯度的最後一站,也是最長的一題。Notebook 開頭的說法是:全連接網路計算效率高,適合拿來實驗,但實務上最好的結果都來自卷積網路。

依序要做:

  1. Naive 卷積:conv_forward_naive、conv_backward_naive。中間有一段 aside,示範用卷積做影像處理。
  2. Naive max pooling:max_pool_forward_naive、max_pool_backward_naive。
  3. Fast layers:官方已經在 fast_layers.py 提供快速版,靠 Cython 擴充。第一次要執行一個編譯 cell,存檔,重啟 runtime,再從頭跑一次。
  4. Sandwich layers 與三層 ConvNet:在 classifiers/cnn.py 完成 ThreeLayerConvNet,照 sanity check loss → gradient check → overfit 小資料 → 正式訓練 → 可視化第一層 filter 的順序走。
  5. Spatial BatchNorm:把 Q1 的 BatchNorm 推廣到 (N, C, H, W) 的特徵圖。
  6. Spatial Group Normalization:notebook 引用 LayerNorm 論文的觀察,在卷積層上 LayerNorm 不如 BatchNorm,因為靠近影像邊緣的單元統計性質跟其他單元差很多。Group Normalization(Wu & He)的折衷做法是把每筆資料的通道切成 G 組,逐組正規化。

「sanity check → gradient check → overfit 小資料」這個順序是整門課反覆使用的除錯流程。第 4 步讓你在 Q3 再完整走一次,養成習慣比寫對公式更重要。

Q4:PyTorch,同一個網路寫三次

Q4 是整份作業的轉折點。Notebook 的說法很直接:你已經懂框架的內部了,現在可以放心用框架。用 PyTorch 可以直接跑 GPU、不必寫 CUDA,也能讓期末專題的實驗快很多。

PyTorch.ipynb 分五部分,用三種抽象層級寫同一批模型:

部分抽象層級做法
Part II Barebones層級 1直接操作 Tensor,自己管參數與初始化
Part III Module API層級 2繼承 nn.Module,在 __init__ 定義層、在 forward 串起來
Part IV Sequential API層級 3用 nn.Sequential 把前饋堆疊寫成一行
Part V CIFAR-10 挑戰自選自己設計網路

Notebook 附了一張取捨表:Barebones 彈性高、方便性低;nn.Module 彈性高、方便性中等;nn.Sequential 彈性低、方便性高。

每一層都會訓練一個兩層全連接網路與一個三層 ConvNet(32 個 5×5 filter → ReLU → 16 個 3×3 filter → ReLU → 全連接輸出 10 類),並給出「一個 epoch 後應該看到的準確率」當 sanity check。例如 Barebones 版三層 ConvNet 應該超過 42%,Sequential 版改用 Nesterov momentum 0.9 的 SGD,應該超過 55%。

Part V 的要求是:10 個 epoch 內在 CIFAR-10 驗證集上達到至少 70%。層、optimizer、超參數都可以自己挑。Notebook 列了幾個方向:filter 大小、filter 數量、max pooling 與 strided convolution 的取捨、在卷積層後加 spatial batch norm(在 PyTorch 叫 BatchNorm2d)、加深網路。最後要在 notebook 末尾描述你做了什麼,測試集只能跑一次。

如果你對 PyTorch 還陌生,先看課表上 4/24 PyTorch Review Session 的 Colab notebook。它從 Tensor、broadcasting、autograd 講起,接著是建一個簡單網路、Dataset 與 DataLoader、FashionMNIST,再比較 CPU 與 GPU 的訓練速度,最後講 pre-trained weights。

Q5:用 PyTorch 做 RNN 影像描述

最後一題把 L7 的 RNN 接上 CNN 特徵,在 COCO 上產生圖片描述。

資料:notebook 用 2014 年版的 COCO,約 8 萬張訓練圖、4 萬張驗證圖,每張有 5 句 Amazon Mechanical Turk 標註的描述。圖片不必自己過 CNN:官方已經從 ImageNet 預訓練的 VGG-16 抽出 fc7 特徵,再用 PCA 從 4096 維降到 512 維。原圖將近 20 GB,所以沒有附在下載檔裡,只給 Flickr URL 方便可視化。描述文字已經編碼成整數 ID 序列。

要寫的部分,全部放在 rnn_layers_pytorch.py 與 classifiers/rnn_pytorch.py:

  • rnn_step_forward、rnn_forward:vanilla RNN 的單步與整段序列。
  • word_embedding_forward:詞 ID 轉向量。
  • temporal_affine_forward、temporal_softmax_loss:每個時間步的輸出層與 loss(有 mask 處理不同長度)。
  • CaptioningRNN 的 loss 與 sample。

轉折就在這裡:notebook 明講,因為用 PyTorch 寫,backward 交給 autograd,rnn_step_backward 等函式不必實作。你仍然要用數值梯度檢查器驗證 autograd 的結果;想挑戰的話,也可以自己寫 backward,但不是必做。

sample 方法處理訓練與測試的落差。訓練時每一步餵入正確答案的詞;測試時從詞彙分布抽樣,再把抽到的詞當成下一步的輸入。Notebook 預告:在過擬合的小模型上,訓練資料的抽樣結果會很好,驗證資料則多半不通順。

起始碼的 CaptioningRNN 也接受 cell_type='lstm',rnn_layers_pytorch.py 裡也有 lstm_step_forward/lstm_forward 的空殼。不過 notebook 只要求 vanilla RNN,只寫了一句「you will implement the LSTM case later」。A2 頁面與 notebook 都沒有列出 LSTM 題目。

唯一的 inline question 問:改用字元級RNN 做描述,有什麼優點與缺點?提示是比較字元級與詞級模型的參數空間。

自學怎麼做

  1. 先補兩講:Q1–Q3 依賴 L5–L6,Q5 依賴 L7。先看完 2025 播放清單的 Lecture 5–7 再開工。
  2. Q1 的兩版 backward 都寫:化簡版是全作業最好的「計算圖 vs 手推」練習,也是 L4 反向傳播的延伸。
  3. Q4 之前做 PyTorch review Colab:一個下午就能跑完,Part V 會輕鬆很多。
  4. Part V 開 GPU:在 Colab 用 Runtime → Change runtime type 切到 GPU,而且要在 import 之前切,因為切換會重啟 kernel。
  5. 遵守 Honor Code:作業總頁寫明往年解答流傳在網路上,官方要求作業是自己的成果。生成式 AI 的使用比照合作規範:要獨立寫出答案、註明合作性質,用 AI 大幅完成作業內容違反 Honor Code。

延伸閱讀

參考資料