banner
Fight4354

Fight4354

AI,Chem,Science,Study,Share,Hobby,LLM,Life,Sport

Pytorch學習記錄

近期在看李沐大神的動手學深度學習課程,在此,記錄一些重要知識點,不要讓知識到處飄,讓知識彙總起來。

1、PyTorch 的 backward 必須是標量#

import torch
x = torch.arange(4.0,requires_grad=True)
y = 2 * torch.dot(x,x)
y.backward()
# 默認情況下,PyTorch會累積梯度,需要清除之前的值
# 對非標量調用 'backward' 需要傳入一個 'gradient' 參數,該參數指定微分函數
x.grad.zero_()  # 清除之前x的梯度
y = x * x  # 這裡的y不是一個標量,這是一個向量
print(y)
# 等價於y.backward(torch.ones(len(x)))
y.sum().backward() # y.sum()後就講向量轉為標量了,對標量求導
x.grad

🔹 關鍵點:PyTorch 的 backward 必須是標量

在 PyTorch 中,.backward() 的設計是基於 鏈式法則,主要針對標量(單個輸出值)對輸入的梯度。

如果你調用 y.backward(),這裡的 y 必須是一個標量,因為:

xy=yx\nabla_x y = \frac{\partial y}{\partial x}
  • xy\nabla_x y 叫做 y 關於 x 的梯度(gradient)

  • yx\frac{\partial y}{\partial x}y 對 x 的偏導數

但是到底它具體是什麼,取決於 $y$ 和 $x$ 的維度。


🔸 情況 1:y 是標量,x 是向量

假設:

  • xRnx \in \mathbb{R}^n

  • yRy \in \mathbb{R}

那麼:

xy=[yx1yx2yxn]Rn\nabla_x y = \begin{bmatrix} \frac{\partial y}{\partial x_1} \\ \frac{\partial y}{\partial x_2} \\ \vdots \\ \frac{\partial y}{\partial x_n} \end{bmatrix} \in \mathbb{R}^n

也就是:

一個長度為 nn 的向量,表示 y 對每個 x 分量的偏導數。

這正是機器學習裡最常用的情況,比如 ** loss 對權重的梯度 **。


🔸 情況 2:y 是向量,x 是向量

假設:

  • xRnx \in \mathbb{R}^n

  • yRmy \in \mathbb{R}^m

那麼:

yx=JRm×n\frac{\partial y}{\partial x} = J \in \mathbb{R}^{m \times n}

這個矩陣 JJ 叫做 Jacobian 矩陣,它的 (i,j)(i, j) 元素是:

Jij=yixjJ_{ij} = \frac{\partial y_i}{\partial x_j}

2、Jacobian 矩陣#

Jacobian 矩陣是:

一個向量函數對輸入向量的偏導矩陣

假設:

  • 輸入:xRnx \in \mathbb{R}^n

  • 輸出:y=f(x)Rmy = f(x) \in \mathbb{R}^m

Jacobian:

J(x)=yx=[y1x1y1xnymx1ymxn]Rm×nJ(x) = \frac{\partial y}{\partial x} = \begin{bmatrix} \frac{\partial y_1}{\partial x_1} & \cdots & \frac{\partial y_1}{\partial x_n} \\ \vdots & \ddots & \vdots \\ \frac{\partial y_m}{\partial x_1} & \cdots & \frac{\partial y_m}{\partial x_n} \\ \end{bmatrix} \in \mathbb{R}^{m \times n}

直觀上:

  • ii 行:yiy_i 對所有 xjx_j 的偏導。

  • 描述:輸入變量小變動對每個輸出變量的線性影響。

3、Hessian 矩陣#

Hessian 矩陣是:

一個標量函數對輸入向量的二階偏導矩陣

假設:

  • 輸入:xRnx \in \mathbb{R}^n

  • 輸出:y=f(x)Ry = f(x) \in \mathbb{R}

Hessian:

H(x)=2yx2=[2yx122yx1x22yx2x12yx22]Rn×nH(x) = \frac{\partial^2 y}{\partial x^2} = \begin{bmatrix} \frac{\partial^2 y}{\partial x_1^2} & \frac{\partial^2 y}{\partial x_1 \partial x_2} & \cdots \\ \frac{\partial^2 y}{\partial x_2 \partial x_1} & \frac{\partial^2 y}{\partial x_2^2} & \cdots \\ \vdots & \vdots & \ddots \\ \end{bmatrix} \in \mathbb{R}^{n \times n}

但是當 yy 是一個 向量,梯度其實是 Jacobian 矩陣,不是單個梯度向量:

Jij=yixjJ_{ij} = \frac{\partial y_i}{\partial x_j}

4、pytorch 中 dtype 和 type 的區別#

先放結論:

dtype 是張量內元素的具體數值類型,type 是張量對象本身的 Python 類型(包含設備信息)。

它們關注的層面完全不一樣。


📍 1️⃣ dtype 是什麼?

  • 指:張量裡每個元素的存儲類型。

  • 舉例:

    • torch.float32 → 單精度浮點數

    • torch.int64 → 64 位整數

    • torch.bool → 布爾類型

看代碼:

x = torch.tensor([1, 2, 3], dtype=torch.float32)
print(x.dtype)  # 輸出:torch.float32

它只告訴你「這個張量的元素用什麼格式存儲」。


📍 2️⃣ type 是什麼?

  • 指:張量對象在 PyTorch 中的全名,包括數據類型和設備。

  • 舉例:

    • torch.FloatTensor → float32 的 CPU 張量

    • torch.cuda.FloatTensor → float32 的 GPU 張量

    • torch.IntTensor → int32 的 CPU 張量

看代碼:

x = torch.tensor([1, 2, 3])
print(x.type())  # 輸出:torch.IntTensor(或你的系統默認類型)

它告訴你「這個張量對象在 PyTorch 系統裡的完整類型名」。


📍 ⚠ 關鍵區別

對比項dtypetype
關注點元素的數值類型張量對象的完整 PyTorch 類型(包括設備信息)
舉例torch.float32, torch.int64torch.FloatTensor, torch.cuda.FloatTensor
主要用途精度、存儲、計算相關區分不同張量類別,調試 / 檢查用
改變方式.to(dtype).float().type()(更換整個類型對象)

5、Soft Label vs Hard Label#

通常我們訓練分類模型,用的標籤是:
hard label(硬標籤)
比如,對於 3 分類任務,真實標籤:

類別 A → [1, 0, 0]
類別 B → [0, 1, 0]
類別 C → [0, 0, 1]

這種標籤完全是 獨熱編碼 (one-hot),只認對與錯。


soft label(軟標籤) 則是:

每個類別對應一個概率,而不是硬性的 0 或 1。

比如:

對於某張圖片,soft label → [0.7, 0.2, 0.1]

這表示:

  • 有 70% 概率是類別 A

  • 20% 概率是類別 B

  • 10% 概率是類別 C

換句話說,標籤也 “承認模糊性”,不是全或無。


6、softmax 回歸和 logistic 回歸#

** 📦 共同點 **

本質都是分類模型
✅ 都用線性函數 + 激活(sigmoid 或 softmax)
✅ 都用交叉熵(cross entropy)作為損失函數

但它們用在不同的任務上。


🌟 主要區別


項目Logistic 回歸Softmax 回歸
任務類型二分類(binary classification)多分類(multi-class classification)
輸出層激活函數sigmoid(單值輸出 0~1)softmax(向量輸出,每個類別概率)
輸出維度1 維C 維(C = 類別數)
目標標籤0 或 1one-hot 編碼,比如 [0,0,1,0]
決策方式輸出 > 0.5 判為正類最大概率的類別作為預測結果


📊 Logistic 回歸細節

  • 假設你有:

    • 輸入特徵 xx

    • 權重 ww 和偏置 bb

  • 模型計算:
    y^=σ(wTx+b)\hat{y} = \sigma(w^T x + b)
    其中 sigma\\sigma 是 sigmoid 函數。

輸出 haty\\hat{y} 是一個概率值(0 到 1),代表正類的概率。

損失函數:
Binary Cross Entropy=[ylog(y^)+(1y)log(1y^)]\text{Binary Cross Entropy} = -[y \log(\hat{y}) + (1-y)\log(1-\hat{y})]


📊 Softmax 回歸細節

  • 假設你有:

    • 輸入特徵 xx

    • 權重矩陣 WW(shape: num_features × num_classes)

    • 偏置 bb

  • 模型計算:
    y^i=ezijezj\hat{y}_i = \frac{e^{z_i}}{\sum_j e^{z_j}}
    其中 z=WTx+bz = W^T x + b

輸出 $\hat {y}$ 是一個長度為 C 的向量,每個元素是對應類別的概率。

損失函數:
Cross Entropy=iyilog(y^i)\text{Cross Entropy} = -\sum_i y_i \log(\hat{y}_i)


** 🧠 為什麼 logistic 回歸不能直接用在多分類?**

因為 sigmoid 只輸出一個值,而多分類需要輸出多個類別的概率,且這些概率要滿足:

總和為 1,互相排斥。

這就是 softmax 的設計目的。


總結一句話

Logistic 回歸 ≈ 2 類 softmax 特例
Softmax 回歸 = 多分類推廣版 logistic 回歸


7、似然和概率#

🌟 什麼是似然函數?

簡單說:

似然函數(likelihood function)是給定模型參數下,觀察到數據的概率。

你可以理解為:
模型假設有某個參數 → 在這個參數下,生成我們現在手上這批數據的 “可能性” 有多大。


📊 和概率的區別?

很多人容易混:
✅ 概率:已知參數,算事件的可能性。
✅ 似然:已知數據,換著看哪個參數下更可能生成這些數據。

雖然數學公式長得一樣,但用途反過來。



🏗️ 數學表達

假設:

  • 數據:x1,x2,...,xnx_1, x_2, ..., x_n

  • 參數:thetatheta

概率

P(xθ)P(x | \theta)

似然函數

L(θx)=P(xθ)L(\theta | x) = P(x | \theta)

區別在於:

  • 概率:θ\theta 固定,看 xx

  • 似然:xx 固定,看 θ\theta



🌟** 舉個簡單例子 **

假設你有一個硬幣,拋了 10 次,結果有 7 次正面。
我們想估計硬幣正面的概率 pp


模型假設
拋硬幣次數:10
正面概率:pp
事件:7 次正面


似然函數

L(p)=Cp7(1p)3L(p) = C \cdot p^7 (1-p)^3

其中:

  • CC 是組合數(固定值,不影響最大化)。

  • 核心是:

    給定 pp,生成這個數據(7 正 3 反)的概率。


🌟 最大似然估計(MLE)

通常我們用:

找到讓似然函數最大的參數。

在這個例子裡:

  • 最大化 p7(1p)3p^7 (1-p)^3

  • 最優 p=7/10=0.7p^* = 7 / 10 = 0.7

這就是最大似然估計。



🔥 在機器學習中

機器學習裡的很多訓練,其實都是:

用最大似然,去擬合參數。

比如:

  • 回歸模型 → 高斯分佈的最大似然

  • 分類模型 → softmax 下的最大似然

  • 神經網絡 → 交叉熵損失,其實就是最大似然推導出來的



總結一句話

似然函數 = 在給定參數下,觀察到當前數據的概率(把它看作參數的函數)。

最大化似然,就是找最可能生成數據的參數。

8、感知機#

感知機(Perceptron) 是一種非常基礎的 二分類線性模型,可以看作是神經網絡的最早形式(單層、無隱藏層)。

它的主要特點和要點是:

基本形式
感知機就是用一個權重向量 w 和偏置 b,去對輸入特徵向量 x 做線性組合,再經過一個符號函數(sign function),決定輸出是 +1 還是 -1。

公式:
  f(x) = sign(w·x + b)

目標
找到一組 w, b,讓所有樣本能被一個超平面分開(即線性可分)。

訓練算法

  • 初始化權重和偏置(通常為零或小值)。

  • 對每個誤分類樣本,更新權重:
      w ← w + η * y * x
      b ← b + η * y
    這裡 η 是學習率,y 是真實標籤(+1 或 -1)。

  • 持續迭代,直到所有樣本都被正確分類(或達到最大迭代次數)。

局限性(硬傷):

  • 只能處理線性可分的問題。非線性數據(比如 XOR 問題)它完全無能為力。

  • 沒有概率輸出,只是硬分類。

  • 容易受噪聲和異常值影響。

意義和歷史地位
雖然現在深度學習早已超越感知機,但感知機是神經網絡發展的起點。當年 Minsky 和 Papert 在 1969 年寫的《Perceptrons》一書指出它不能解決 XOR 問題,這直接導致 AI 寒冬的到來。直到多層網絡(MLP)和反向傳播算法出現,才打破了這個局限。

9、多層感知機#

二分類問題公式
image

image

二分類問題公式與多分類問題區別在於 w2w_2的形狀為mkm*k。(k 為類別個數)

每一層隱藏層都需要一個激活函數(非線性函數),如果沒有激活函數,就相當於一個大的線性函數。
輸出層可以不需要激活函數。

多層感知機多分類問題與 Softmax 回歸的區別,在於多了隱藏層,其餘均相同。

代碼

import torch
from torch import nn

# 構建模型,隱藏層包含256個隱藏單元,並使用了ReLU激活函數
net = nn.Sequential(nn.Flatten(),nn.Linear(784,256),nn.ReLU(),nn.Linear(256,10))

代碼解釋
nn.Sequential() 用來按順序堆疊一系列子模塊(層、激活函數等),自動組織前向傳播。換句話說:它就是一個有序容器,把你想要的網絡模塊按順序包起來。
nn.Flatten()把輸入的多維張量展平成一維向量。
對 MNIST 來說,輸入圖像 shape 是 [batch_size, 1, 28, 28](灰度圖),Flatten 後變成 [batch_size, 784],方便接入全連接層。

10、激活函數#

Sigmoid 函數#

Sigmoid 激活函數 定義為:

σ(x)=11+ex\sigma(x) = \frac{1}{1 + e^{-x}}

輸出範圍
(0, 1) —— 把任意實數映射到 0 和 1 之間。

圖像特徵

output

  • S 形曲線(所以叫 sigmoid,sigmoid = S 型)。

  • 中心對稱於 (0, 0.5)。

  • xx 很大或很小時,梯度接近 0 —— 梯度消失。

優點

  • 可以解釋為概率(尤其適合二分類最後一層)。

  • 光滑、連續、可微。

缺點(致命的)

  • 梯度消失:當 xx 很大或很小時,導數接近 0,反向傳播幾乎沒法更新權重。

  • 輸出不以 0 為中心:這會讓梯度更新時收斂變慢,因為正負梯度不對稱。

  • 容易飽和:輸入太大或太小都會被壓平。

現在的主流做法

  • 除了二分類最後一層,隱藏層幾乎都不用 sigmoid,而是用 ReLU 或更先進的變體。

  • 如果是二分類,最後一層用 sigmoid,損失函數用 binary cross entropy。

Tanh 函數#

tanh(雙曲正切)激活函數 定義:

tanh(x)=exexex+ex\tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}}

輸出範圍
(-1, 1) —— 把任意實數壓縮到 -1 到 1 之間。

圖像特徵

output

  • S 形曲線(跟 sigmoid 類似,但上下對稱)。

  • 中心對稱於 (0, 0)(這比 sigmoid 好,輸出均值更接近 0,有助於優化收斂)。

  • xx 很大或很小時,也會出現梯度消失。

優點

  • 相比 sigmoid,輸出以 0 為中心,對梯度更新更友好。

  • 光滑、連續、可微。

缺點(核心問題)

  • 和 sigmoid 一樣,容易飽和 → 梯度消失。

現在的主流做法

  • 在某些需要對稱輸出的模型(比如 RNN)中,tanh 仍然有用。

  • 但對於深層神經網絡的隱藏層,現代主流還是用 ReLU 及其改進版。

ReLU 函數#

ReLU(Rectified Linear Unit)激活函數 定義:

ReLU(x)=max(0,x)\text{ReLU}(x) = \max(0, x)

輸出範圍
[0,+)[0, +\infty)

圖像特徵

output

  • x<0x < 0,輸出 0。

  • x0x \geq 0,輸出 xx
    簡單、直接,一條折線。

優點

  • 計算簡單,收斂快。相比於 Sigmoid 函數和 Tanh 函數,這倆均需要指數運行,指數運算偏貴。

  • 不容易出現梯度消失(因為正區間梯度恆為 1)。

  • 稀疏激活(很多神經元輸出 0,這有助於簡化模型)。

缺點

  • 死亡 ReLU 問題:如果某個神經元在訓練中被卡進負區間(輸出一直為 0),它可能再也更新不了(因為負區間梯度為 0)。

  • 對輸入值不對稱(只保留正值)。

現代改進版

  • Leaky ReLU:負區間給一個很小的斜率。

  • Parametric ReLU (PReLU):讓負區間的斜率可學習。

  • ELU、GELU、Swish:進一步改進。

11、模型複雜度#

image

12、正則化#

在機器學習中,正則化方法就是一種用來防止模型過擬合、提高模型泛化能力的技術集合。 它通過在模型的學習過程中引入一些 “懲罰” 或 “限制”,來約束模型的複雜度,使得模型不會過於 “完美” 地擬合訓練數據中的每一個細節(尤其是噪聲),從而能夠更好地適應新的、未見過的數據。
只在訓練中使用,預測時不需要。

正則化是什麼?

一句話:正則化通過在損失函數裡加入 “約束 / 懲罰”,主動限制模型自由度,逼它學到簡潔泛化好的規律,而不是死記硬背訓練集裡的噪聲。

數學上常寫成

minθ  L(θ;X,y)  +  λΩ(θ)\min_{\theta}\; \mathcal{L}(\theta;\,X,y)\;+\;\lambda\,\Omega(\theta)
  • L\mathcal{L}:原始經驗損失(交叉熵、MSE …)

  • Ω\Omega:正則項(越大表示模型越 “複雜”)

  • λ\lambda:正則強度;λ=0\lambda=0 退化成無正則,λ\lambda\to\infty 則把模型壓到極簡

核心作用

目標解釋
抑制過擬合減小方差,提升對未見樣本的魯棒性
數值穩定避免權重爆炸或矩陣奇異
可解釋性稀疏化或結構化約束讓特徵 / 子網絡更易閱讀
防共線在高維共線特徵下仍能給出唯一解

L1 正則化 (Lasso Regression)#

✅** 1. L1 正則化是什麼?**

一句話定義:

L1 正則化就是在損失函數中加入 所有權重絕對值的和 作為懲罰項。

它的目標是:

讓某些不重要的權重 自動變成 0,從而讓模型 “更簡單”。


2. 數學形式(簡潔地看)

普通損失函數是:

Loss=模型誤差(比如交叉熵)\text{Loss} = \text{模型誤差(比如交叉熵)}

加上 L1 正則化後,變成:

Losstotal=原始誤差+λwi\text{Loss}_{\text{total}} = \text{原始誤差} + \lambda \sum |w_i|

其中:

  • wiw_i 是每個權重參數

  • λ\lambda 是控制懲罰強度的超參數(越大,越 “狠”)


3. L1 的最大特點:讓部分權重變為 0(稀疏化)

這就是 L1 和 L2 的關鍵區別:

所以如果你希望模型自動挑出重要特徵、丟掉垃圾特徵,L1 正則是理想選擇。


4. 舉個例子(想像)

你在做一個房價預測任務,有 100 個輸入特徵,但實際上只有 5 個有用。

如果你用 L1 正則,訓練後模型可能只保留這 5 個特徵的權重,其余 95 個直接變成 0。
這相當於模型自動做了特徵選擇


總結一句話

L1 正則化 = 懲罰權重絕對值 → 促使部分參數變 0 → 自動選擇重要特徵。

L2 正則化(權重衰退)(Ridge Regression)#

一句話定義

L2 正則化 是在損失函數中加入 模型參數平方的懲罰項
用來抑制權重過大,避免過擬合


數學形式

設模型的原始損失函數為:

Loss=L(y^,y)\text{Loss} = L(\hat{y}, y)

加上 L2 正則後,變成:

Losstotal=L(y^,y)+λwi2\text{Loss}_{\text{total}} = L(\hat{y}, y) + \lambda \sum w_i^2

其中:

  • λ\lambda:正則化強度(超參數)一般取10210310410^{-2}、10^{-3}、10^{-4}

  • wi2\sum w_i^2:所有權重的平方和(就是 L2 範數)

image

image


實際效果(直覺)

沒有 L2 的情況:

  • 模型可能會瘋狂放大某個權重,導致對訓練數據擬合得很好,但泛化很差。

有了 L2 正則:

  • 模型 “更保守”,不輕易拉大參數

  • 模型對輸入的波動更穩定(泛化能力更強)


在 PyTorch 中怎麼用?

L2 正則 = 權重衰退,所以 PyTorch 中你只要在優化器裡加:

optimizer = torch.optim.SGD(model.parameters(), lr=0.1, weight_decay=1e-4)

這個 weight_decay 參數其實就是 λ\lambda!默認就是 L2 正則。


在 sklearn 中怎麼用?

from sklearn.linear_model import Ridge  # Ridge 就是帶 L2 的線性回歸
model = Ridge(alpha=1.0)

總結一句話

L2 正則化 = 懲罰權重平方,壓縮但保留全部參數,提升模型泛化能力。

Dropout (丟棄法)#

一句話定義

Dropout 是一種隨機屏蔽神經元的正則化方法
它讓神經網絡在訓練時更 “健壯”,防止過擬合。


背後的動機

深度神經網絡容易過擬合,尤其當:

  • 層數深

  • 訓練數據小

  • 參數多,模型複雜

原因是:

模型會學會 “依賴某些神經元組合” 來記住訓練數據 → 泛化能力變差。

Dropout 就是打破這種依賴 ——
訓練時,隨機屏蔽(置 0)一部分神經元,強迫網絡不能只靠一小撮神經元合作,而是必須具備冗餘能力


怎麼操作的?

訓練時:

對某一隱層輸出向量 h=(h1,,hn)\mathbf h = (h_1,\dots,h_n)
訓練期應用:

h~=mph,miBernoulli(p)\tilde{\mathbf h}= \frac{\mathbf m}{p}\odot \mathbf h,\qquad m_i \sim \text{Bernoulli}(p)

保留概率 $p$ 由你設定;通常 0.5–0.9。

  • m\mathbf m:隨機掩碼,決定是否 “保留” 第 ii 個單元。

  • \odot:逐元素乘。

  • 1/p1/pinverted dropout 常用的重標定因子,使 E[h~i]=hi\mathbb E[\tilde h_i] = h_i,保證訓練 / 推斷期激活尺度一致。

所以從數學角度看,它是一種 乘性二元噪聲注入,並非真的把神經元物理地刪掉。

隨機掩碼(random mask)= 一張用 0/1 取值填充的張量,決定在本輪前向 / 反向傳播裡哪些單元 “暫時關燈”,哪些 “正常工作”。
在 Dropout(或其它噪聲正則)中,它是把乘性噪聲注入網絡的最小 “開關矩陣”。

元素值

mijBernoulli(p){1(保留)0(丟弃)m_{ij} \sim \text{Bernoulli}(p)\quad \bigl\{ \begin{array}{l} 1\quad(\text{保留})\\ 0\quad(\text{丟弃}) \end{array}

測試時:

不 Drop,全部激活,但輸出不縮放。


使用位置:
在全連接層(Dense Layer / Linear Layer)和其後的激活函數(如 ReLU, Sigmoid, Tanh 等)之間或之後。

  • 更常見的是放在激活函數之後: Dense -> Activation -> Dropout
  • 這樣做是因為 Dropout 的目的是隨機 “關閉” 神經元的輸出。激活函數的輸出代表了神經元的最終輸出信號,對其進行 Dropout 更直接地模擬了神經元的隨機失活。
  • 少數情況也可能放在激活函數之前: Dense -> Dropout -> Activation
    雖然不那麼主流,但也有研究和實踐表明這樣做有時也能取得效果。其邏輯是先對權重計算的線性組合結果進行 Dropout,然後再通過激活函數。

通常應用於一個或多個隱藏層 (Hidden Layers)

  • 對於較深的網絡,可以在多個隱藏層之後都使用 Dropout。
    是否在所有隱藏層都使用,以及使用多大的 Dropout 率 (dropout rate/probability),通常是需要通過實驗調整的超參數。

一般不建議在輸出層 (Output Layer) 使用 Dropout。

  • 輸出層負責產生最終的預測結果。如果在輸出層使用 Dropout,可能會干擾模型最終的預測輸出,特別是對於分類任務,可能會隨機丟棄掉某些類別的預測信號,這通常是不希望看到的。

PyTorch 實現:

import torch.nn as nn

net = nn.Sequential(
    nn.Linear(256, 128),
    nn.ReLU(),
    nn.Dropout(p=0.5),   # Dropout 層:訓練時屏蔽 50% 神經元
    nn.Linear(128, 10)
)

Dropout 的優勢:

優點描述
抑制過擬合強制網絡不能依賴某些特徵
增強泛化能力每次訓練像在訓練不同 “子網絡”
易用一行代碼即可加入

⚠️ 注意事項:

  • Dropout 只在訓練階段起作用,測試階段必須關閉 Dropout

  • 如果模型已經很小或者數據量足夠,Dropout 有時反而會傷害性能(欠擬合)。


總結一句話:

Dropout 是一種 “訓練時隨機丟點,測試時全開” 的策略,增強模型魯棒性,防止過擬合。

Early Stopping (早停法)#

一句話定義

Early Stopping 是通過監控驗證集表現,在模型開始過擬合前停止訓練的一種方法。


🧠 為什麼需要 Early Stopping?

我們在訓練一個模型時,經常會看到這樣的現象:

輪數訓練集準確率驗證集準確率
160%58%
1095%88% ✅
3099% ✅70% ❌

訓練集越來越好,但驗證集越來越差。這說明:

模型正在 “死記硬背” 訓練數據 → 過擬合開始了

這時候繼續訓練反而是浪費時間、甚至破壞模型。


✅** Early Stopping 的核心思路 **

很簡單:

觀察驗證集的表現,一旦它開始下降,就立刻停止訓練,保留效果最好的模型。

這樣:

  • 模型不會過擬合

  • 訓練速度更快

  • 一般不需要複雜的正則項

👉 所以 Early Stopping 是一種訓練級別的正則方法,而不是結構級別的。


總結一句話

Early Stopping 是最樸素但極有效的正則化策略:當驗證集不再變好,立刻停。

13、權重初始化#

為了避免 “信號爆炸或消失”,我們希望

網絡裡每一層的激活(正向)和梯度(反向)的均值 = 0,方差 = 常數

具體地它把每層的輸出 hith_i^t 和梯度 hit\frac{\partial \ell}{\partial h_i^t} 當作隨機變量:

方向均值方差
正向E[hit]=0\mathbb E[h_i^t]=0Var[hit]=a\mathrm{Var}[h_i^t]=a
反向E ⁣[hit]=0\mathbb E\!\left[\dfrac{\partial \ell}{\partial h_i^t}\right]=0Var ⁣[hit]=b\mathrm{Var}\!\left[\dfrac{\partial \ell}{\partial h_i^t}\right]=b

其中 a,ba,b 是兩個你自己定的常數(一般取 1 或 2),且 對所有層 tt 和所有通道 ii 都一樣

推導一層的 “方差守恆” 條件(全連接層為例)

hit=j=1ninWijtxjt1,xjt1 (上層激活)h_i^t=\sum_{j=1}^{n_{\text{in}}} W_{ij}^t\,x_j^{t-1},\qquad x_j^{t-1}~\text{(上層激活)}

常見假設

  1. E[xjt1]=0,  Var[xjt1]=a\mathbb E[x_j^{t-1}]=0,\; \mathrm{Var}[x_j^{t-1}]=a

  2. E[Wijt]=0,  Var[Wijt]=σw2\mathbb E[W_{ij}^t]=0,\; \mathrm{Var}[W_{ij}^t]=\sigma_w^2

  3. xxWW 獨立、元素之間近似獨立

於是

Var[hit]=ninσw2a\mathrm{Var}[h_i^t] = n_{\text{in}}\,\sigma_w^2\,a

要求 輸出方差繼續等於 aa

ninσw2a=a    σw2=1nin.n_{\text{in}}\,\sigma_w^2\,a = a \;\Longrightarrow\; \sigma_w^2 = \frac{1}{n_{\text{in}}}.

反向同理(梯度一路乘 WW^\top 傳播),要求

σw2=1nout.\sigma_w^2 = \frac{1}{n_{\text{out}}}.

兩端都顧及 → 折中方案

σw2=2nin+nout\sigma_w^2 = \frac{2}{n_{\text{in}}+n_{\text{out}}}

這就是 Glorot/Xavier 初始化。隨機初始化

Xavier 初始化(Glorot 初始化)#

一句話:它是一種設置網絡權重初值的策略,通過讓正向激活反向梯度在每一層都保持方差相近,緩解深度網絡裡的梯度消失 / 爆炸問題。提出者是 Xavier Glorot 與 Yoshua Bengio(2010)。

具體公式

采樣分布建議方差實際采樣區間 / 標準差
均勻 U (−r, r)σw2=2nin+nout\sigma_w^2 = \dfrac{2}{n_\text{in}+n_\text{out}}r=6nin+noutr = \sqrt{\dfrac{6}{n_\text{in}+n_\text{out}}}
正態 𝒩(0, σ²)同上σ=2nin+nout\sigma = \sqrt{\dfrac{2}{n_\text{in}+n_\text{out}}}
  • n_in: 本層每個神經元接收的輸入維度

  • n_out: 本層神經元個數

卷積層
nin=kernelh×kernelw×in_channelsn_\text{in}= \text{kernel}_h \times \text{kernel}_w \times \text{in\_channels}


與 He 初始化的區別

名稱建議方差適用激活
Xavier/Glorot2nin+nout\dfrac{2}{n_\text{in}+n_\text{out}}Sigmoid、tanh、soft-sign 等雙側激活
He/Kaiming2nin\dfrac{2}{n_\text{in}}ReLU、Leaky-ReLU、GELU(單側激活會丟掉 1/2 能量,需更大方差)
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。