VGG16 哪一層的運算量(FLOPs)最多?
原題
VGG16 連題組第二題:在神經網路中,了解各層的運算量分佈,有助於模型壓縮與硬體加速的策略設計。請問在 VGG16 中,下列何者運算量(FLOPs)最多?
白話
同一個動物園影像辨識專案,工程師這次不只看「有多少個參數」,而是想知道「每次做一次前向傳播時,哪種層的計算量(浮點運算次數,FLOPs)最多」。上一題(q42)我們知道全連接層的參數量最多,這題問的是不同的問題:計算量。
問你:在 VGG16 的所有層類型中,哪一種層每次推論時的運算量最多?
先自己選一個答案,再看完整解析。
一句話總結
VGG16 裡運算量最多的是卷積層(Conv2d):卷積核在大型特徵圖的每個空間位置重複做乘加運算,VGG16 整體約 15.5 GFLOP 中,卷積層佔了超過 95%。
情境
先感受問題:參數少不代表算得快
動物園工程師收到了一張 224×224 的長頸鹿照片,要用 VGG16 分類。上一題他發現全連接層參數最多,這次他想知道:「推論一張圖要計算多少次浮點運算?哪層最耗時?」
這就是 FLOPs(浮點運算次數)的重要性:參數量決定模型檔案有多大,FLOPs 決定每次推論要算多少次,這是硬體加速、邊緣部署時最關鍵的指標。
關鍵差異:卷積層雖然每個核心的參數量不多,但它要在整張特徵圖的每個空間位置重複執行所有乘加運算。一張 224×224 的影像,光第一層 Conv2d 就有 224×224 = 50,176 個空間位置,每個位置都要跑一遍 3×3×3 的乘加,計算量巨大。
相比之下,全連接層雖然參數最多,但每個參數只用一次,不像卷積層要在空間上重複使用。
舊方法
「參數多就算得多」為什麼是錯誤直覺?
- 參數量和 FLOPs 是不同指標:參數量衡量模型大小(儲存),FLOPs 衡量推論速度(計算)。一個層可以參數少但計算量大,也可以參數多但計算量相對少。
- 卷積的空間重複性:一個 3×3×512×512 的卷積核有約 236 萬個參數,但它要在 14×14 = 196 個空間位置各執行一次,總計算量是 236萬 × 196 ≈ 4.6 億次乘加。
- 全連接層的單次執行:Linear-33 有約 1.03 億個參數,但推論時只執行一次矩陣向量乘法,FLOPs ≈ 2 × 25,088 × 4,096 ≈ 2.06 億次乘加。
- 早期卷積層特徵圖很大:第一層 Conv2d 處理 224×224 的影像,後面的層特徵圖逐漸縮小(112→56→28→14→7),但仍有大量空間位置要計算。
- ReLU 和池化層 FLOPs 極少:ReLU 只做 max(0, x),池化只做比較或加法,計算量遠小於卷積和全連接。
新方法
卷積層:在大特徵圖上滑動帶來巨量計算
動物園工程師用 fvcore 計算 VGG16 的 FLOPs 分析:
- 13 層 Conv2d 加總:約 15.4 GFLOP(佔總運算量 99% 以上)
- 3 層 Linear 加總:約 0.124 GFLOP(不到 1%)
- ReLU、MaxPool2d:微量比較操作,幾乎可忽略
最大的卷積層是第三組(224×224 → 112×112,64 通道 → 128 通道),每層就有約 1.85 GFLOP。即使最後一組(14×14,512 通道)特徵圖很小,因為通道數多(512×512),計算量仍然可觀。
這個發現解釋了為什麼 GPU 對 CNN 的加速效果最明顯:GPU 擅長的正是「大量平行的小矩陣乘法」,而卷積運算正是這樣的結構。
這就是選項 A 講的:卷積層(Conv2d)的運算量最多。
中級考試大概率會考程式碼跟公式,所以這部分你還是要學。但如果現在學起來很痛苦,可以先跳過,等讀完其他題目回頭再來。
Step 1 純故事版(不出現公式)
想像卷積層是一個用放大鏡掃描整幅畫的人,放大鏡是 3×3 大小,要從左上角一格一格滑到右下角,每格都做一次完整計算。畫越大,要滑的格子越多,計算越多。
全連接層像是把所有資訊彙整到一個大型報告,雖然報告很長,但只寫一次就結束了。
所以卷積層雖然「放大鏡本身」(核心權重)不大,但因為要在整幅畫上來回掃描,總計算量遠超只寫一份報告的全連接層。
Step 2 中文 ↔ 公式對照
| 白話說法 | 公式 / 數字 |
|---|---|
| 卷積層一次乘加的次數 | K×K×C_in×C_out×H_out×W_out × 2 |
| VGG16 第一層 Conv2d(64 通道) | 3×3×3×64×224×224×2 ≈ 0.173 GFLOP |
| 全連接層乘加次數 | input_size × output_size × 2 |
| Linear-33(25088→4096) | 25088×4096×2 ≈ 0.206 GFLOP |
| VGG16 卷積層合計 | ≈ 15.4 GFLOP(佔 99%+) |
Step 3 符號角色表
- FLOPs(Floating Point Operations):浮點運算次數,衡量一次前向傳播需要多少計算量
- K:卷積核的大小(VGG16 全部用 3×3,所以 K=3)
- C_in / C_out:輸入通道數 / 輸出通道數
- H_out × W_out:輸出特徵圖的空間大小,卷積 FLOPs 的關鍵倍數因子
- GFLOP:10 億次浮點運算,GPU 算力常用單位
Step 4 完整公式對應
卷積層 FLOPs = 2 × K² × C_in × C_out × H_out × W_out VGG16 各組卷積的 FLOPs(約估): Block 1(224×224, 3→64→64): 0.173 + 0.345 ≈ 0.52 GFLOP Block 2(112×112, 64→128→128): 0.692 + 1.385 ≈ 2.08 GFLOP Block 3(56×56, 128→256×3): 2 × 1.385 + 2.771 ≈ 5.54 GFLOP Block 4(28×28, 256→512×3): 3 × 2.771 ≈ 8.31 GFLOP ← 最多的一組 Block 5(14×14, 512→512×3): 3 × 0.693 ≈ 2.08 GFLOP 合計 ≈ 15.5 GFLOP 全連接層 FLOPs(約估): Linear-33: 2×25088×4096 ≈ 0.206 GFLOP Linear-36: 2×4096×4096 ≈ 0.034 GFLOP Linear-39: 2×4096×1000 ≈ 0.008 GFLOP 合計 ≈ 0.124 GFLOP 卷積 vs 全連接:15.5 / 0.124 ≈ 125 倍
Step 5 自我複述
- 為什麼 q42 說全連接層參數最多,而 q43 說卷積層 FLOPs 最多?兩者的差異是什麼?
- 卷積層 FLOPs 的公式裡為什麼有 H_out × W_out?這個因子代表什麼?
- VGG16 後面的 Block 4(28×28)比 Block 3(56×56)特徵圖小,為什麼 Block 4 的 FLOPs 還是更多?
- GPU 為什麼特別適合加速卷積層而非全連接層?
- 如果要讓 VGG16 在行動裝置上更快,應該優先壓縮哪種層?
錯選項
為什麼其他選項是錯的
B全連接層(Linear)
字面在說什麼
全連接層參數最多,所以 FLOPs 也最多。
為什麼不對
全連接層雖然參數量佔 VGG16 的 89.4%,但每個參數只用一次(矩陣向量乘法),FLOPs 約為 0.124 GFLOP。卷積層的參數雖然少,但每個位置都要重複計算,FLOPs 達 15.5 GFLOP,是全連接層的 125 倍。參數量多不代表 FLOPs 多。
誰會選錯
把上一題(參數最多)的答案直接套用到這題,以為「最胖的層就算得最多」,沒注意到 FLOPs 和參數量是兩個完全不同的指標。
CReLU 激活函數
字面在說什麼
ReLU 激活函數的運算量最多。
為什麼不對
ReLU 只做 max(0, x),每個元素一次比較運算,FLOPs 極低,通常在 FLOPs 統計中直接忽略或歸入「其他」。它不做乘法,只做比較,是所有層中運算最簡單的。
誰會選錯
以為激活函數到處都有(每個卷積後都跟著 ReLU)、所以累積起來最多。數量多並不代表每次計算量大。
D池化層(MaxPool2d, AdaptiveAvgPool2d)
字面在說什麼
池化層的運算量最多。
為什麼不對
MaxPool2d 在 2×2 窗口取最大值,每個輸出元素只做 4 次比較,沒有乘法運算,FLOPs 極低。AdaptiveAvgPool2d 類似,做簡單的平均計算。兩者的計算量都比卷積層少幾個數量級。
誰會選錯
覺得池化層「負責縮小特徵圖、很重要」,誤以為重要的工作就要做很多計算。功能重要性和計算量是不同維度。
變形題
同個考點下次怎麼變形
答案
卷積層是「參數少、FLOPs 多」的典型;全連接層是「參數多、FLOPs 相對少」的典型。BatchNorm 是「參數少(只有 2 × C)、FLOPs 也少」的例子。Transformer 的 Self-Attention 是「參數少但 FLOPs 隨序列長度二次方成長」的極端案例。
答案
1. 使用 GPU/TPU 做卷積加速(CUDA cuDNN 對卷積有高度優化);2. 量化(Quantization)把浮點運算換成整數,減少每次乘加的時間;3. 用 MobileNet、EfficientNet 等以深度可分離卷積(Depthwise Separable Conv)替換標準卷積,FLOPs 可降低 8-9 倍。
答案
標準卷積一次把所有通道都乘加;深度可分離卷積分兩步:先對每個通道獨立做空間卷積(Depthwise Conv),再用 1×1 卷積做通道混合(Pointwise Conv)。FLOPs 從 K²×C_in×C_out 降到 K²×C_in + C_in×C_out,對 3×3 卷積約降低 8-9 倍。
答案
卷積層的 FLOPs 與輸入面積成正比,縮小一半(線性)等於面積縮小 4 倍,所以卷積層 FLOPs 減少約 4 倍,整體約降到原來的 25%。這也是為什麼行動端部署常先縮小輸入解析度。
答案
使用 `fvcore` 套件:`from fvcore.nn import FlopCountAnalysis; flops = FlopCountAnalysis(model, input_tensor); print(flops.total())`。或用 `thop` 套件:`from thop import profile; macs, params = profile(model, inputs=(input,))`,MACs(Multiply-Accumulate Operations)≈ FLOPs/2。
延伸
想再往下看,這 5 個
- 卷積神經網路(CNN)
本題核心架構,卷積層的空間滑動特性是 FLOPs 佔比最高的根本原因。 - 模型壓縮(Model Compression)
知道卷積層佔 FLOPs 的 99% 後,壓縮策略就要針對卷積層,例如深度可分離卷積、剪枝、量化。 - 模型量化(Quantization)
把浮點運算(32-bit)轉成整數(8-bit),直接降低每次卷積的計算成本,是邊緣部署最常用的加速方法。 - GPU(圖形處理器)
GPU 的平行計算架構對卷積的大量矩陣乘法高度友好,這是 GPU 成為深度學習標準硬體的原因。 - 遷移學習(Transfer Learning)
VGG16 連題組的核心應用,了解 FLOPs 分布有助於決定遷移學習時哪些層值得凍結或重訓練。