一、神經網絡基礎
1. 神經元模型
在神經網絡中,最基本的單元是神經元(Neuron),也稱為節點或單元。它模擬了生物神經系統中的神經元行為。一個典型的神經元模型包含多個輸入(x1,x2,…,xnx_1, x_2, \ldots, x_nx1?,x2?,…,xn?),每個輸入都對應一個權重(w1,w2,…,wnw_1, w_2, \ldots, w_nw1?,w2?,…,wn?),以及一個偏置(bias)。神經元的輸出(yyy)通過激活函數(Activation Function)計算得出,公式如下:
y=f(∑i=1nwixi+b) y = f\left(\sum_{i=1}^{n} w_i x_i + b\right) y=f(i=1∑n?wi?xi?+b)
其中,fff 表示激活函數,常見的激活函數有Sigmoid、Tanh和ReLU等。
代碼示例:
import numpy as npdef sigmoid(z):return 1 / (1 + np.exp(-z))def neuron_output(weights, inputs, bias):z = np.dot(weights, inputs) + biasreturn sigmoid(z)weights = np.array([0.5, -0.2, 0.1])
inputs = np.array([1.0, 0.5, -1.5])
bias = 0.3output = neuron_output(weights, inputs, bias)
print("Neuron output:", output)
2. 激活函數
激活函數引入非線性特性,使得神經網絡能夠學習復雜的模式。常用的激活函數包括:
- Sigmoid: 將輸入映射到(0,1)區間,適用于二分類問題。
- Tanh: 將輸入映射到(-1,1)區間,輸出均值為0,收斂速度比Sigmoid快。
- ReLU(Rectified Linear Unit): 當輸入大于0時輸出輸入值,否則輸出0,緩解梯度消失問題,加速訓練。
代碼示例:
def tanh(z):return np.tanh(z)def relu(z):return np.maximum(0, z)# 示例比較不同激活函數
z = np.array([-2.0, -1.0, 0.0, 1.0, 2.0])
print("Sigmoid:", sigmoid(z))
print("Tanh:", tanh(z))
print("ReLU:", relu(z))
二、前饋神經網絡結構
1. 多層感知機(MLP)
前饋神經網絡由輸入層、一個或多個隱藏層及輸出層組成。每一層由多個神經元構成,層與層之間全連接。信息從輸入層流向輸出層,無反饋連接。
架構示意:
輸入層 -> 隱藏層1 -> 隱藏層2 -> ... -> 輸出層
代碼示例:
from keras.models import Sequential
from keras.layers import Dense# 構建一個簡單的三層MLP
model = Sequential()
model.add(Dense(units=32, activation='relu', input_dim=784)) # 輸入層(假設輸入為28x28圖像)
model.add(Dense(units=64, activation='relu')) # 隱藏層1
model.add(Dense(units=10, activation='softmax')) # 輸出層(10類分類)
2. 前向傳播過程
在前向傳播中,輸入數據通過網絡層層傳遞,每層的輸出作為下一層的輸入。最終,輸出層的輸出即為模型的預測結果。
代碼示例:
# 使用Keras進行前向傳播
import tensorflow as tf
from tensorflow.keras.datasets import mnist# 加載數據
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape(-1, 784).astype('float32') / 255
x_test = x_test.reshape(-1, 784).astype('float32') / 255
y_train = tf.keras.utils.to_categorical(y_train, 10)
y_test = tf.keras.utils.to_categorical(y_test, 10)# 編譯模型
model.compile(optimizer='adam',loss='categorical_crossentropy',metrics=['accuracy'])# 訓練模型
model.fit(x_train, y_train, epochs=5, batch_size=32)# 評估模型
loss, accuracy = model.evaluate(x_test, y_test)
print(f"Test Accuracy: {accuracy*100:.2f}%")
三、損失函數與優化器
1. 損失函數
損失函數衡量模型預測與真實標簽之間的差異,指導模型參數的調整。常見的損失函數包括:
- 均方誤差(MSE): 常用于回歸問題。
- 交叉熵損失(Cross-Entropy Loss): 常用于分類問題,特別是多類別分類。
- 二元交叉熵(Binary Cross-Entropy): 適用于二分類問題。
代碼示例:
from keras.losses import binary_crossentropy, categorical_crossentropy, mean_squared_error# 示例計算損失
y_true = np.array([1, 0, 0])
y_pred = np.array([0.8, 0.1, 0.1])# 多類別交叉熵
loss_ce = categorical_crossentropy(y_true, y_pred)
print("Categorical Cross-Entropy Loss:", loss_ce)# 二類別交叉熵
loss_bce = binary_crossentropy(y_true[0], y_pred[0])
print("Binary Cross-Entropy Loss:", loss_bce)
2. 優化器
優化器通過調整模型參數以最小化損失函數。常用的優化算法包括:
- 梯度下降(Gradient Descent): 最基本的優化方法,但收斂速度慢。
- 隨機梯度下降(SGD): 每次使用一個樣本更新參數,速度快但波動大。
- 動量(Momentum): 引入動量項,加速收斂并減少震蕩。
- 自適應學習率方法:
- Adagrad: 根據參數梯度的歷史累積調整學習率。
- RMSprop: 結合動量和Adagrad的優點,適應性更強。
- Adam: 結合了動量和RMSprop,廣泛使用的優化器。
代碼示例:
from keras.optimizers import SGD, Adam# 使用SGD優化器
sgd_optimizer = SGD(learning_rate=0.01, momentum=0.9)
model.compile(optimizer=sgd_optimizer, loss='categorical_crossentropy', metrics=['accuracy'])# 使用Adam優化器
adam_optimizer = Adam(learning_rate=0.001)
model.compile(optimizer=adam_optimizer, loss='categorical_crossentropy', metrics=['accuracy'])
四、反向傳播算法
1. 反向傳播原理
反向傳播(Backpropagation)是通過計算損失函數相對于每個參數的梯度,來更新網絡參數的過程。具體步驟包括:
- 前向傳播: 計算每一層的激活值和最終輸出。
- 計算損失: 比較輸出與真實標簽,計算損失。
- 反向傳播: 從輸出層開始,逐層向后計算梯度。
- 參數更新: 根據梯度和優化器規則更新權重和偏置。
2. 梯度計算與鏈式法則
反向傳播依賴于鏈式法則(Chain Rule),即復合函數的導數等于各函數導數的乘積。對于每一層,梯度通過激活函數的導數和權重矩陣傳遞回前一層。
代碼示例:
# 簡化的反向傳播示例(手動實現單層)
import numpy as np# 定義簡單的兩層網絡
input_data = np.array([[0.1, 0.2]])
weights = np.array([[0.5, -0.3], [0.2, 0.4]])
bias = np.array([0.1, -0.1])# 前向傳播
hidden_layer = sigmoid(np.dot(input_data, weights) + bias)
print("Hidden Layer Output:", hidden_layer)# 假設真實標簽為[0,1]
true_labels = np.array([[0, 1]])# 計算損失(使用MSE)
loss = np.mean((hidden_layer - true_labels) ** 2)
print("Loss:", loss)# 反向傳播:計算梯度
delta = hidden_layer - true_labels
dW = np.dot(input_data.T, delta)
db = np.sum(delta, axis=0)
print("Gradient dW:", dW)
print("Gradient db:", db)
五、訓練與驗證
1. 數據集劃分
為了評估模型的泛化能力,通常將數據集劃分為訓練集、驗證集和測試集。訓練集用于模型學習,驗證集用于調參和監控訓練過程,測試集用于最終評估。
代碼示例:
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris# 加載數據
data = load_iris()
X = data.data
y = data.target# 將多類別標簽轉換為one-hot編碼
y = tf.keras.utils.to_categorical(y, num_classes=3)# 劃分訓練集和測試集(80%訓練,20%測試)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
2. 過擬合與正則化
過擬合指模型在訓練集上表現良好,但在驗證集或測試集上表現較差。常見防止過擬合的方法包括:
- L1和L2正則化: 在損失函數中添加權重絕對值或平方和的懲罰項,限制權重大小。
- Dropout: 在訓練過程中隨機“丟棄”一部分神經元,減少神經元間的依賴。
- 早停(Early Stopping): 當驗證性能不再提升時停止訓練,防止過擬合。
代碼示例:
from keras.layers import Dropout
from keras.regularizers import l2
from keras.callbacks import EarlyStopping# 添加L2正則化和Dropout層
model = Sequential()
model.add(Dense(units=64, activation='relu', kernel_regularizer=l2(0.01), input_dim=4))
model.add(Dropout(0.5)) # Dropout比例為50%
model.add(Dense(units=3, activation='softmax'))# 編譯模型
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])# 添加早停回調
early_stop = EarlyStopping(monitor='val_loss', patience=5)
六、實戰案例:手寫數字識別
1. MNIST數據集介紹
MNIST是一個廣泛用于手寫數字識別的數據集,包含6萬張訓練圖像和1萬張測試圖像,每張圖像為28x28像素的灰度圖,對應數字0-9。該數據集簡單且具有代表性,適合初學者實踐神經網絡。
2. 數據預處理與加載
在訓練前,需要對圖像數據進行歸一化處理,將像素值縮放到[0,1]區間,以提高訓練效率和模型性能。此外,將標簽進行One-Hot編碼以適應多分類任務。
代碼示例:
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
import numpy as np
import matplotlib.pyplot as plt# 加載MNIST數據集
(x_train, y_train), (x_test, y_test) = mnist.load_data()
print(f"Training data shape: {x_train.shape}, Test data shape: {x_test.shape}")# 數據歸一化
x_train = x_train.astype('float32') / 255.0
x_test = x_test.astype('float32') / 255.0# 標簽One-Hot編碼
y_train = to_categorical(y_train, num_classes=10)
y_test = to_categorical(y_test, num_classes=10)