深度學習模型的訓練流程涉及多個關鍵環節,從啟用函式的選擇到過擬合的防範,都需要仔細考量。ReLU 啟用函式因其解決梯度消失問題和計算效率高等優勢,成為深度學習模型訓練中的常用選擇,但其「死亡 ReLU」問題仍需關注,Leaky ReLU、PReLU 等變體則提供瞭解決方案。Softmax 函式在多分類別問題中,能有效將輸出轉換為機率分佈,方便結果判讀。模型訓練過程中,過擬合是常見挑戰,L1/L2 正則化、Dropout、批次/層次歸一化等技術則能有效限制模型複雜度,提升泛化能力。
在實務應用上,PyTorch 和 Keras 等深度學習框架提供簡潔易用的 API,方便模型建構與訓練。以手寫數字識別為例,透過構建簡單的多層感知器模型,並利用 MNIST 資料集進行訓練,可以清楚展現深度學習模型的訓練流程,包含資料預處理、模型定義、損失函式與最佳化器設定,以及訓練與驗證過程。同時,PyTorch 的動態計算圖和自動微分特性,賦予開發者更大的彈性,而 Keras 的高階 API 則簡化了模型建構的複雜度,兩者各有優勢,可根據實際需求選擇。
深度神經網路的訓練
深度神經網路的訓練是一個複雜的過程,需要仔細選擇啟用函式以避免梯度消失和爆炸。幸運的是,ReLU(Rectified Linear Unit)啟用函式可以解決這兩個問題。ReLU的圖形和其導數如下:
ReLU具有以下幾個理想的特性:
- 它是冪等的,這意味著如果我們將一個值透過任意數量的ReLU啟用函式,它將不會改變。
- 它的導數要麼是0,要麼是1,這取決於反向傳播的值。這樣可以避免梯度消失。
- 它會產生稀疏啟用,這意味著輸出將是0的機率是0.5。
- 它在前向和反向傳播中計算速度更快。
然而,ReLU也有一個缺點,就是它可能會導致某些單元永久輸出0,這被稱為「死亡ReLU」。為瞭解決這個問題,提出了幾種ReLU的變體,例如Leaky ReLU、Parametric ReLU(PReLU)、Exponential Linear Unit(ELU)、Scaled Exponential Linear Unit(SELU)和Sigmoid Linear Unit(SiLU)。
最後,softmax啟用函式常用於分類別問題的輸出層。它可以將輸出轉換為機率分佈,讓我們可以將輸出解釋為每個類別的機率。
內容解密:
- ReLU啟用函式的圖形和導數
- Leaky ReLU、PReLU、ELU、SELU和SiLU的圖形和導數
- Softmax啟用函式的公式和性質
graph LR A[ReLU] --> B[Leaky ReLU] A --> C[PReLU] A --> D[ELU] A --> E[SELU] A --> F[SiLU] B --> G[Softmax]
圖表翻譯:
- ReLU啟用函式的圖形和導數:ReLU的圖形是對角線,導數是0或1。
- Leaky ReLU、PReLU、ELU、SELU和SiLU的圖形和導數:這些變體的圖形和導數與ReLU類別似,但有一些改動。
- Softmax啟用函式的公式和性質:Softmax的公式是f(z_i) = exp(z_i) / ∑_{j=1}^{n} exp(z_j),它具有正規化和可微分的性質。
flowchart TD A[ReLU] --> B[Leaky ReLU] A --> C[PReLU] A --> D[ELU] A --> E[SELU] A --> F[SiLU] B --> G[Softmax] G --> H[分類別問題]
軟體開發中常見的數學函式:softmax函式
在深度學習中,softmax函式是一種常用的啟用函式,尤其是在分類別問題中。它的主要功能是將輸入的向量轉換為一個機率分佈,確保輸出的值為正且總和為1。
給定一個向量 $z = [z_1, z_2, …, z_n]$, softmax函式的輸出為:
$$ \text{softmax}(z)i = \frac{e^{z_i}}{\sum{j=1}^{n} e^{z_j}} $$
這個函式的作用是將輸入的向量中的每個元素轉換為一個機率值,然後將這些機率值歸一化,確保它們的總和為1。這樣,輸出的向量就可以被解釋為一個機率分佈。
例如,假設我們有一個向量 $z = [1, 2]$, 那麼softmax函式的輸出為:
$$ \text{softmax}(z)_1 = \frac{e^1}{e^1 + e^2} = \frac{2.7}{2.7 + 7.39} = 0.27 $$
$$ \text{softmax}(z)_2 = \frac{e^2}{e^1 + e^2} = \frac{7.39}{2.7 + 7.39} = 0.73 $$
這個例子表明,softmax函式可以將輸入的向量轉換為一個機率分佈,其中較大的輸入值對應於較大的機率值。
交叉熵損失函式
在深度學習中,交叉熵損失函式是一種常用的損失函式,尤其是在分類別問題中。它的主要功能是衡量模型的預測結果與實際結果之間的差異。
給定一個實際的機率分佈 $p(x)$ 和一個預測的機率分佈 $q(x)$, 交叉熵損失函式的定義為:
$$ H(p, q) = -\sum_{j=1}^{n} p_j(x) \log q_j(x) $$
這個函式的作用是計算實際的機率分佈和預測的機率分佈之間的差異。當實際的機率分佈和預測的機率分佈完全相同時,交叉熵損失函式的值為0。
深度神經網路的過度擬合問題
過度擬合是深度神經網路中的一個常見問題。它發生在模型過度複雜,能夠完美地擬合訓練資料,但是在測試資料上表現不佳。
過度擬合的原因包括:
- 模型過度複雜
- 訓練資料不足
- 訓練時間過長
為了防止過度擬合,深度神經網路中常用的技術包括:
- 正則化:在損失函式中增加一項正則化項,來懲罰模型的複雜度。
- 早停:在訓練過程中監視模型的表現,如果模型的表現開始惡化,則停止訓練。
- 資料增強:增加訓練資料的多樣性,來防止模型過度擬合。
深度神經網路的正則化技術
深度神經網路的正則化技術是指在訓練過程中增加一項正則化項,來懲罰模型的複雜度。常用的正則化技術包括:
- L1正則化:在損失函式中增加一項L1正則化項,來懲罰模型的權重。
- L2正則化:在損失函式中增加一項L2正則化項,來懲罰模型的權重。
- Dropout:在訓練過程中隨機地丟棄一些神經元,來防止模型過度擬合。
這些正則化技術可以有效地防止模型過度擬合,從而提高模型的泛化能力。
最小-最大歸一化
最小-最大歸一化是一種常用的資料預處理技術。它的主要功能是將資料的範圍轉換為一個統一的範圍,通常是[0, 1]。
給定一個資料集 $x = [x_1, x_2, …, x_n]$, 最小-最大歸一化的公式為:
$$ x’ = \frac{x - x_{min}}{x_{max} - x_{min}} $$
這個公式的作用是將資料的範圍轉換為[0, 1],其中 $x_{min}$ 和 $x_{max}$ 分別是資料的最小值和最大值。
最小-最大歸一化可以有效地防止資料的範圍不同導致的問題,從而提高模型的泛化能力。
標準化技術
在深度神經網路的訓練中,資料標準化是一個非常重要的步驟。標準化的目的是將所有的輸入資料轉換到一個共同的尺度上,以便於神經網路的學習和訓練。
最小-最大標準化
最小-最大標準化是一種常用的標準化方法,它將所有的輸入資料轉換到[0, 1]的範圍內。這個方法的公式如下:
x’ = (x - x_min) / (x_max - x_min)
其中,x’是標準化後的資料,x是原始資料,x_min是資料集中的最小值,x_max是資料集中的最大值。
例如,對於一張灰度影像,顏色值的範圍是0到255。假設有一個畫素的強度是125,那麼它的標準化值是:
x’ = (125 - 0) / (255 - 0) = 0.49
最小-最大標準化是一種快速且容易實作的方法,但是它有一個缺點,就是資料集中的異常值可能會對標準化結果產生很大的影響。例如,如果資料集中有一個錯誤的元素具有非常大的值,它將會成為x_max,並且會使得所有的標準化值趨近於0。
標準分數(Z分數)標準化
標準分數(Z分數)標準化是一種更好的標準化方法,它可以更好地處理資料集中的異常值。標準分數的公式如下:
z = (x - μ) / σ
其中,z是標準化後的資料,x是原始資料,μ是資料集的平均值,σ是資料集的標準差。
平均值μ的計算公式如下:
μ = (1/N) * ∑(x_i)
其中,x_i是資料集中的單個元素,N是資料集的大小。
標準差σ的計算公式如下:
σ = √((1/N) * ∑(x_i - μ)^2)
標準分數標準化可以更好地處理資料集中的異常值,因為它使用了平均值和標準差來計算標準化值。這使得標準化結果更加穩健和可靠。
深度學習基礎
深度學習是一種人工智慧技術,模仿人類大腦的結構和功能,對資料進行分析和學習。在深度學習中,資料的預處理是一個非常重要的步驟。預處理的目的是將資料轉換為模型可以接受的格式,並且去除資料中的噪音和不相關的訊息。
標準差和變異數
標準差是描述資料分散程度的一個指標,它表示資料點與平均值之間的距離。變異數是標準差的平方,表示資料點之間的距離。標準差和變異數都是描述資料分散程度的重要指標。
$$\sigma = \sqrt{\frac{1}{N} \sum_{i=1}^{N} (x_i - \mu)^2}$$
$$\sigma^2 = \frac{1}{N} \sum_{i=1}^{N} (x_i - \mu)^2$$
資料增強
資料增強是一種技術,透過人工增加訓練資料的大小,從而提高模型的泛化能力。例如,在影像分類別中,資料增強可以透過旋轉、翻轉、縮放等方式增加影像的變化性。
Dropout
Dropout是一種正則化技術,透過隨機刪除神經網路中的某些單元,從而防止模型過度擬合。Dropout只在訓練階段使用,在推理階段,所有單元都會被使用。
批次歸一化
批次歸一化是一種正則化技術,透過對神經網路的隱藏層進行歸一化,從而提高模型的訓練速度和泛化能力。批次歸一化的目的是將隱藏層的輸出值的平均值和標準差分別設為0和1。
$$\hat{x}{ij} = \frac{x{ij} - \mu_X}{\sqrt{\sigma_X^2 + \epsilon}}$$
$$y_{ij} = \gamma \hat{x}_{ij} + \beta$$
層次歸一化
層次歸一化是一種正則化技術,透過對神經網路的每一層進行歸一化,從而提高模型的訓練速度和泛化能力。層次歸一化的目的是將每一層的輸出值的平均值和標準差分別設為0和1。
$$\mu_{x_i} = \frac{1}{n} \sum_{j=1}^{n} x_{ij}$$
$$\sigma_{x_i}^2 = \frac{1}{n} \sum_{j=1}^{n} (x_{ij} - \mu_{x_i})^2$$
$$\hat{x}{ij} = \frac{x{ij} - \mu_{x_i}}{\sqrt{\sigma_{x_i}^2 + \epsilon}}$$
$$y_{ij} = \gamma \hat{x}_{ij} + \beta$$
深度學習的正則化技術
在深度學習中,正則化技術是一種用於防止過度擬合的方法。過度擬合是指模型在訓練資料上表現良好,但在測試資料上表現不佳。這是因為模型過度複雜,學習到了訓練資料中的噪音和隨機性。
批次正則化(Batch Normalization)
批次正則化是一種常用的正則化技術,它透過對每個批次的輸入資料進行正則化,來防止過度擬合。批次正則化的步驟如下:
- 計算每個批次的均值和標準差。
- 將每個批次的輸入資料進行正則化,使用均值和標準差。
- 將正則化的輸入資料輸入到神經網路中。
批次正則化的優點是,它可以加速訓練速度,改善模型的泛化能力。然而,它也有一些缺點,例如需要計算每個批次的均值和標準差,這可能會增加計算成本。
層正則化(Layer Normalization)
層正則化是一種與批次正則化類別似的技術,但它是對每個層的輸入資料進行正則化。層正則化的步驟如下:
- 計算每個層的均值和標準差。
- 將每個層的輸入資料進行正則化,使用均值和標準差。
- 將正則化的輸入資料輸入到下一個層中。
層正則化的優點是,它可以改善模型的泛化能力,尤其是在深度神經網路中。
RMSNorm
RMSNorm是一種簡化的層正則化技術,它只對每個層的輸入資料進行重新縮放,而不進行重新中心化。RMSNorm的步驟如下:
- 計算每個層的均方根(RMS)。
- 將每個層的輸入資料進行重新縮放,使用RMS。
RMSNorm的優點是,它可以加速訓練速度,改善模型的泛化能力。
L2正則化
L2正則化是一種對模型的權重進行懲罰的技術,它可以防止過度擬合。L2正則化的步驟如下:
- 將模型的權重進行平方。
- 將平方的權重進行求和。
- 將求和的結果增加到損失函式中。
L2正則化的優點是,它可以防止過度擬合,改善模型的泛化能力。
深度學習的應用
深度學習的應用非常廣泛,包括影像識別、語音識別、自然語言處理等。深度學習可以用於解決許多複雜的問題,例如影像分類別、物體偵測、語言翻譯等。
影像識別
影像識別是一種用於識別影像中物體的技術。深度學習可以用於影像識別,例如使用卷積神經網路(CNN)進行影像分類別。
語音識別
語音識別是一種用於識別語音中單詞的技術。深度學習可以用於語音識別,例如使用迴圈神經網路(RNN)進行語音識別。
自然語言處理
自然語言處理是一種用於處理自然語言的技術。深度學習可以用於自然語言處理,例如使用長短期記憶網路(LSTM)進行語言翻譯。
深度學習的應用
深度學習(DL)是一種機器學習(ML)技術,近年來在各個領域取得了令人驚艷的成果。從影像識別、語音辨識到自然語言處理,深度學習都展示了其強大的能力。然而,隨著深度學習的發展,一些人開始擔心機器可能會超越人類的智慧。但是,經過本章的閱讀,你將會發現,我們仍然遠遠沒有達到機器具有人類級別智慧的境界。
深度學習的基礎
讓我們來探討一些深度學習的實際應用案例:
- 自動駕駛:現代汽車已經具備了多種安全和便捷的功能,例如自動緊急制動和車道保持助手。這些系統使用前置攝像頭來識別車道標誌、其他車輛、行人和腳踏車。Mobileye是這些系統的著名供應商之一,Intel在2017年以153億美元收購了Mobileye。這並不是一個孤立的案例,特斯拉的Autopilot系統也依賴於卷積神經網路(CNN)來實作自動駕駛。
- 醫學應用:深度學習在醫學領域具有巨大的潛力,例如醫學影像分析、病理學分析和醫學記錄分析。然而,嚴格的法規要求和患者資料保密性限制了其採用。儘管如此,我們仍然可以找出深度學習可以產生重大影響的領域。例如,醫學影像是一種非侵入性方法,用於建立人體內部的視覺化表現。電腦輔助診斷和電腦視覺可以幫助專家更好地分析醫學影像。
深度學習函式庫的介紹
現在,讓我們來介紹兩個流行的深度學習函式庫:PyTorch和Keras。
- PyTorch:PyTorch是一個獨立的函式庫,提供了動態計算圖和自動微分的功能。它支援GPU運算和分散式訓練。
- Keras:Keras是一個高階神經網路API,可以在 TensorFlow、Theano或Microsoft Cognitive Toolkit(CNTK)上執行。它提供了簡單的API,用於構建和訓練神經網路。
使用Keras進行手寫數字識別
讓我們使用Keras來識別手寫數字。MNIST資料集是一個流行的資料集,包含70,000個手寫數字的影像。我們可以使用Keras的load_data()
函式來載入這個資料集。
import tensorflow as tf
(X_train, Y_train), (X_validation, Y_validation) = tf.keras.datasets.mnist.load_data()
然後,我們需要將資料進行預處理,包括重塑和歸一化。
X_train = X_train.reshape(60000, 784) / 255
X_validation = X_validation.reshape(10000, 784) / 255
接下來,我們可以使用Keras的Sequential
API來構建一個簡單的神經網路。
model = tf.keras.models.Sequential([
tf.keras.layers.Dense(64, activation='relu', input_shape=(784,)),
tf.keras.layers.Dense(10, activation='softmax')
])
最後,我們可以編譯和訓練模型。
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(X_train, Y_train, epochs=5, validation_data=(X_validation, Y_validation))
這個例子展示瞭如何使用Keras來識別手寫數字。深度學習的應用遠遠不止於此,隨著技術的發展,我們可以期待看到更多令人興奮的應用案例。
深度學習基礎
在深度學習中,神經網路(NN)是一種重要的模型。以下是建立一個簡單的神經網路的步驟:
步驟1:定義類別數量
首先,我們需要定義類別的數量。假設我們有10個類別,則可以使用以下程式碼:
classes = 10
步驟2:將標籤轉換為類別編碼
接下來,我們需要將標籤轉換為類別編碼。這可以使用TensorFlow的to_categorical
函式:
Y_train = tf.keras.utils.to_categorical(Y_train, classes)
Y_validation = tf.keras.utils.to_categorical(Y_validation, classes)
步驟3:定義神經網路模型
現在,我們可以定義神經網路模型。這裡,我們使用的是序列模型(Sequential model),其中每一層都作為下一層的輸入。在Keras中,Dense
代表的是全連線層(fully connected layer)。我們將使用一個具有100個單位的隱藏層,批次歸一化(Batch Normalization),ReLU啟用函式和softmax輸出:
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, BatchNormalization, Activation
input_size = 784
hidden_units = 100
model = Sequential([
Dense(hidden_units, input_dim=input_size),
BatchNormalization(),
Activation('relu'),
Dense(classes),
Activation('softmax')
])
步驟4:定義最佳化器和損失函式
接下來,我們需要定義最佳化器和損失函式。這裡,我們使用的是Adam最佳化器和類別交叉熵損失函式(categorical cross-entropy loss):
model.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer='adam')
步驟5:訓練模型
現在,我們可以訓練模型了。這裡,我們使用的是fit
方法,該方法會在資料集上進行迭代。Keras會預設使用GPU進行訓練,如果GPU不可用,則會fallback到CPU:
model.fit(X_train, Y_train, batch_size=100, epochs=20, verbose=1)
步驟6:評估模型
最後,我們需要評估模型的準確度。這可以使用evaluate
方法:
score = model.evaluate(X_validation, Y_validation, verbose=1)
內容解密:
上述程式碼定義了一個簡單的神經網路模型,包括隱藏層、批次歸一化、ReLU啟用函式和softmax輸出。最佳化器和損失函式也被定義為Adam和類別交叉熵損失函式。模型在訓練資料集上進行訓練,然後在驗證資料集上進行評估。
圖表翻譯:
以下是神經網路模型的Mermaid圖表:
graph LR A[輸入層] --> B[隱藏層] B --> C[批次歸一化] C --> D[ReLU啟用函式] D --> E[softmax輸出] E --> F[輸出層]
這個圖表展示了神經網路模型的結構,包括輸入層、隱藏層、批次歸一化、ReLU啟用函式和softmax輸出。
深度學習基礎
介紹流行的深度學習函式庫
在前面的章節中,我們已經實作了一個簡單的神經網路來分類別手寫數字。現在,我們來看看如何使用 PyTorch 來實作相同的功能。
使用 PyTorch 分類別數字
PyTorch 是一個流行的深度學習函式庫,提供了動態計算圖和自動微分等功能。下面是使用 PyTorch 分類別數字的例子:
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
# 定義神經網路模型
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.fc1 = nn.Linear(28 * 28, 128) # 輸入層 (28x28 圖片) -> 隱藏層 (128 個單位)
self.fc2 = nn.Linear(128, 10) # 隱藏層 (128 個單位) -> 輸出層 (10 個類別)
def forward(self, x):
x = x.view(-1, 28 * 28) # 將輸入圖片展平為 1D 陣列
x = torch.relu(self.fc1(x)) # 啟用函式 (ReLU)
x = self.fc2(x)
return x
# 初始化模型、損失函式和最佳化器
model = Net()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)
# 載入 MNIST 資料集
transform = transforms.ToTensor()
train_dataset = datasets.MNIST('~/.pytorch/MNIST_data/', download=True, train=True, transform=transform)
test_dataset = datasets.MNIST('~/.pytorch/MNIST_data/', download=True, train=False, transform=transform)
# 訓練模型
for epoch in range(10):
for x, y in train_dataset:
x = x.view(-1, 28 * 28)
y = y.view(-1)
optimizer.zero_grad()
output = model(x)
loss = criterion(output, y)
loss.backward()
optimizer.step()
# 測試模型
model.eval()
test_loss = 0
correct = 0
with torch.no_grad():
for x, y in test_dataset:
x = x.view(-1, 28 * 28)
output = model(x)
loss = criterion(output, y)
test_loss += loss.item()
_, predicted = torch.max(output, 1)
correct += (predicted == y).sum().item()
accuracy = correct / len(test_dataset)
print('測試準確率:', accuracy)
# 顯示隱藏層的權重
weights = model.fc1.weight
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np
fig = plt.figure()
for i in range(128):
ax = fig.add_subplot(10, 13, i + 1)
ax.axis("off")
ax.imshow(np.reshape(weights[i].numpy(), (28, 28)), cmap=cm.Greys_r)
plt.show()
這個例子使用 PyTorch 來實作一個簡單的神經網路,分類別手寫數字。模型的架構與 Keras 的例子相同,使用兩個全連線層(fc1 和 fc2)來分類別數字。訓練過程中,我們使用隨機梯度下降法(SGD)來更新模型的引數,損失函式為交叉熵損失(CrossEntropyLoss)。最終,我們顯示了隱藏層的權重,觀察模型學習到的特徵。
圖表翻譯:
此圖顯示了 PyTorch 模型學習到的特徵,隱藏層的權重被重塑為 28x28 的二維陣列,並使用灰度 colormap 顯示。每個子圖代表一個隱藏層單位學習到的特徵,顯示了模型對數字圖片的理解。
使用PyTorch進行深度學習
在本文中,我們將使用PyTorch重建一個簡單的神經網路模型。首先,我們需要選擇使用的裝置(CPU或GPU)。
import torch
# 選擇裝置(CPU或GPU)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
接下來,我們需要載入MNIST資料集。PyTorch支援MNIST資料集,並且可以自動下載和分割資料。
from torchvision import datasets
from torchvision.transforms import ToTensor, Lambda, Compose
# 載入訓練資料
train_data = datasets.MNIST(
root='data',
train=True,
transform=Compose([
ToTensor(),
Lambda(lambda x: torch.flatten(x))
]),
download=True
)
# 載入驗證資料
validation_data = datasets.MNIST(
root='data',
train=False,
transform=Compose([
ToTensor(),
Lambda(lambda x: torch.flatten(x))
])
)
資料集會自動下載和分割成訓練和驗證部分。ToTensor()
轉換函式將影像從numpy陣列轉換為PyTorch張量,並將其歸一化到[0, 1]範圍內。torch.flatten()
轉換函式將二維28x28影像展平為一維784張量,以便我們可以將其餵入神經網路。
封裝資料集
接下來,我們需要將資料集封裝在DataLoader
例項中。
from torch.utils.data import DataLoader
# 封裝訓練資料
train_loader = DataLoader(
dataset=train_data,
batch_size=100,
shuffle=True
)
# 封裝驗證資料
validation_loader = DataLoader(
dataset=validation_data,
batch_size=100,
shuffle=True
)
DataLoader
例項會自動建立mini-batch和隨機打亂資料。它們也是迭代器,可以一次提供一個mini-batch。
定義神經網路模型
然後,我們需要定義神經網路模型。這裡,我們使用了一個具有單個隱藏層的多層感知器(MLP)。
torch.manual_seed(1234)
hidden_units = 100
classes = 10
model = torch.nn.Sequential(
torch.nn.Linear(28 * 28, hidden_units),
torch.nn.BatchNorm1d(hidden_units),
torch.nn.ReLU(),
torch.nn.Linear(hidden_units, classes)
)
這個定義類別似於Keras的定義。不同之處在於,PyTorch的Linear
(全連線)層需要指定輸入和輸出維度,因為它們不能自動提取前一層的輸出維度。啟用函式被定義為單獨的操作。
圖表翻譯:
graph LR A[資料集] --> B[ToTensor()] B --> C[torch.flatten()] C --> D[DataLoader] D --> E[神經網路模型] E --> F[訓練] F --> G[驗證]
這個圖表展示了資料集的轉換和封裝過程,以及神經網路模型的定義和訓練過程。
定義損失函式和最佳化器
在深度學習中,損失函式(Loss Function)是用來衡量模型預測值與真實值之間的差異。最佳化器(Optimizer)則是用來調整模型的引數,以最小化損失函式。以下是定義損失函式和最佳化器的步驟:
import torch
import torch.nn as nn
import torch.optim as optim
# 定義交叉熵損失函式
cost_func = nn.CrossEntropyLoss()
# 定義Adam最佳化器
optimizer = optim.Adam(model.parameters())
定義訓練模型函式
訓練模型函式(train_model)是用來訓練模型的。它需要模型、損失函式、最佳化器和資料載入器(data_loader)等引數。以下是定義訓練模型函式的步驟:
def train_model(model, cost_function, optimizer, data_loader):
# 將模型移到GPU
model.to(device)
# 設定模型為訓練模式
model.train()
# 初始化損失和準確率
current_loss = 0.0
current_acc = 0
# 迭代訓練資料
for i, (inputs, labels) in enumerate(data_loader):
# 將輸入和標籤移到GPU
inputs = inputs.to(device)
labels = labels.to(device)
# 清空引數梯度
optimizer.zero_grad()
# 啟用梯度計算
with torch.set_grad_enabled(True):
# 前向傳播
outputs = model(inputs)
loss = cost_function(outputs, labels)
# 反向傳播
loss.backward()
# 更新引數
optimizer.step()
# 更新損失和準確率
current_loss += loss.item()
_, predicted = torch.max(outputs, 1)
current_acc += (predicted == labels).sum().item()
# 計算平均損失和準確率
average_loss = current_loss / len(data_loader)
average_acc = current_acc / len(data_loader.dataset)
return average_loss, average_acc
訓練模型
現在可以使用定義好的訓練模型函式來訓練模型了。需要傳入模型、損失函式、最佳化器和資料載入器等引數。
# 訓練模型
average_loss, average_acc = train_model(model, cost_func, optimizer, data_loader)
print(f"平均損失:{average_loss:.4f}, 平均準確率:{average_acc:.4f}")
內容解密:
在上面的程式碼中,我們定義了交叉熵損失函式和Adam最佳化器。然後,我們定義了訓練模型函式,該函式需要模型、損失函式、最佳化器和資料載入器等引數。該函式會迭代訓練資料,清空引數梯度,啟用梯度計算,前向傳播,反向傳播,更新引數,更新損失和準確率。最後,我們使用定義好的訓練模型函式來訓練模型,並計算平均損失和準確率。
圖表翻譯:
graph LR A[模型] --> B[損失函式] B --> C[最佳化器] C --> D[訓練模型函式] D --> E[訓練資料] E --> F[損失和準確率] F --> G[平均損失和準確率]
在上面的圖表中,我們可以看到模型、損失函式、最佳化器、訓練模型函式、訓練資料、損失和準確率、平均損失和準確率之間的關係。這個圖表可以幫助我們更好地理解訓練模型的過程。
PyTorch 訓練流程實作
PyTorch 中的模型訓練需要手動實作,與 Keras 的 fit
函式不同。以下是使用 PyTorch 進行模型訓練的步驟:
從技術架構視角來看,本文深入淺出地介紹了深度學習的基礎知識、常用啟用函式ReLU及其變體、損失函式、正則化技術以及兩種主流深度學習框架:Keras 和 PyTorch。文章不僅清晰地闡述了各個元件的原理和特性,更重要的是提供了大量的程式碼範例,方便讀者快速上手實踐,尤其是在手寫數字識別、模型訓練、資料預處理等方面給出了詳盡的步驟和說明。然而,文章對於不同正則化技術的比較分析略顯不足,例如,何時選擇Batch Normalization,何時選擇Layer Normalization 缺乏更具體的指導。
透過比較 Keras 和 PyTorch 的程式碼實作,可以發現兩種框架在易用性和靈活性上的差異。Keras 更為簡潔易用,適合快速原型開發;而 PyTorch 提供了更細粒度的控制,適合研究和客製化模型。技術團隊在技術選型時,需要根據專案的具體需求和團隊成員的技術背景進行權衡。對於追求快速開發的應用場景,Keras 或許是更佳選擇;而對於需要深入研究模型結構和訓練過程的場景,PyTorch 則更具優勢。
展望未來,隨著深度學習技術的持續發展,更高效的模型架構、更最佳化的訓練演算法以及更便捷的開發工具將不斷湧現。開發者需要持續學習新技術,關注社群動態,才能保持技術的領先性。玄貓認為,深入理解深度學習的底層原理,掌握至少一種主流深度學習框架,將是未來開發者必備的核心競爭力。對於想要入門深度學習的開發者,本文提供了一個很好的學習路徑,建議從理解基本概念入手,逐步深入到程式碼實踐,並結合實際專案需求,不斷提升自己的深度學習技能。