社群計算機視覺課程文件

ResNet(殘差網路)

Hugging Face's logo
加入 Hugging Face 社群

並獲得增強的文件體驗

開始使用

ResNet(殘差網路)

擁有更多層的神經網路被認為更有效,因為增加更多層可以提高模型效能。

隨著網路變得更深,提取的特徵可以進一步豐富,例如 VGG16 和 VGG19 中所示。

一個問題出現了:“學習網路是否像堆疊更多層一樣容易?”梯度消失問題是回答這個問題的障礙,透過歸一化初始化和中間歸一化層解決了這個問題。

然而,一個新的問題出現了:退化問題。隨著神經網路變得更深,準確率飽和並迅速下降。一項比較淺層和深層普通網路的實驗表明,深層模型表現出更高的訓練和測試誤差,這表明有效訓練更深層架構存在根本性挑戰。這種退化並非由於過擬合,而是因為當網路變得更深時,訓練誤差增加了。新增的層並沒有近似恆等函式。

Degradation-error

ResNet 的殘差連線釋放了極致深度的潛力,與之前的架構相比,準確率大幅提升。

ResNet 架構

  • 一個殘差塊。來源:ResNet 論文 residual

ResNet 引入了一種稱為殘差學習的概念,它允許網路學習殘差(即學習到的表示與輸入之間的差異),而不是試圖直接將輸入對映到輸出。這是透過跳躍連線(或快捷連線)實現的。

讓我們分解一下

1. 基本構建塊:殘差塊

在典型的神經網路層中,我們的目標是學習對映 F(x),其中 x 是輸入,F 是網路應用的變換。如果沒有殘差學習,層的變換是:y = F(x)。在 ResNet 中,網路不是直接學習 F(x),而是被設計為學習殘差 R(x),其中:R(x) = F(x) − x。因此,殘差塊中的變換寫為:y = F(x) + x。

這裡,x 是殘差塊的輸入,F(x) 是塊堆疊層(通常是卷積、批歸一化和 ReLU)的輸出。恆等對映 x 透過跳躍連線直接新增到 F(x) 的輸出中。因此,該塊正在學習殘差 R(x) = F(x),最終輸出是 F(x) + x。與原始對映相比,這種殘差函式更容易最佳化。如果最優變換接近恆等(即不需要變換),網路可以很容易地將 F(x) ≈ 0 以便直接透過輸入。

  • ResNet 的構建塊如圖片所示,來源 ResNet 論文。

resnet_building_block

2. 學習殘差和梯度流

ResNets 對非常深的網路效果良好的主要原因是在反向傳播過程中改善了梯度流。讓我們從數學上分析反向傳播。假設您有殘差塊 y = F(x) + x。在透過鏈式法則計算梯度時,我們計算損失 𝐿 對輸入 x 的導數。對於標準塊(沒有殘差),梯度為

∂x/∂L = ∂F(x)/∂L * ∂F(x)/∂x

然而,對於殘差塊,其中 y = F(x) + x,梯度變為

∂L/∂x = ∂L/∂F(x) * ∂F(x)/∂x + ∂L/∂F(x) ⋅1

請注意,現在我們在梯度計算中多了一個項 1。這意味著每層的梯度都有一個直接路徑返回到較早的層,從而改善了梯度流並減少了梯度消失的可能性。梯度更容易流過網路,從而允許更深的網路在沒有退化的情況下進行訓練。

3. 為什麼現在可以實現更深的網路:

ResNet 使訓練數百甚至數千層網路成為可能。以下是更深網路從中受益的原因:

  • 恆等快捷連線:快捷連線執行恆等對映,其輸出被新增到堆疊層的輸出中。恆等快捷連線既不增加額外引數也不增加計算複雜性,這些連線繞過層,為資訊流建立直接路徑,並使神經網路能夠學習殘差函式 (F)。
  • 更好的梯度流:如前所述,殘差有助於梯度在反向傳播過程中更好地傳播,解決了超深網路中的梯度消失問題。
  • 更容易最佳化:透過學習殘差,網路本質上是將學習過程分解為更容易的增量步驟。對於網路來說,學習殘差 R(x) = F(x) − x 比直接學習 F(x) 更容易,尤其是在非常深的網路中。

總結:

我們可以得出結論:ResNet 網路 -> 普通網路 + 快捷連線!

對於操作 (F(x) + x),(F(x)) 和 (x) 應該具有相同的維度。ResNet 採用兩種技術來實現這一點:

  • 零填充快捷連線:新增零值通道,在不引入額外可學習引數的情況下保持維度。
  • 投影快捷連線:在必要時使用 1x1 卷積調整維度,這涉及一些額外的可學習引數。

在 ResNet 50、101 和 152 等更深層的 ResNet 架構中,採用了一種專門的“瓶頸構建塊”來管理引數複雜性並保持效率,同時實現更深層次的學習。

ResNet 程式碼

在 ImageNet 上預訓練的深度殘差網路

您可以在下面看到如何使用 transformers 庫載入預訓練的帶有影像分類頭的 ResNet。

from transformers import ResNetForImageClassification

model = ResNetForImageClassification.from_pretrained("microsoft/resnet-50")

model.eval()

所有預訓練模型都期望輸入影像以類似方式歸一化,即形狀為 (3 x H x W) 的 3 通道 RGB 影像的小批次,其中 H 和 W 預期至少為 224。影像必須載入到 [0, 1] 範圍,然後使用 mean = [0.485, 0.456, 0.406] 和 std = [0.229, 0.224, 0.225] 進行歸一化。

這是一個示例執行。此示例可在 Hugging Face 文件中找到。

from transformers import AutoFeatureExtractor, ResNetForImageClassification
import torch
from datasets import load_dataset

dataset = load_dataset("huggingface/cats-image")
image = dataset["test"]["image"][0]

feature_extractor = AutoFeatureExtractor.from_pretrained("microsoft/resnet-50")
model = ResNetForImageClassification.from_pretrained("microsoft/resnet-50")

inputs = feature_extractor(image, return_tensors="pt")

with torch.no_grad():
    logits = model(**inputs).logits

# model predicts one of the 1000 ImageNet classes
predicted_label = logits.argmax(-1).item()
print(model.config.id2label[predicted_label])

參考文獻

< > 在 GitHub 上更新

© . This site is unofficial and not affiliated with Hugging Face, Inc.