返回文章列表

深度學習模型架構演進與效能分析

本文探討深度學習模型架構的演進,從SqueezeNet的輕量化設計到ResNet的跳躍連線,再到DenseNet的稠密連線和深度可分離卷積的應用,以及NASNet的自動化搜尋和MobileNetV2的效能提升,分析不同架構的特性、優勢和應用場景,並提供程式碼範例和效能比較。

深度學習 模型架構

深度學習模型架構的發展持續推動著人工智慧技術的進步。從早期注重輕量化的SqueezeNet,到引入跳躍連線的ResNet,再到強調特徵重用的DenseNet,以及深度可分離卷積和神經架構搜尋等技術的興起,模型架構的設計理念不斷演變,以追求更高的效能、更低的計算成本和更廣泛的應用場景。SqueezeNet透過Fire模組精簡架構,ResNet利用跳躍連線解決梯度消失問題,DenseNet則透過密集連線提升特徵重用率。深度可分離卷積的出現進一步降低了計算量,而NASNet則透過自動化搜尋探索更優的架構設計。MobileNetV2的倒置殘差瓶頸結構則在效能和效率之間取得了更好的平衡。

模組化架構的演進:SqueezeNet與ResNet

SqueezeNet的創新與實作

SqueezeNet是一種簡化版的卷積神經網路架構,主要透過Fire模組的設計來減少引數數量。Fire模組的核心概念是使用1x1的卷積層來減少輸入通道數,接著使用1x1和3x3的卷積層來擴充套件特徵圖。

Fire模組實作

def fire_module(squeeze, expand):
    return lambda x: fire(x, squeeze, expand)

def fire(x, squeeze, expand):
    y = tf.keras.layers.Conv2D(filters=squeeze, kernel_size=1, activation='relu', padding='same')(x)
    y = tf.keras.layers.BatchNormalization()(y)
    y1 = tf.keras.layers.Conv2D(filters=expand//2, kernel_size=1, activation='relu', padding='same')(y)
    y1 = tf.keras.layers.BatchNormalization()(y1)
    y3 = tf.keras.layers.Conv2D(filters=expand//2, kernel_size=3, activation='relu', padding='same')(y)
    y3 = tf.keras.layers.BatchNormalization()(y3)
    return tf.keras.layers.concatenate([y1, y3])

SqueezeNet架構實作

x = tf.keras.layers.Input(shape=[IMG_HEIGHT, IMG_WIDTH, 3])
y = tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu')(x)
y = tf.keras.layers.BatchNormalization()(y)
y = fire_module(16, 32)(y)
y = tf.keras.layers.MaxPooling2D(pool_size=2)(y)
# ... 其他層的堆積疊
y = tf.keras.layers.GlobalAveragePooling2D()(y)
y = tf.keras.layers.Dense(len(CLASSES), activation='softmax')(y)
model = tf.keras.Model(x, y)

內容解密:

  1. Fire模組的作用:Fire模組首先使用1x1的卷積層減少輸入通道數,接著使用1x1和3x3的卷積層擴充套件特徵圖。這種設計可以有效減少引數數量,同時保持模型的表達能力。
  2. SqueezeNet的架構特點:SqueezeNet透過堆積疊多個Fire模組和最大池化層來構建深度網路。最終使用全域性平均池化和softmax層進行分類別。
  3. 引數數量與效能:SqueezeNet在ImageNet上的準確率達到76%,而引數數量僅為2.7M,遠低於其他模型如AlexNet。

ResNet與跳躍連線

ResNet透過引入跳躍連線(skip connections)來解決深度神經網路訓練中的梯度消失問題。跳躍連線允許訊號直接跨越多層傳遞,有助於梯度的反向傳播。

殘差塊(Residual Block)的設計

此圖示顯示了殘差塊的基本結構,其中輸入x透過卷積路徑C(x)後與原始輸入x相加,形成輸出f(x)。

內容解密:

  1. 殘差學習的概念:ResNet的核心思想是學習輸入與輸出之間的殘差,而不是直接學習輸出。這使得網路更容易訓練。
  2. 跳躍連線的作用:跳躍連線允許梯度直接流過網路,減少了梯度消失的問題。同時,它使得網路可以被視為多個淺層網路的集合,提高了訓練效率。
  3. ResNet的不同變體:ResNet有多種不同深度的版本,如ResNet50和ResNet101,透過堆積疊不同數量的殘差塊來實作。

深度解析ResNet與DenseNet架構

ResNet架構的創新與優勢

ResNet(殘差網路)透過引入跳躍連線(skip connections)革新了深度學習架構,使極深的神經網路能夠有效訓練。Li等人在「Visualizing the Loss Landscape of Neural Nets」研究中,透過3D視覺化損失函式的拓撲結構,展示了跳躍連線如何使最佳解更容易被找到(圖3-31)。實驗結果證明,使用跳躍連線後,損失函式的全域性最小值變得更容易被存取。


### ResNet架構重點整理
- **架構特點**:使用跳躍連線的卷積模組
- **發表來源**:Kaiming He等,2015年,[論文連結](https://arxiv.org/abs/1512.03385)
- **程式碼範例**:03g_finetune_RESNET50_flowers104.ipynb 和 03g_fromzero_RESNET50_flowers104.ipynb

ResNet效能表現

模型名稱引數數量(不含分類別層)ImageNet準確率104種花卉F1分數(微調)104種花卉F1分數(從零訓練)
ResNet5023M75%94%(精確度:95%,召回率:94%)73%(精確度:76%,召回率:72%)
InceptionV3(對比)22M78%95%(精確度:95%,召回率:94%)-
SqueezeNet(對比)2.7M-精確度:77%,召回率:75%-

ResNet架構解讀

ResNet的主要目標是使非常深的架構能夠有效訓練與收斂。雖然其分類別效能略低於InceptionV3,但其設計理念極具創新性。除了ResNet50,還有ResNet101和ResNet152等變體可供選擇。

DenseNet架構的創新與優勢

DenseNet架構進一步拓展了跳躍連線的概念,將每一層的輸出都傳遞給後續所有層,透過通道級別的拼接(concatenation)來整合資料。這種設計不僅提高了特徵的重用率,還大幅減少了所需的引數量。


### DenseNet基本單元:密集區塊
在密集區塊中,每一對卷積層都會接收所有前序層的輸出,並透過通道拼接來整合資料。所有卷積層均使用ReLU啟用函式和批次正規化。

DenseNet架構特點

  1. 密集連線:每一層的輸出都與後續所有層輸入進行拼接。
  2. 通道控制:透過1x1卷積將通道數控制在較低範圍(K值)。
  3. 線性增長:通道數量隨層數線性增長,而非指數增長。
# DenseBlock 簡化範例
def dense_block(inputs, growth_rate, num_layers):
    for i in range(num_layers):
        # BN-ReLU-Conv(1x1) 減少通道維度
        x = BatchNormalization()(inputs)
        x = ReLU()(x)
        x = Conv2D(growth_rate * 4, (1, 1), padding='same')(x)
        
        # BN-ReLU-Conv(3x3) 主要卷積運算
        x = BatchNormalization()(x)
        x = ReLU()(x)
        x = Conv2D(growth_rate, (3, 3), padding='same')(x)
        
        # 通道拼接
        inputs = Concatenate()([inputs, x])
    return inputs

#### 內容解密:
1. **BatchNormalization()**批次正規化有助於穩定訓練過程並加速收斂
2. **ReLU()**啟用函式提供非線性變換能力
3. **Conv2D()**卷積運算其中1x1卷積用於降維而3x3卷積進行主要特徵提取
4. **Concatenate()**將當前層輸出與所有前序層輸出在通道維度上進行拼接實作密集連線

DenseNet架構解析

DenseNet的設計哲學強調特徵重用,每一層都能存取之前所有層的特徵圖,這使得網路能夠以更少的引數達到良好的效能。DenseNet121是常見的組態,其成長率K=32,表示每層新增32個通道。


### DenseNet效能特點
- **引數效率**:相較於其他架構,DenseNet在引數量上更為節省。
- **特徵重用**:密集連線機制使得特徵能夠被充分重用。
- **可擴充套件性**:能夠輕鬆擴充套件至200層以上。

深度可分離卷積與DenseNet架構解析

DenseNet架構綜覽

DenseNet是一種具備稠密跳躍連線的卷積神經網路架構,由Gao Huang等人於2016年提出。該架構透過在不同層之間建立密集的連線模式,改善了資訊流通和梯度傳遞效率。

DenseNet主要特點

  • 稠密連線結構:每一層的輸入都包含前面所有層的輸出,形成資訊的高度流通。
  • 引數效率:相較於傳統網路,DenseNet在引數數量上更具效率。
  • 效能表現:在ImageNet資料集上,DenseNet201達到77%的準確率,而DenseNet121也取得了75%的準確率。

DenseNet實驗結果

模型名稱引數數量(不含分類別頭)ImageNet準確率104種花卉資料集F1得分(微調)104種花卉資料集F1得分(從零訓練)
DenseNet2011800萬77%95%(精確度:96%,召回率:95%)-
DenseNet121700萬75%76%(精確度:80%,召回率:74%)-
InceptionV3(對比)2200萬78%95%(精確度:95%,召回率:94%)-
SqueezeNet(對比)270萬76%(精確度:77%,召回率:75%)--

深度可分離卷積原理

傳統的卷積操作同時進行空間濾波和通道組合,這導致引數使用效率不高。深度可分離卷積將這兩個操作分開,先對每個通道進行獨立的空間濾波,再透過1x1卷積進行通道組合。

深度可分離卷積範例

考慮一個3x3卷積層,輸入通道為8,輸出通道為16:

  • 傳統卷積:需要16個3x3x8的濾波器,總引數量為3 * 3 * 8 * 16 = 1152。
  • 深度可分離卷積:先使用8個3x3濾波器進行空間濾波(引數量3 * 3 * 8),再使用1x1卷積進行通道組合(引數量8 * 16),總引數量為3 * 3 * 8 + 8 * 16 = 200。
# 示範深度可分離卷積的PyTorch實作
import torch
import torch.nn as nn

class DepthwiseSeparableConv(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size=3):
        super(DepthwiseSeparableConv, self).__init__()
        self.depthwise = nn.Conv2d(in_channels, in_channels, kernel_size, 
                                   groups=in_channels, padding=1)
        self.pointwise = nn.Conv2d(in_channels, out_channels, 1)

    def forward(self, x):
        x = self.depthwise(x)
        x = self.pointwise(x)
        return x

#### 程式碼解析:
# DepthwiseSeparableConv類別實作了深度可分離卷積,主要分為兩個步驟:
# 1. depthwise卷積:使用groups=in_channels引數實作每個通道的獨立濾波
# 2. pointwise卷積:使用1x1卷積實作通道間的組合
# 這種實作方式大幅減少了引數數量,同時保持了模型的表達能力

與Inception模組的關聯

深度可分離卷積在概念上與Inception模組相似,都是透過分解卷積操作來提升效率。兩者的主要差異在於操作的順序和組合方式。

未來研究方向
  • 探索更高效的網路架構設計
  • 研究不同深度可分離卷積變體的效能差異
  • 分析稠密連線結構在不同任務中的適用性

本研究結果表明,透過合理的架構設計和引數最佳化,可以在保持模型效能的同時顯著降低計算成本,為未來深度學習模型的開發提供了重要的參考價值。

深度可分離卷積與Xception架構

在深度學習的卷積神經網路(CNN)中,卷積層的設計對於模型的效能有著至關重要的影響。傳統的卷積運算雖然功能強大,但在引數量和計算成本上往往較高。為了改善這一點,深度可分離卷積(Depthwise Separable Convolution)被提出並廣泛應用於現代的CNN架構中,如Xception。

簡化的Inception模組與深度可分離卷積

簡化的Inception模組與深度可分離卷積在功能上非常相似。兩者都旨在透過將標準卷積運算分解為更簡單的操作來減少引數量和計算量。深度可分離卷積首先對輸入的每個通道進行獨立的空間卷積(depthwise convolution),然後透過1x1的卷積(pointwise convolution)來融合不同通道的資訊。

tf.keras.layers.SeparableConv2D(
    filters=32,
    kernel_size=(3, 3),
    strides=(1, 1),
    padding='same',
    depth_multiplier=1
)

內容解密:

  • filters:輸出通道的數量,決定了最終1x1卷積輸出的維度。
  • kernel_size:空間濾波器的大小,可以是單一數字(如3,表示3x3濾波器)或一對數字(如(4, 2),表示4x2的矩形濾波器)。
  • strides:空間卷積的步長。
  • padding:填充方式,‘valid’表示無填充,‘same’表示零填充以保持輸入輸出尺寸相同。
  • depth_multiplier:每個輸入通道被空間濾波器處理的次數,預設為1。

Xception架構

Xception架構結合了深度可分離卷積和ResNet風格的跳躍連線。由於深度可分離卷積在功能上等同於Inception模組,Xception同時具備了ResNet和Inception架構的優點,並且設計上更為簡潔。

Xception架構特點

  • 使用深度可分離卷積替代傳統卷積(除了前兩層)。
  • 殘差塊中使用3x3的可分離卷積,而不是傳統的3x3和1x1卷積組合。
  • 所有卷積層均使用ReLU啟用和批次歸一化。
  • 深度可分離卷積的深度乘數(depth multiplier)設為1。

神經架構搜尋(NAS)設計

NASNet利用自動化的演算法來設計最優的網路結構。它簡化了搜尋空間,透過設計基本的單元(cell),然後手動堆積疊這些單元來形成完整的網路。

NASNet特點

  • 使用神經架構搜尋演算法來設計基本單元。
  • 基本單元分為兩類別:保持特徵圖尺寸不變的“正常單元”和將特徵圖尺寸減半的“縮減單元”。
  • 使用強化學習等演算法來最佳化搜尋過程。

神經架構搜尋設計

NASNet架構解析

NASNet是一種透過神經架構搜尋(Neural Architecture Search, NAS)技術自動生成的深度學習模型。該模型的設計根據重複堆積疊的單元,包括正常單元(Normal Cell)和縮減單元(Reduction Cell),以形成完整的神經網路。

NASNet的關鍵特性

  • NASNet僅使用可分離卷積(Separable Convolutions),儘管常規卷積也是搜尋空間的一部分。這似乎證實了可分離卷積的優越性。
  • 在合併分支時,NASNet選擇將結果相加,而不是串接。這與ResNet類別似,但與使用串接的Inception或DenseNet不同。
  • 在正常單元中,NASNet選擇多個平行分支,而不是較少的分支和更多的轉換層。這更類別似於Inception,而不是ResNet。
  • NASNet使用具有大尺寸(5x5或7x7)濾波器的可分離卷積,而不是全部使用3x3卷積。

NASNet的效能表現

模型引數數量(不含分類別頭)ImageNet準確率104種花卉資料集F1分數(微調後)
NASNetLarge85M82%89%(精確度:92%,召回率:89%)
DenseNet20118M77%95%(精確度:96%,召回率:95%)
Xception21M79%95%(精確度:95%,召回率:95%)

儘管NASNetLarge具有大量的引數,但在104種花卉資料集上的表現並不如預期(F1分數89% vs. 其他模型的95%)。這可能是因為大量的可訓練引數需要更多的訓練資料。

MobileNet系列模型

MobileNetV2引入了新的建構區塊,包括深度卷積(Depthwise Convolutions)和倒置殘差瓶頸(Inverted Residual Bottlenecks),為設計更高效的搜尋空間提供了基礎。後續的MnasNet和EfficientNet模型根據相同的建構區塊進行自動化的神經架構搜尋。

深度卷積

深度卷積是一種空間濾波操作,對每個輸入通道獨立應用卷積濾波器,產生相同數量的輸出通道。

tf.keras.layers.DepthwiseConv2D(kernel_size=(3, 3), strides=(1, 1), padding='valid', depth_multiplier=1)

倒置殘差瓶頸

倒置殘差瓶頸是一種新的殘差區塊設計,將跳躍連線放置在通道數量較少的位置,並在殘差區塊內部擴充套件通道數量。

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title CNN 架構演進與效能分析

package "輕量化架構" {
    component [SqueezeNet] as squeeze
    component [Fire Module] as fire
    component [MobileNet] as mobile
    component [MobileNetV2] as mobilev2
}

package "殘差架構" {
    component [ResNet] as resnet
    component [跳躍連接] as skip
    component [DenseNet] as dense
    component [稠密連接] as dense_conn
}

package "高效卷積" {
    component [深度可分離卷積] as depthwise
    component [1x1 卷積] as pointwise
    component [倒置殘差] as inverted
}

package "自動搜尋" {
    component [NASNet] as nasnet
    component [架構搜尋] as nas
    component [效能最佳化] as perf
}

squeeze --> fire : 壓縮擴展
fire --> mobile : 輕量化
mobile --> mobilev2 : V2 改進

resnet --> skip : 解決梯度消失
skip --> dense : 更多連接
dense --> dense_conn : 特徵重用

depthwise --> pointwise : 分離計算
pointwise --> inverted : 先擴後壓
inverted --> mobilev2 : 高效結構

nasnet --> nas : 自動化
nas --> perf : 最佳架構

note right of fire
  Fire Module:
  - 1x1 壓縮通道
  - 1x1 + 3x3 擴展
  - 減少參數量
end note

note right of dense_conn
  DenseNet 特點:
  - 所有層互連
  - 特徵重用
  - 梯度直接傳遞
end note

@enduml

此圖示說明瞭倒置殘差瓶頸的結構,其中輸入首先經過1x1卷積擴充套件通道數量,然後進行深度卷積,最後再經過1x1卷積減少通道數量,並與原始輸入相加形成殘差連線。

MobileNetV2的創新之處

  • 將跳躍連線放置在通道數量較少的位置,以保留低維資訊。
  • 在殘差區塊內部擴充套件通道數量,以提高模型的表達能力。

內容解密:

MobileNetV2的設計理念是根據對ResNet和Xception等模型的分析和改進。它引入了倒置殘差瓶頸結構,以減少計算量並提高模型的效率。該結構透過在殘差區塊內部擴充套件通道數量,並在跳躍連線處減少通道數量,從而實作了高效的資訊傳遞和特徵提取。