很常聽到深度學習,但到底是在學些什麼?今天來跟我一起學習一個重要的概念:
多層感知機(MLP, Multi-Layer Perceptron)是最基礎的神經網路之一。它雖然簡單,卻是許多進階模型的基礎,例如 CNN(卷積神經網路) 和 Transformer(變換器)(某論文),用於處理自然語言模型。在寫這篇學習筆記不知道睡著幾次,如果以錯誤請不吝指教。
我會先從了解 MLP 的數學原理開始,了解知道神經網路的本質跟運作方式,並使用 PyTorch 來訓練一個 MLP 模型來辨識手寫數字 MNIST。
MLP 是一種前饋式神經網路(Feedforward Neural Network),至少包含三層:
每個神經元的輸出計算如下:
y=f(Wx+b)
其中:
借用這支影片來解釋,整個過程
呼~有點累了,小總結
在神經網路中,每個神經元都會接收輸入,然後透過權重(Weight)進行加權運算,最後經過活化函數(如 Sigmoid)產生輸出。
👉 可以把 權重(Weight) 想成決定「每個輸入有多重要」,而 Bias 則是「調整基準值」,讓神經網路有更多自由度來學習不同的模式
這是神經元的計算方式,權重跟偏差都是用矩陣計算
每個神經元會接收來自前一層的輸入,經過加權計算(Weight) 和 偏差(Bias),然後透過活化函數(Activation Function)決定是否「開燈」(活化)。
數學上,神經元的計算公式:
🔥 什麼時候神經元會被活化?(以 Sigmoid為例子)
🚦 規則Sigmoid:可以設定0.6以上才活化
MLP 需要活化函數來引入非線性,否則模型只是單純的線性變換(像 y = mx + b)。常見的活化函數有:
一般選擇:
我們希望神經網路能夠學習到最適合的權重(Weight)和偏差(Bias),讓它對輸入的資料做出最準確的預測。
為了達成這個目標,我們需要:
這時候,「反向傳播」就派上用場了!🚀
反向傳播(Backpropagation) 是一種用來計算梯度(Gradient)的方法,它告訴我們該如何調整每個權重與偏差,讓模型表現變好。
簡單來說,反向傳播的目標是讓「損失(Loss)」變小,它的核心步驟如下:
Backpropagation calculus | DL4
大概了解概念就好,這裡好難QQ
假設我們的神經網路只有一個神經元,活化函數使用 Sigmoid:
y=σ(Wx+b)
假設:
我們的目標是減少損失(Loss),所以要調整 W 和 b。
透過鏈鎖律(Chain Rule),計算權重 W的梯度:
也用計算偏差 b 的梯度
補充
🔍 什麼是鏈鎖律?
鏈鎖律(Chain Rule) 是微積分的一個重要公式,它告訴我們如何計算一個函數的複合函數的導數。
數學上,如果一個變數 z 依賴於 y,而 y 又依賴於 x,那麼需用鏈鎖律
👉 簡單來說,就是「一層一層地把梯度傳遞回去」,因為損失函數 L 並不是直接與所有權重 W 相關,而是通過中間變數(例如神經元的輸出)相連。
假設學習率(Learning Rate)η=0.1\eta = 0.1η=0.1:
模型的權重和偏差都變得更好,讓下一次的預測會更接近 1.0!
✅ 讓模型自動學習最佳權重
👉 透過梯度下降,神經網路可以「找到最好的數字」,讓它的預測越來越準確。
✅ 不需要人工設計規則
👉 在傳統機器學習(如 SVM)中,可能需要手動調整特徵,而神經網路透過反向傳播自動學習適合的特徵。
✅ 適用於大規模數據與深度網路
👉 反向傳播可以計算多層神經網路的梯度,讓像 GPT、BERT 這類的超大型 AI 模型得以訓練。
讓我們用 PyTorch 訓練一個 MLP 來辨識手寫數字 MNIST。MLP 的模型可以用 Torch.nn 這個函式庫練習。
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
# 1. 載入 MNIST 數據集
transform = transforms.Compose([transforms.ToTensor()])
train_dataset = datasets.MNIST(root='./data', train=True, transform=transform, download=True)
test_dataset = datasets.MNIST(root='./data', train=False, transform=transform, download=True)
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)
# 2. 定義 MLP 模型
class MLP(nn.Module):
def __init__(self):
super(MLP, self).__init__()
self.fc1 = nn.Linear(28*28, 128) # 第一層
self.fc2 = nn.Linear(128, 64) # 第二層
self.fc3 = nn.Linear(64, 10) # 輸出層(10 類別)
self.relu = nn.ReLU()
def forward(self, x):
x = x.view(-1, 28*28) # 展平成一維
x = self.relu(self.fc1(x))
x = self.relu(self.fc2(x))
x = self.fc3(x)
return x
model = MLP()
# 3. 設定損失函數與優化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 4. 訓練模型
epochs = 5
for epoch in range(epochs):
for images, labels in train_loader:
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
print(f'Epoch {epoch+1}/{epochs}, Loss: {loss.item():.4f}')
# 5. 驗證準確率
correct = 0
total = 0
with torch.no_grad():
for images, labels in test_loader:
outputs = model(images)
_, predicted = torch.max(outputs, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f'測試集準確率: {100 * correct / total:.2f}%')
雖然 MLP 是最簡單的神經網路之一,但它已經可以解決許多數據分類問題,例如:
如果想進一步學習,可以探索:
MLP 是深度學習的起點,透過 PyTorch,你可以快速實作並理解它的運作原理。希望這篇文章幫助你稍微了解神經網路的名詞!
如果你對 MLP 或 PyTorch 有任何問題,歡迎留言討論!💬🚀