返回文章列表

CNN 卷積神經網路模型架構解析

本文探討卷積神經網路(CNN)的核心概念、架構演進以及 ResNet 的實作細節。從基礎的卷積、池化操作到 BatchNorm 等技術,文章逐一剖析,並以程式碼示例說明如何在 PyTorch 中構建和使用 CNN 模型,同時比較了 AlexNet、VGG

深度學習 影像處理

深度學習在影像處理領域的蓬勃發展,卷積神經網路(CNN)功不可沒。相較於傳統的全連線網路,CNN 更能有效地捕捉影像特徵,降低計算成本,並提升模型準確度。本文將從 CNN 的基礎元件開始,逐步探討其架構演進,並以 ResNet 為例,剖析其內部結構和技術原理。首先,卷積層利用濾波器提取影像特徵,池化層則降低特徵圖解析度,減少運算量。步幅和填充等超引數的調整,能有效控制特徵提取的精細程度。ReLU 啟用函式的引入,為模型增添非線性特性,提升表達能力。Dropout 技術則能有效防止過擬合,提升模型泛化能力。

卷積神經網路(Convolutional Neural Networks)

在第2章中,我們嘗試使用全連線神經網路(fully connected neural networks)進行實驗後,可能會注意到一些問題。如果嘗試增加更多層或大幅增加引數數量,很可能會導致GPU記憶體不足。此外,訓練到一定的準確率需要一段時間,即使如此,準確率也不太理想,尤其是考慮到深度學習的熱潮。為什麼會這樣呢?

理論上,全連線網路(或稱前饋網路)可以作為通用近似器(universal approximator),但理論並未說明需要多長時間才能訓練成所需的函式近似值。然而,我們可以做得更好,特別是在影像處理方面。在本章中,我們將學習卷積神經網路(CNNs),以及它們如何成為目前最準確的影像分類別器的基礎。我們將建立一個新的根據卷積的神經網路架構,用於我們的魚與貓的應用,並展示它比前一章的方法更快訓練且更準確。

我們的第一個卷積模型

這次,我們將先介紹最終的模型架構,然後討論所有新的部分。如同第2章所述,我們建立的訓練方法是獨立於模型的,因此您可以先測試這個模型,然後再回來看解釋。

class CNNNet(nn.Module):
    def __init__(self, num_classes=2):
        super(CNNNet, self).__init__()
        self.features = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(64, 192, kernel_size=5, padding=2),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(192, 384, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.Conv2d(384, 256, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.Conv2d(256, 256, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=3, stride=2),
        )
        self.avgpool = nn.AdaptiveAvgPool2d((6, 6))
        self.classifier = nn.Sequential(
            nn.Dropout(),
            nn.Linear(256 * 6 * 6, 4096),
            nn.ReLU(),
            nn.Dropout(),
            nn.Linear(4096, 4096),
            nn.ReLU(),
            nn.Linear(4096, num_classes)
        )

    def forward(self, x):
        x = self.features(x)
        x = self.avgpool(x)
        x = torch.flatten(x, 1)
        x = self.classifier(x)
        return x

內容解密:

  1. nn.Sequential()的使用:允許我們建立一系列層。在forward()方法中,輸入會依次透過陣列中的每個層。可以利用這一點將模型分解為更邏輯的排列。在這個網路中,我們有兩個主要的鏈:features區塊和classifier

  2. Conv2d:是一個2D卷積層。如果我們有一個灰階影像,它由一個陣列組成,x畫素寬和y畫素高,每個條目都有一個值,指示它是黑色還是白色或介於兩者之間。對於彩色影像,如RGB影像,輸入通道數為3。

    • nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding)
      • in_channels是該層接收的輸入通道數。在網路的開始,我們接收RGB影像作為輸入,因此輸入通道數為3。
      • out_channels是輸出通道數,對應於我們的卷積層中的濾波器數量。
      • kernel_size描述了濾波器的高度和寬度。可以是一個單一的純量,指定一個正方形濾波器(例如,在第一個卷積層中,我們設定了一個11×11的濾波器),或者可以使用一個元組(例如(3,5)表示一個3×5的濾波器)。
      • stride指示當我們調整濾波器到新位置時,在輸入上移動多少步。

卷積運算

卷積層會有許多這樣的濾波器,它們的值由網路的訓練填充,並且該層中的所有濾波器分享相同的偏差值。

考慮一個小的4×4影像:

10 11 9 3
2 123 4 0
45 237 23 99
20 67 22 255

以及一個2×2的濾波器:

1 0
1 0

將濾波器拖過原始輸入,從左上角開始,第一個計算是:

  • (10 × 1) + (11 × 0) + (2 × 1) + (123 × 0) = 12

移動濾波器,進行下一次計算,假設步長為2,則得到輸出13。重複這個過程,直到遍歷整個輸入,最終得到一個特徵圖(feature map)。

圖表說明

此圖示展示了一個3×3的核心如何在4×4的張量上運作,產生一個2×2的輸出。

為什麼使用卷積神經網路?

  • 卷積神經網路特別適合處理影像資料,因為它們能夠捕捉區域性模式和特徵。
  • 相較於全連線網路,CNNs引數更少,需要的計算資源也更少,從而能夠更有效地訓練和執行。

卷積神經網路(CNN)基礎元件詳解

卷積神經網路(CNN)是一種專門為處理具有網格結構的資料(如影像)而設計的神經網路架構。本篇文章將探討CNN中的幾個關鍵元件,包括卷積層(Convolutional Layers)、池化層(Pooling Layers)以及丟棄層(Dropout Layers)。

卷積層(Conv2d)

卷積層是CNN的核心元件,主要用於提取輸入資料的特徵。卷積運算透過在輸入資料上滑動一個濾波器(filter),並計算濾波器與輸入資料之間的點積,從而生成特徵對映(feature map)。

步幅(Stride)與填充(Padding)

在進行卷積運算時,有兩個重要的超引數需要考慮:步幅(stride)和填充(padding)。步幅決定了濾波器在輸入資料上移動的步長,而填充則是在輸入資料周圍新增額外的畫素,以控制輸出特徵對映的大小。

例如,當步幅設為1時,濾波器每次移動一個畫素;而當填充設為1時,輸入資料周圍會新增一圈零畫素,以確保濾波器能夠完全覆寫輸入資料的邊緣區域。

# 以PyTorch為例,建立一個卷積層
import torch.nn as nn
conv_layer = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=3, stride=1, padding=1)

內容解密:

  • in_channels=1 表示輸入資料的通道數為1(例如,灰階影像)。
  • out_channels=1 表示輸出的特徵對映數量為1。
  • kernel_size=3 表示濾波器的大小為3x3。
  • stride=1 表示濾波器每次移動一個畫素。
  • padding=1 表示在輸入資料周圍新增一圈零畫素。

池化層(Pooling Layers)

池化層的主要功能是降低特徵對映的解析度,從而減少網路中的引數數量並加速計算。最常見的池化方法是最大池化(Max Pooling),它會在每個區域中選取最大值作為輸出。

最大池化(MaxPool2d)

在我們的範例模型中,使用了最大池化層,核大小為3,步幅為2。下面是一個簡單的例子:

假設有一個5x5的輸入:

1 2 1 4 1
5 6 1 2 5
5 0 0 9 6

使用核大小為3x3、步幅為2的最大池化層,會得到兩個3x3的張量:

1 2 1       1 4 1
5 6 1       1 2 5
5 0 0       0 9 6

最大池化會從每個張量中選取最大值,從而得到輸出張量 [6, 9]

# 以PyTorch為例,建立一個最大池化層
max_pool_layer = nn.MaxPool2d(kernel_size=3, stride=2)

內容解密:

  • kernel_size=3 表示池化核的大小為3x3。
  • stride=2 表示池化核每次移動兩個畫素。

丟棄層(Dropout Layers)

丟棄層是一種正則化技術,透過在訓練過程中隨機丟棄某些神經元,以防止過擬合。在我們的範例模型中,丟棄層被初始化為0.5,表示有50%的神經元會被隨機丟棄。

# 以PyTorch為例,建立一個丟棄層
dropout_layer = nn.Dropout(p=0.5)

內容解密:

  • p=0.5 表示有50%的神經元會被隨機丟棄。

CNN架構的歷史發展

雖然CNN模型已經存在了幾十年,但直到GPU變得普及後,深層CNN網路才變得實用。在過去的十年中,許多重要的CNN架構被提出,例如AlexNet,它在2012年的ImageNet競賽中取得了當時最好的成績,並推廣了最大池化和丟棄層的使用。

AlexNet

AlexNet是深度學習歷史上的一個重要里程碑。它引入了最大池化和丟棄層的概念,並證明瞭深層網路可以在GPU上高效訓練。雖然它現在已經不是最先進的架構,但它對深度學習的發展起到了重要作用。

卷積神經網路(CNN)架構的演進

卷積神經網路(CNN)在影像識別領域取得了巨大的成功,不同的架構不斷被提出以提高準確率和效率。本篇文章將介紹幾種具有代表性的CNN架構,包括AlexNet、Inception/GoogLeNet、VGG、ResNet等,並探討它們的特點和創新之處。

AlexNet架構

AlexNet是深度學習在影像識別領域的一個重要里程碑。它採用了多層卷積和池化層,並使用ReLU作為啟用函式。AlexNet的成功在於它展示了深度神經網路在影像識別任務上的強大能力。

程式碼範例:AlexNet模型定義

import torchvision.models as models
alexnet = models.alexnet(num_classes=2)

內容解密:

  1. import torchvision.models as models:匯入PyTorch的torchvision.models模組,該模組提供了多種預訓練的模型。
  2. alexnet = models.alexnet(num_classes=2):呼叫models.alexnet函式建立一個AlexNet模型,並指定輸出類別數為2。

Inception/GoogLeNet架構

Inception/GoogLeNet是2014年ImageNet競賽的冠軍,它引入了Inception模組。Inception模組允許網路同時使用不同大小的卷積核,從而捕捉不同尺度的特徵。

Inception模組結構圖

此圖示展示了Inception模組的基本結構。

內容解密:

  1. Inception模組首先對輸入進行1x1卷積,以減少維度。
  2. 同時進行不同大小(3x3、5x5)的卷積運算,以捕捉不同尺度的特徵。
  3. 將所有卷積結果合併,作為下一層的輸入。

VGG架構

VGG是2014年ImageNet競賽的亞軍,它採用了一種簡單而有效的結構:多層卷積和池化層的堆積疊。VGG-16是其中一個著名的變體,它包含了16層可訓練的權重。

VGG-16結構圖

此圖示展示了VGG-16的基本結構。

內容解密:

  1. VGG-16採用多層卷積和池化層的堆積疊結構。
  2. 使用兩個大型的全連線層進行分類別。

ResNet架構

ResNet是2015年ImageNet競賽的冠軍,它引入了殘差連線(residual connection)的概念,解決了深層網路訓練中的梯度消失問題。

ResNet殘差塊結構圖

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title CNN 卷積神經網路模型架構解析

package "機器學習流程" {
    package "資料處理" {
        component [資料收集] as collect
        component [資料清洗] as clean
        component [特徵工程] as feature
    }

    package "模型訓練" {
        component [模型選擇] as select
        component [超參數調優] as tune
        component [交叉驗證] as cv
    }

    package "評估部署" {
        component [模型評估] as eval
        component [模型部署] as deploy
        component [監控維護] as monitor
    }
}

collect --> clean : 原始資料
clean --> feature : 乾淨資料
feature --> select : 特徵向量
select --> tune : 基礎模型
tune --> cv : 最佳參數
cv --> eval : 訓練模型
eval --> deploy : 驗證模型
deploy --> monitor : 生產模型

note right of feature
  特徵工程包含:
  - 特徵選擇
  - 特徵轉換
  - 降維處理
end note

note right of eval
  評估指標:
  - 準確率/召回率
  - F1 Score
  - AUC-ROC
end note

@enduml

此圖示展示了ResNet殘差塊的基本結構。

內容解密:

  1. 殘差塊允許輸入直接跳過幾層連線至輸出。
  2. 這種結構有助於解決深層網路中的梯度消失問題。

使用預訓練模型

PyTorch提供了多種預訓練的CNN模型,可以直接用於影像識別任務。這些模型包括AlexNet、VGG、ResNet等。

程式碼範例:使用預訓練的ResNet模型

import torchvision.models as models
resnet = models.resnet18(pretrained=True)

內容解密:

  1. models.resnet18(pretrained=True):呼叫models.resnet18函式建立一個預訓練的ResNet-18模型。

卷積神經網路架構解析:以ResNet為例

本段落將深入解析卷積神經網路(CNN)中的經典架構——ResNet的內部結構,並詳細闡述其關鍵元件的作用與技術原理。

ResNet模型結構剖析

首先,讓我們觀察ResNet模型的結構:

(conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace)
(maxpool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)
(layer1): Sequential(
    (0): BasicBlock(...)
    (1): BasicBlock(...)
)
(layer2): Sequential(
    (0): BasicBlock(...)
    (1): BasicBlock(...)
)
...
(avgpool): AdaptiveAvgPool2d(output_size=(1, 1))
(fc): Linear(in_features=512, out_features=1000, bias=True)

內容解密:

  1. 初始卷積層:使用7x7的卷積核,步長為2,輸出64個特徵圖
  2. 批次標準化(BatchNorm2d):對每個小批次的輸出進行標準化處理,使其均值接近0,變異數為1
  3. ReLU啟用函式:引入非線性特性,提高模型的表達能力
  4. 最大池化(MaxPool2d):降低特徵圖的解析度,減少計算量

BatchNorm技術解析

BatchNorm是ResNet架構中的關鍵技術之一,其主要功能是:

  • 自動調整網路中的資料分佈,避免梯度消失或爆炸
  • 加速網路訓練過程
  • 提高模型的穩定性

為何需要BatchNorm?

在深層網路中,由於多層之間的連續相乘,可能導致梯度問題。BatchNorm透過動態調整每層的輸出分佈,有效緩解了這一問題。

ResNet層級結構分析

ResNet採用模組化的設計思路,主要包含以下幾個層級:

  1. layer1-layer4:由多個BasicBlock組成,每個Block包含兩個卷積層和一個捷徑連線(shortcut connection)
  2. BasicBlock內部結構
    • 兩個3x3卷積層,中間夾雜ReLU啟用函式
    • 使用BatchNorm進行標準化處理
    • 捷徑連線實作殘差學習,有效解決梯度消失問題

內容解密:

  • 殘差學習:透過捷徑連線,將輸入直接加到輸出上,實作殘差學習,改善梯度傳遞效率
  • 卷積層設計:採用3x3的小型卷積核,既減少引數量,又能捕捉區域性特徵

模型選擇建議

在實際應用中,選擇適當的預訓練模型至關重要。建議:

  1. 列印模型結構:使用print(model)檢視不同架構的層級結構和運算順序
  2. 根據任務需求選擇模型:考慮模型的複雜度和效能需求,選擇合適的ResNet版本(如ResNet-50或ResNet-152)