一、神經網絡的基本組成與分類
1.1 神經網絡的核心組成部分
神經網絡是現代人工智能的基石,其設計靈感來源于生物神經系統的信息處理方式。作為工程師,了解神經網絡的基本組成部分對于構建和優化模型至關重要。一個典型的神經網絡主要由以下幾個關鍵部分組成:
神經元: 也稱為節點或單元,是神經網絡的基本計算單元。每個神經元接收輸入信號,通過加權求和和激活函數產生輸出信號。神經元是神經網絡的最小功能單位,通過不同的連接方式構成復雜的網絡結構
層(Layers): 由多個神經元組成的集合,是神經網絡的基本結構單元。神經網絡通常由三種類型的層組成:
- 輸入層(Input Layer): 接收外部數據輸入的神經元集合,輸入層的神經元數目通常與輸入數據的特征數目相同。輸入層不包含任何權重或激活函數,其主要任務是接收原始輸入數據并將其傳遞給神經網絡的第一個隱藏層
- 隱藏層(Hidden Layers): 位于輸入層和輸出層之間,負責對輸入數據進行特征提取和轉換。隱藏層可以有多層(構成深度神經網絡),每層包含多個神經元。隱藏層是神經網絡的核心部分,負責學習數據中的復雜模式和特征
- 輸出層(Output Layer): 生成最終預測結果的神經元集合。輸出層的神經元數目取決于具體任務,如分類問題中類的數目。輸出層使用特定的激活函數(如 softmax用于分類,線性激活用于回歸)將神經網絡的內部表示轉換為最終預測結果
權重(Weights): 表示神經元之間連接的強度。每個連接都有一個權重,表示輸入信號的重要性。權重是通過訓練過程調整的關鍵參數,它們決定了神經網絡從數據中學習到的知識
偏置(Biases): 每個神經元都有一個偏置項,用于調整激活函數的輸入,從而控制輸出信號。偏置有助于模型在沒有輸入信號時也能產生非零輸出,增加了模型的靈活性
激活函數(Activation Functions): 將神經元的加權和輸入轉換為輸出信號的函數,增加網絡的非線性表達能力。常見的激活函數包括:
-
ReLU(Rectified Linear Unit): 當輸入大于 0 時輸出輸入值,否則輸出 0。ReLU 是深度學習中最常用的激活函數之一,能夠有效緩解梯度消失問題
-
Sigmoid: 將輸入映射到 (0, 1) 區間,常用于二分類問題的輸出層
-
Tanh: 將輸入映射到 (-1, 1) 區間,輸出值以 0 為中心,通常比 sigmoid 表現更好
-
Softmax: 常用于多分類問題的輸出層,將多個神經元的輸出轉換為概率分布
損失函數(Loss Function): 衡量神經網絡預測輸出與實際目標之間差異的函數。損失函數是優化過程的核心,常見的損失函數包括:
-
均方誤差(MSE,Mean Squared Error):常用于回歸任務
-
交叉熵(Cross Entropy)損失:常用于分類任務
-
二進制交叉熵(Binary Cross Entropy):用于二分類任務
優化器(Optimizers): 用于調整神經網絡權重和偏置的算法,以最小化損失函數。常見的優化器包括:
-
梯度下降(Gradient Descent)及其變體(如隨機梯度下降 SGD)
-
Adam:一種自適應學習率的優化器,是深度學習中最常用的優化器之一
-
RMSprop:另一種自適應學習率的優化器
前向傳播(Forward Propagation): 數據從輸入層經過隱藏層到輸出層的過程。每層的神經元將輸入信號進行加權求和,通過激活函數生成輸出信號,傳遞到下一層。
反向傳播(Backward Propagation): 通過計算損失函數相對于每個權重和偏置的梯度,逐層調整網絡參數的過程。反向傳播結合優化器,使得神經網絡能夠學習和改進。
正則化(Regularization): 防止過擬合的一些技術,如 L1 和 L2 正則化、Dropout 等,通過增加模型泛化能力提高性能。
1.2 神經網絡的主要分類
神經網絡可以根據不同的標準進行分類。以下是幾種常見的分類方式:
按網絡結構分類
前饋神經網絡(Feedforward Neural Network, FNN):
- 數據只能從輸入層向前傳播到輸出層,沒有反饋環路
- 每層的神經元只與下一層的神經元相連,沒有層內連接或跨層連接
- 是最基礎的神經網絡類型,包括多層感知機(MLP)
- 優點:結構簡單,易于實現和訓練;缺點:無法捕捉數據中的時序依賴關系
循環神經網絡(Recurrent Neural Network, RNN):
- 具有反饋環路,允許信息在網絡中循環流動,使得網絡可以記住之前的輸入信息
- 特別適合處理序列數據(如文本、語音、時間序列),能夠捕捉數據中的時序依賴關系
- 常見的變體包括長短期記憶網絡(LSTM)和門控循環單元(GRU)
- 缺點:訓練過程中可能遇到梯度消失或爆炸問題,難以捕捉長距離依賴關系
卷積神經網絡(Convolutional Neural Network, CNN):
- 主要用于處理網格結構數據(如圖像、音頻),通過卷積層提取數據中的局部特征
- 包含卷積層、池化層和全連接層等組件
- 具有參數共享和局部連接的特點,大大減少了模型參數數量,提高了訓練效率
- 廣泛應用于計算機視覺任務,如圖像識別、目標檢測、圖像分割等
Transformer 網絡:
- 專為處理序列數據設計,特別是自然語言處理任務
- 核心創新在于注意力機制,能夠并行處理數據并捕捉長距離依賴關系
- 與循環神經網絡不同,Transformer 因并行處理數據而天然缺失詞序理解能力,因此需要位置編碼來提供序列中各詞元的位置信息
- 采用多頭注意力機制,能夠在不同語義維度上施加差異化關注,增強模型理解力
- 廣泛應用于機器翻譯、文本摘要、語言模型等任務
狀態空間模型(State Space Models, SSM):
- 一種新興的序列建模方法,結合了循環神經網絡和狀態空間建模的優勢
- 通過狀態隨時間演化的過程捕捉序列數據中的時序特征,能夠有效建模長距離依賴,同時保持線性計算復雜度
- 與傳統 RNN 相比,具有更好的訓練穩定性和更長的記憶能力
- 代表性模型包括 Mamba、S4 等,在長序列任務中表現出色
按學習范式分類
監督學習神經網絡:
-
使用帶標簽的訓練數據進行學習,模型的目標是最小化預測結果與真實標簽之間的差異
-
包括分類任務(如圖像分類、文本分類)和回歸任務(如房價預測、股票價格預測)
無監督學習神經網絡:
- 使用無標簽的訓練數據進行學習,模型的目標是發現數據中的潛在結構或模式
- 常見任務包括聚類、降維、異常檢測等
強化學習神經網絡:
- 通過與環境的交互進行學習,根據環境反饋的獎勵信號調整自身行為
- 常用于機器人控制、游戲 AI 等領域
按網絡深度分類
淺層神經網絡:
- 通常指只有一個隱藏層的神經網絡,也稱為單層感知機
- 表達能力有限,只能解決簡單的線性可分問題
深層神經網絡:
- 具有多個隱藏層的神經網絡,能夠學習數據中的復雜非線性關系
- 需要更復雜的訓練技術和更多的數據,但具有更強的表達能力
1.3 神經網絡的關鍵組件詳解
神經元與感知機
神經元是神經網絡的基本計算單元,靈感來源于生物神經元。感知機是最早的人工神經元模型,其計算方式為對輸入特征進行加權求和后,再加上一個偏置值,最后通過激活函數輸出。其數學表達式可寫作:
其中,x_i為輸入特征,w_i為權重,b為偏置,f為激活函數
層類型詳解
輸入層(Input Layer):
- 接收外部數據輸入的神經元集合
- 輸入層的神經元數目通常與輸入數據的特征數目相同
- 不包含任何權重或激活函數,僅負責將原始輸入數據傳遞給下一層
全連接層(Fully Connected Layer/Dense Layer):
-
每個神經元與上一層的每個神經元相連接,是最基本的神經網絡層
-
每個連接都有一個權重,通過激活函數進行非線性轉換
-
常用于深度神經網絡的中間層,用于學習復雜的非線性關系,適用于圖像分類、自然語言處理等任務
卷積層(Convolutional Layer):
-
包含卷積核,用于在圖像或序列數據上執行卷積操作,以檢測局部特征
-
通過參數共享和局部連接減少模型參數數量,提高計算效率
-
主要用于計算機視覺任務,如圖像識別、對象檢測、圖像分割。也可應用于序列數據處理,如文本分類
池化層(Pooling Layer):
- 用于減小特征圖的尺寸,通常采用最大池化或平均池化
- 有助于減少計算量和提取重要特征
- 在卷積神經網絡(CNN)中,池化層常用于減少維度,改善模型的穩健性
循環層(Recurrent Layer):
-
用于處理序列數據,可以捕獲時間依賴性,包括簡單循環層、LSTM 和 GRU
-
特別適合處理文本、語音、時間序列等序列數據
-
適用于自然語言處理、時間序列分析等需要考慮時間信息的任務
長短時記憶層(LSTM Layer)和門控循環單元層(GRU Layer):
-
特殊類型的循環層,具有記憶單元和門控機制,可更好地處理長序列依賴性
-
LSTM 通過遺忘門、輸入門和輸出門控制信息流動,能夠長期保存重要信息
-
GRU 是 LSTM 的簡化版本,合并了遺忘門和輸入門,結構更簡單
-
適用于文本生成、機器翻譯、語音識別等任務
轉置卷積層(Transpose Convolution Layer/Deconvolution Layer):
-
用于將特征圖的尺寸擴大,通常用于圖像分割、圖像生成和超分辨率任務
-
在生成對抗網絡(GAN)和語義分割網絡中廣泛應用
規范化層(Normalization Layer):
- 用于規范神經元的輸出,包括批量歸一化(Batch Normalization)和層歸一化(Layer Normalization)等
- 有助于提高訓練穩定性,加速收斂,并減少梯度消失問題
- 廣泛用于深度神經網絡中
注意力層(Attention Layer):
-
計算輸入序列中各元素之間的注意力權重,使模型能夠關注輸入的不同部分
-
是 Transformer 架構的核心組件,分為自注意力(Self-Attention)和交叉注意力(Cross-Attention)
-
有助于模型捕捉長距離依賴關系,提高對關鍵信息的關注能力
多頭注意力層(Multi-Head Attention Layer):
-
并行運行多個注意力頭,每個頭捕捉數據中不同的關聯模式
-
突破單維注意力限制,使模型在處理數據時能基于不同語義維度施加差異化關注
-
增強了模型的表達能力和理解能力
位置前饋網絡(Position-wise Feed-Forward Network):
-
由兩個線性變換層及 ReLU 激活函數組成,獨立作用于序列各位置
-
精煉各位置的編碼表征,提高模型的非線性表達能力
損失層(Loss Layer):
-
用于計算神經網絡的損失函數,衡量模型的性能并用于反向傳播
-
在訓練神經網絡時,損失層用于監督學習任務,如分類、回歸和生成任務
二、使用 Keras 快速搭建神經網絡
2.1 Keras 簡介與環境設置
Keras 是一個高級神經網絡 API,由 Python 語言編寫,最初由 Fran?ois Chollet 開發。它的設計理念是 “為人類設計的深度學習 API”,旨在提供一種簡潔、直觀且高效的方式來構建和訓練神經網絡模型。
Keras 具有以下核心優勢:
- 簡潔的 API: Keras 的 API 設計簡潔直觀,大大降低了深度學習的入門門檻,使得用戶可以快速實現想法。
- 模塊化設計: 模型由各種可配置的模塊(層)組成,用戶可以像搭積木一樣輕松構建復雜的神經網絡。
- 多后端支持: Keras 3.0 版本支持 TensorFlow、PyTorch 和 JAX 三種不同的深度學習框架作為后端,用戶可以根據需求選擇最適合的框架。
- 跨平臺兼容性: 模型可以在 CPU、GPU、移動端和嵌入式設備上運行,具有良好的跨平臺性能。
- 豐富的文檔和社區支持: Keras 擁有完善的官方文檔和活躍的社區,用戶可以輕松獲取幫助和資源。
在開始使用 Keras 之前,需要先安裝必要的軟件包。推薦的安裝方式是使用 pip 包管理器:
pip install tensorflow==2.13.0 # 選擇穩定版本
2.2 使用 Keras 構建簡單神經網絡
Keras 提供了兩種主要的模型構建方式:Sequential API和Functional API。以下將分別介紹這兩種方法。
Sequential API:線性堆疊模型
Sequential API 是構建簡單線性堆疊模型的首選方式,適用于大多數前饋神經網絡結構。
步驟 1:導入必要的庫
from tensorflow.keras import models, layers
步驟 2:創建 Sequential 模型
model = models.Sequential(name="我的第一個神經網絡")
步驟 3:添加網絡層
# 添加輸入層和第一個隱藏層
model.add(layers.Dense(64, activation='relu', input_shape=(28, 28)))# 添加第二個隱藏層
model.add(layers.Dense(32, activation='relu'))# 添加輸出層(假設是一個10類分類任務)
model.add(layers.Dense(10, activation='softmax'))
步驟 4:編譯模型
在訓練模型之前,需要指定優化器、損失函數和評估指標:
model.compile(optimizer='adam',#指定優化器loss='sparse_categorical_crossentropy',#損失函數metrics=['accuracy']#評估指標
)
步驟 5:訓練模型
history = model.fit(x_train, y_train,#輸入數據,目標值epochs=10,#訓練集被遍歷的次數batch_size=32,#每次模型更新所使用的樣本數量validation_split=0.2#劃分出 20% 的數據作為驗證集
)
步驟 6:評估模型
test_loss, test_accuracy = model.evaluate(x_test, y_test)
print(f"測試損失: {test_loss:.4f}")
print(f"測試準確率: {test_accuracy:.4f}")
步驟 7:使用模型進行預測
predictions = model.predict(x_test)
predicted_class = tf.argmax(predictions, axis=-1).numpy()
print("預測結果:", predicted_class)
Functional API:復雜網絡結構
當需要構建更復雜的網絡結構(如多輸入、多輸出、分支結構等)時,Functional API 提供了更大的靈活性。
步驟 1:定義輸入層
from tensorflow.keras import Input# 定義輸入層,假設輸入數據是28x28的圖像
input_layer = Input(shape=(28, 28), name="輸入層")
步驟 2:添加網絡層
# 第一個隱藏層
x = layers.Dense(64, activation='relu')(input_layer)# 第二個隱藏層
x = layers.Dense(32, activation='relu')(x)# 輸出層
output_layer = layers.Dense(10, activation='softmax', name="輸出層")(x)
步驟 3:創建模型
model = models.Model(inputs=input_layer, outputs=output_layer, name="我的復雜模型")
步驟 4:編譯、訓練和評估模型
編譯、訓練和評估步驟與 Sequential API 類似。
Functional API 的優勢在于可以創建更復雜的網絡結構,例如:
- 多輸入模型:
# 定義兩個輸入
input1 = Input(shape=(100,))
input2 = Input(shape=(200,))# 處理每個輸入
x1 = layers.Dense(64, activation='relu')(input1)
x2 = layers.Dense(32, activation='relu')(input2)# 合并兩個輸入的特征
merged = layers.concatenate([x1, x2])# 添加輸出層
output = layers.Dense(10, activation='softmax')(merged)# 創建模型
model = models.Model(inputs=[input1, input2], outputs=output)
- 多輸出模型:
# 定義輸入
input_layer = Input(shape=(28, 28))# 共享隱藏層
x = layers.Dense(64, activation='relu')(input_layer)
x = layers.Dense(32, activation='relu')(x)# 兩個不同的輸出層
output1 = layers.Dense(10, activation='softmax', name="分類輸出")(x)
output2 = layers.Dense(1, activation='sigmoid', name="回歸輸出")(x)# 創建模型
model = models.Model(inputs=input_layer, outputs=[output1, output2])
2.3 Keras 常用層詳解
Keras 提供了豐富的層類型,以下是一些最常用的層及其應用場景:
核心層
Dense 層: 全連接層,每個神經元與上一層的每個神經元相連,是最基礎的神經網絡層。常用于處理向量數據,如分類、回歸任務的隱藏層或輸出層。
# 創建一個具有64個神經元,使用ReLU激活函數的全連接層
dense_layer = layers.Dense(units=64, activation='relu')
Input 層: 定義模型的輸入,通常不需要顯式創建,而是通過Input()函數定義輸入形狀。
# 定義一個形狀為(28, 28)的輸入層
input_layer = Input(shape=(28, 28))
Flatten 層: 將多維輸入展平為一維,常用于從卷積層過渡到全連接層。
# 創建展平層
flatten_layer = layers.Flatten()
卷積層
Conv2D 層: 二維卷積層,主要用于處理圖像數據,通過卷積操作提取局部特征。
# 創建一個具有32個3x3卷積核的卷積層
conv_layer = layers.Conv2D(filters=32, kernel_size=(3, 3), activation='relu')
MaxPooling2D 層: 二維最大池化層,通過取窗口內的最大值來下采樣特征圖。
# 創建2x2的最大池化層
pool_layer = layers.MaxPooling2D(pool_size=(2, 2))
Conv1D 層: 一維卷積層,用于處理序列數據,如文本或時間序列。
Conv3D 層: 三維卷積層,用于處理體積數據,如醫學圖像或視頻。
循環層
LSTM 層: 長短期記憶網絡層,用于處理序列數據,能夠學習長期依賴關系。
# 創建一個具有128個單元的LSTM層
lstm_layer = layers.LSTM(units=128, return_sequences=True)
GRU 層: 門控循環單元層,是 LSTM 的簡化版本,結構更簡單但仍能有效捕捉序列中的長期依賴。
SimpleRNN 層: 簡單循環神經網絡層,適用于簡單的序列任務,但難以捕捉長距離依賴。
規范化和正則化層
BatchNormalization 層: 批量歸一化層,對前一層的輸出進行批量歸一化,加速訓練并提高模型穩定性。
# 創建批量歸一化層
bn_layer = layers.BatchNormalization()
Dropout 層: 隨機失活層,訓練過程中隨機將部分神經元輸出設為 0,防止過擬合。
# 創建一個丟棄率為0.5的Dropout層
dropout_layer = layers.Dropout(rate=0.5)
LSTM 層: 長短期記憶網絡層,用于處理序列數據,能夠學習長期依賴關系。
特殊用途層
Embedding 層: 嵌入層,將正整數(索引)轉換為固定大小的密集向量,常用于自然語言處理任務。
# 創建嵌入層,詞匯表大小為1000,輸出維度為64
embedding_layer = layers.Embedding(input_dim=1000, output_dim=64)
GlobalAveragePooling2D 層: 全局平均池化層,對特征圖的每個通道取平均值,將空間維度壓縮為 1,常用于替代 Flatten 層。
Concatenate 層: 拼接層,將多個張量在某個維度上拼接,用于合并不同分支的特征。
Lambda 層: 自定義層,允許用戶定義任意可微分的操作作為一個層,增加了模型的靈活性。
2.4 模型編譯與訓練技巧
在 Keras 中,模型的編譯和訓練是模型開發過程中的關鍵步驟。以下詳細介紹相關參數和技巧:
編譯模型
在編譯模型時,需要指定優化器、損失函數和評估指標:
model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy']
)
優化器選擇:
- Adam: 默認的優化器選擇,適用于大多數情況,具有自適應學習率的特點。
- SGD: 隨機梯度下降,需要手動調整學習率和動量參數,適用于大規模數據集和復雜模型。
- RMSprop: 均方根傳播,適用于循環神經網絡和某些類型的卷積神經網絡。
- Adagrad和Adadelta: 自適應學習率優化器,適用于數據稀疏的情況。
損失函數選擇:
- 分類任務: 使用交叉熵損失,如sparse_categorical_crossentropy(適用于整數標簽)或categorical_crossentropy(適用于獨熱編碼標簽)。
- 二分類任務: 使用binary_crossentropy。
- 回歸任務: 使用均方誤差(MSE)或平均絕對誤差(MAE)。
評估指標:
- 分類任務: 常用accuracy作為評估指標。
- 回歸任務: 常用mae(平均絕對誤差)或mse(均方誤差)。
- 多標簽分類: 可以使用precision、recall和AUC等指標。
訓練模型
訓練模型的主要函數是model.fit(),其關鍵參數包括:
history = model.fit(x_train, y_train,epochs=10,batch_size=32,validation_split=0.2,callbacks=[...],verbose=1
)
訓練數據參數:
x_train: 輸入數據,可以是 NumPy 數組、TensorFlow 數據集或其他兼容格式。
y_train: 目標數據,與輸入數據對應。
batch_size: 每次迭代使用的樣本數量。較大的 batch_size 可能會加快訓練速度,但會消耗更多內存;較小的 batch_size 可能會導致訓練不穩定,但能更有效地利用內存。
訓練配置參數:
epochs: 訓練的輪數,即整個數據集被訓練的次數。需要注意的是,過多的訓練輪數可能導致過擬合。
validation_split: 從訓練數據中劃分出的驗證集比例(0 到 1 之間的浮點數)。
validation_data: 顯式指定驗證數據(x_val, y_val),如果指定了該參數,validation_split將被忽略。
回調函數(Callbacks):
回調函數是在訓練過程中執行的一系列操作,可以用于監控訓練過程、提前終止訓練、保存模型等。常用的回調函數包括:
EarlyStopping: 當驗證損失在指定的輪數內不再改善時,自動停止訓練,防止過擬合。
tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=3)
ModelCheckpoint: 在訓練過程中保存模型,通常保存驗證損失最低的模型。
tf.keras.callbacks.ModelCheckpoint('best_model.h5', save_best_only=True)
TensorBoard: 用于可視化訓練過程中的各種指標和模型結構。
tf.keras.callbacks.TensorBoard(log_dir='./logs')
LearningRateScheduler: 動態調整學習率,根據訓練進度自動調整學習率大小。
tf.keras.callbacks.LearningRateScheduler(schedule)
ReduceLROnPlateau: 當驗證損失停止改善時,自動降低學習率。
tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=3)
訓練技巧:
- 數據預處理: 對輸入數據進行標準化或歸一化處理,有助于加速訓練過程并提高模型性能。對于圖像數據,通常將像素值縮放到 [0, 1] 區間;對于數值特征,通常進行標準化處理。
- 過擬合處理:
- 添加 Dropout 層,隨機失活部分神經元。
- 使用 L1 或 L2 正則化,約束模型參數的大小。
- 增加訓練數據量或使用數據增強技術(針對圖像數據)。
- 提前終止訓練(EarlyStopping)。
- 學習率調整: 使用自適應學習率優化器(如 Adam)或動態調整學習率的回調函數,有助于找到更優的參數空間。
- 批量歸一化: 在網絡中添加 BatchNormalization 層,有助于加速訓練并提高模型的泛化能力。
- 使用預訓練模型: 在大規模數據集上預訓練的模型可以作為當前任務的起點,特別是在數據有限的情況下,遷移學習可以顯著提高模型性能。
三、神經網絡應用實戰
3.1 圖像識別實戰:MNIST 數字識別
MNIST 是一個經典的圖像識別數據集,包含手寫數字 0-9 的灰度圖像,常用于圖像識別任務的入門示例。以下是使用 Keras 實現 MNIST 數字識別的完整步驟。
步驟 1:導入必要的庫
import tensorflow as tf
from tensorflow.keras import layers, models
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
import matplotlib.pyplot as plt
步驟 2:加載和預處理數據
# 加載MNIST數據集
(x_train, y_train), (x_test, y_test) = mnist.load_data()# 數據預處理
x_train = x_train.reshape(-1, 28, 28, 1).astype('float32') / 255.0 # 歸一化并增加通道維度
x_test = x_test.reshape(-1, 28, 28, 1).astype('float32') / 255.0# 轉換標簽為獨熱編碼
y_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)
步驟 3:構建 CNN 模型
使用卷積神經網絡(CNN)構建 MNIST 識別模型:
model = models.Sequential([layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),layers.MaxPooling2D((2, 2)),layers.Conv2D(64, (3, 3), activation='relu'),layers.MaxPooling2D((2, 2)),layers.Conv2D(64, (3, 3), activation='relu'),layers.Flatten(),layers.Dense(64, activation='relu'),layers.Dense(10, activation='softmax')
])
其結構如下
輸入層 (28, 28, 1) → 卷積層1:32個(3,3)卷積核,ReLU激活↓池化層1:(2,2)最大池化 → 卷積層2:64個(3,3)卷積核,ReLU激活↓池化層2:(2,2)最大池化 → 卷積層3:64個(3,3)卷積核,ReLU激活↓扁平化(Flatten) → 全連接層1:64個神經元,ReLU激活↓輸出層:10個神經元,softmax激活(對應10類分類)
步驟 4:編譯模型
model.compile(optimizer='adam',loss='categorical_crossentropy',metrics=['accuracy']
)
步驟 5:訓練模型
history = model.fit(x_train, y_train,epochs=5,batch_size=64,validation_split=0.2
)
步驟 6:評估模型
test_loss, test_acc = model.evaluate(x_test, y_test)
print(f"測試損失: {test_loss:.4f}")
print(f"測試準確率: {test_acc:.4f}")
步驟 7:可視化結果
# 顯示訓練過程中的損失和準確率變化
plt.plot(history.history['loss'], label='訓練損失')
plt.plot(history.history['val_loss'], label='驗證損失')
plt.title('訓練和驗證損失')
plt.xlabel('輪數')
plt.ylabel('損失')
plt.legend()
plt.show()plt.plot(history.history['accuracy'], label='訓練準確率')
plt.plot(history.history['val_accuracy'], label='驗證準確率')
plt.title('訓練和驗證準確率')
plt.xlabel('輪數')
plt.ylabel('準確率')
plt.legend()
plt.show()# 顯示部分測試圖像及其預測結果
predictions = model.predict(x_test[:10])
for i in range(10):plt.subplot(2, 5, i+1)plt.imshow(x_test[i].reshape(28, 28), cmap='gray')plt.title(f"預測: {tf.argmax(predictions[i])}")plt.axis('off')
plt.show()
在 MNIST 數據集上,一個設計良好的 CNN 模型通常可以達到 99% 以上的測試準確率,顯著優于傳統的機器學習方法。
3.2 自然語言處理實戰:IMDb 影評分類
IMDb 影評分類是一個經典的文本分類任務,需要將影評分為正面和負面兩類。以下是使用 Keras 實現 IMDb 影評分類的完整步驟。
步驟 1:導入必要的庫
import tensorflow as tf
from tensorflow.keras import layers, models
from tensorflow.keras.datasets import imdb
from tensorflow.keras.preprocessing.sequence import pad_sequences
步驟 2:加載和預處理數據
# 加載IMDb數據集,只保留最常見的10000個單詞
vocab_size = 10000
max_len = 500 # 每個影評最多保留500個單詞
(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=vocab_size)# 對序列進行填充,使所有序列長度一致
x_train = pad_sequences(x_train, maxlen=max_len)
x_test = pad_sequences(x_test, maxlen=max_len)
步驟 3:構建 LSTM 模型
使用循環神經網絡(LSTM)構建影評分類模型:
model = models.Sequential([layers.Embedding(vocab_size, 128),layers.LSTM(64, dropout=0.2, recurrent_dropout=0.2),layers.Dense(64, activation='relu'),layers.Dropout(0.5),layers.Dense(1, activation='sigmoid')
])
其結構如下
輸入數據(文本序列)↓
【Embedding 層】
- 輸入維度:vocab_size(詞匯表大小)
- 輸出維度:128(詞向量維度)↓
【LSTM 層】
- 隱藏單元數:64
- dropout:0.2(輸入 dropout)
- recurrent_dropout:0.2(循環狀態 dropout)↓
【Dense 層】
- 神經元數:64
- 激活函數:relu↓
【Dropout 層】
- 丟棄率:0.5↓
【輸出 Dense 層】
- 神經元數:1
- 激活函數:sigmoid(用于二分類輸出,輸出值在 0-1 之間)↓
輸出結果(二分類概率)
步驟 4:編譯模型
model.compile(optimizer='adam',loss='binary_crossentropy',metrics=['accuracy']
)
步驟 5:訓練模型
history = model.fit(x_train, y_train,epochs=5,batch_size=64,validation_split=0.2
)
步驟 6:評估模型
test_loss, test_acc = model.evaluate(x_test, y_test)
print(f"測試損失: {test_loss:.4f}")
print(f"測試準確率: {test_acc:.4f}")
步驟 7:可視化結果
# 顯示訓練過程中的損失和準確率變化
plt.plot(history.history['loss'], label='訓練損失')
plt.plot(history.history['val_loss'], label='驗證損失')
plt.title('訓練和驗證損失')
plt.xlabel('輪數')
plt.ylabel('損失')
plt.legend()
plt.show()plt.plot(history.history['accuracy'], label='訓練準確率')
plt.plot(history.history['val_accuracy'], label='驗證準確率')
plt.title('訓練和驗證準確率')
plt.xlabel('輪數')
plt.ylabel('準確率')
plt.legend()
plt.show()
在 IMDb 影評分類任務中,使用 LSTM 網絡通常可以達到 85% 以上的測試準確率。如果使用更復雜的模型(如 Transformer)或進行更精細的超參數調優,性能還可以進一步提高。
3.3 時間序列預測實戰:股票價格預測
時間序列預測是另一個重要的應用領域,以下以股票價格預測為例,展示如何使用 Keras 構建時間序列預測模型。
步驟 1:導入必要的庫
import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow.keras import layers, models
from sklearn.preprocessing import MinMaxScaler
步驟 2:加載和預處理數據
# 加載股票數據(假設數據保存在CSV文件中,包含'date'和'close'列)
df = pd.read_csv('stock_data.csv', parse_dates=['date'], index_col='date')
data = df[['close']].values# 數據歸一化
scaler = MinMaxScaler(feature_range=(0, 1))
data_scaled = scaler.fit_transform(data)# 創建時間序列數據集
def create_dataset(data, lookback=60):X, Y = [], []for i in range(lookback, len(data)):X.append(data[i-lookback:i, 0])Y.append(data[i, 0])return np.array(X), np.array(Y)lookback = 60 # 使用過去60天的數據預測下一天的價格
X, Y = create_dataset(data_scaled, lookback)# 劃分訓練集和測試集
train_size = int(len(X) * 0.8)
X_train, X_test = X[:train_size], X[train_size:]
Y_train, Y_test = Y[:train_size], Y[train_size:]# 調整輸入形狀以適應LSTM層的要求(樣本數,時間步數,特征數)
X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], 1))
X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))
步驟 3:構建 LSTM 模型
model = models.Sequential([layers.LSTM(50, activation='relu', input_shape=(lookback, 1)),layers.Dense(1)
])
步驟 4:編譯模型
model.compile(optimizer='adam',loss='mean_squared_error'
)
步驟 5:訓練模型
history = model.fit(X_train, Y_train,epochs=20,batch_size=32,validation_split=0.2
)
步驟 6:評估模型
test_loss = model.evaluate(X_test, Y_test)
print(f"測試損失(MSE): {test_loss:.4f}")
步驟 7:進行預測
# 預測測試集
predictions = model.predict(X_test)# 反歸一化預測結果
predictions = scaler.inverse_transform(predictions)
Y_test_actual = scaler.inverse_transform([Y_test])# 計算均方根誤差(RMSE)
rmse = np.sqrt(np.mean((predictions - Y_test_actual)**2))
print(f"RMSE: {rmse:.4f}")
步驟 8:可視化結果
# 繪制實際值和預測值的對比
plt.figure(figsize=(10, 6))
plt.plot(Y_test_actual[0], label='實際價格')
plt.plot(predictions, label='預測價格')
plt.title('股票價格預測')
plt.xlabel('時間')
plt.ylabel('價格')
plt.legend()
plt.show()
時間序列預測是一個具有挑戰性的任務,股票價格預測尤其困難,因為市場受到多種因素的影響。上述模型只是一個簡單的示例,可以通過增加模型復雜度、調整超參數或添加更多特征來提高預測性能。
3.4 高級應用:使用預訓練模型進行遷移學習
遷移學習是深度學習中一種強大的技術,它允許我們使用在大規模數據集上預訓練好的模型作為起點,然后針對特定任務進行微調。以下以圖像分類為例,展示如何使用 Keras 中的預訓練模型進行遷移學習。
步驟 1:導入必要的庫
import tensorflow as tf
from tensorflow.keras import layers, models
from tensorflow.keras.applications import ResNet50
from tensorflow.keras.preprocessing import image
from tensorflow.keras.applications.resnet50 import preprocess_input, decode_predictions
import numpy as np
步驟 2:加載預訓練模型
# 加載預訓練的ResNet50模型,不包含頂層的全連接層
base_model = ResNet50(weights='imagenet',include_top=False,input_shape=(224, 224, 3)
)# 凍結基礎模型的參數,使其在訓練過程中不被更新
base_model.trainable = False
步驟 3:添加自定義分類頭
# 在基礎模型上添加自定義的分類頭
model = models.Sequential([base_model,layers.GlobalAveragePooling2D(),layers.Dense(256, activation='relu'),layers.Dropout(0.5),layers.Dense(10, activation='softmax') # 假設是10類分類任務
])
步驟 4:編譯模型
model.compile(optimizer='adam',loss='categorical_crossentropy',metrics=['accuracy']
)
步驟 5:準備數據
假設我們有一個自定義的圖像數據集,需要將其預處理為模型所需的格式:
# 假設數據集已經按照類別組織在不同的文件夾中
# 使用ImageDataGenerator進行數據增強和預處理
from tensorflow.keras.preprocessing.image import ImageDataGeneratortrain_datagen = ImageDataGenerator(preprocessing_function=preprocess_input,rotation_range=20,width_shift_range=0.2,height_shift_range=0.2,shear_range=0.2,zoom_range=0.2,horizontal_flip=True
)val_datagen = ImageDataGenerator(preprocessing_function=preprocess_input)train_generator = train_datagen.flow_from_directory('train_dir',target_size=(224, 224),batch_size=32,class_mode='categorical'
)val_generator = val_datagen.flow_from_directory('val_dir',target_size=(224, 224),batch_size=32,class_mode='categorical'
)
步驟 6:訓練模型
history = model.fit(train_generator,epochs=10,validation_data=val_generator
)
步驟 7:評估模型
test_generator = val_datagen.flow_from_directory('test_dir',target_size=(224, 224),batch_size=32,class_mode='categorical',shuffle=False
)test_loss, test_acc = model.evaluate(test_generator)
print(f"測試損失: {test_loss:.4f}")
print(f"測試準確率: {test_acc:.4f}")
步驟 8:微調模型(可選)
在初步訓練完成后,可以選擇解凍部分基礎模型的層進行微調,以進一步提高性能:
# 解凍基礎模型的頂層
base_model.trainable = True
fine_tune_at = 100 # 從第100層開始解凍for layer in base_model.layers[:fine_tune_at]:layer.trainable = False# 重新編譯模型,使用較低的學習率
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=1e-5),loss='categorical_crossentropy',metrics=['accuracy']
)# 繼續訓練模型
history_fine = model.fit(train_generator,epochs=20,initial_epoch=history.epoch[-1],validation_data=val_generator
)
通過遷移學習,可以在較小的數據集上取得比從頭訓練更好的性能,特別是在數據有限的情況下。Keras 提供了多種預訓練模型,包括 ResNet、VGG、Inception 等,可以根據任務需求選擇合適的模型。
四、小結
神經網絡作為深度學習的核心技術,已經在圖像識別、自然語言處理、語音識別等多個領域取得了突破性進展。從簡單的感知機到復雜的 Transformer 網絡,神經網絡的發展歷程展示了人類對智能系統的不懈探索。
Keras 作為一個簡潔、高效的深度學習 API,大大降低了神經網絡開發的門檻,使得更多人能夠參與到 AI 技術的研究和應用中。通過 Keras,工程師可以快速構建和訓練各種類型的神經網絡模型,實現從研究到生產的快速迭代。
學習神經網絡是一個持續的過程,需要我們堅定不移的持續努力向前推進。