深度學習模型的訓練和評估是模型開發的關鍵步驟。本文以多層感知器(MLP)為例,示範如何使用 TensorFlow 和 Keras 建立、訓練和評估模型,並探討不同超引數對模型效能的影響。首先,我們使用 one-hot 編碼處理類別標籤,並使用交叉熵損失函式和 Adam 最佳化器編譯模型。接著,我們使用訓練資料集訓練模型,並使用驗證資料集監控模型的泛化能力。訓練完成後,我們使用測試資料集評估模型的效能,並計算準確率、精確率、召回率和混淆矩陣等指標。為了進一步提升模型效能,我們調整了模型的層數、批次大小和隱藏層神經元數量等超引數,並分析了這些引數對模型效能的影響。實驗結果顯示,適當調整這些超引數可以有效提升模型的效能,但過度調整可能導致過擬合或欠擬合。
模型訓練與評估
在前一步驟中,我們已經成功建立了一個多層感知器(MLP)模型,接下來將進行模型的訓練與評估。
模型訓練
首先,我們需要定義一個函式來訓練模型:
from tensorflow.keras.utils import to_categorical
def train_model(model, x_train, y_train, x_val, y_val, batch_size=32, epochs=10):
# 將類別向量轉換為二元類別矩陣(one-hot 編碼)
y_train = to_categorical(y_train)
y_val = to_categorical(y_val)
# 編譯模型,使用交叉熵損失函式和 Adam 最佳化器
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
# 訓練模型
history = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, validation_data=(x_val, y_val))
return history
# 訓練模型
history = train_model(model, x_train, y_train, x_val, y_val, batch_size=32, epochs=10)
內容解密:
- 匯入必要的模組:從 TensorFlow.keras 中匯入
to_categorical函式,用於將類別標籤進行 one-hot 編碼。 - 定義訓練函式:
train_model函式負責模型的訓練過程,包含編譯模型和訓練模型的步驟。 - one-hot 編碼:將類別標籤轉換為二元類別矩陣,這是因為模型的輸出層使用了 softmax 啟用函式,需要與 one-hot 編碼的標籤進行比較。
- 編譯模型:使用交叉熵損失函式和 Adam 最佳化器,交叉熵損失函式適合於多類別分類別問題,而 Adam 最佳化器是一種常見且有效的最佳化演算法。
- 訓練模型:使用
fit方法訓練模型,指定批次大小和訓練輪數,並使用驗證資料集進行驗證。
模型評估
在訓練完成後,我們需要對模型進行評估,以瞭解其在測試資料集上的表現:
import matplotlib.pyplot as plt
from sklearn.metrics import accuracy_score, precision_score, recall_score, confusion_matrix
def evaluate_model(model, x_test, y_test):
# 對測試資料進行預測
y_pred = model.predict(x_test)
# 將預測結果轉換為類別標籤
y_pred_classes = np.argmax(y_pred, axis=1)
# 將真實標籤轉換為類別標籤(注意:y_test 需要先進行 one-hot 編碼)
y_test = to_categorical(y_test)
y_true_classes = np.argmax(y_test, axis=1)
# 計算準確率、精確率、召回率和混淆矩陣
accuracy = accuracy_score(y_true_classes, y_pred_classes)
precision = precision_score(y_true_classes, y_pred_classes, average='weighted')
recall = recall_score(y_true_classes, y_pred_classes, average='weighted')
cm = confusion_matrix(y_true_classes, y_pred_classes)
return accuracy, precision, recall, cm
# 評估模型
y_test = to_categorical(y_test) # 先將y_test進行one-hot編碼
accuracy, precision, recall, cm = evaluate_model(model, x_test, y_test)
# 輸出評估指標
print("準確率:", accuracy)
print("精確率:", precision)
print("召回率:", recall)
print("混淆矩陣:\n", cm)
# 視覺化混淆矩陣
plt.imshow(cm, cmap=plt.cm.Blues)
plt.title('混淆矩陣')
plt.colorbar()
plt.xlabel('預測標籤')
plt.ylabel('真實標籤')
plt.show()
內容解密:
- 匯入必要的模組:匯入
matplotlib.pyplot用於視覺化混淆矩陣,以及sklearn.metrics中的評估指標函式。 - 定義評估函式:
evaluate_model函式用於評估模型的效能,包括預測、計算評估指標和傳回結果。 - 預測和轉換標籤:使用模型對測試資料進行預測,並將預測結果和真實標籤轉換為類別標籤。
- 計算評估指標:計算準確率、精確率、召回率和混淆矩陣,這些指標能夠全面評估模型的效能。
- 輸出和視覺化結果:輸出評估指標,並使用
matplotlib視覺化混淆矩陣,以便直觀瞭解模型的預測情況。
疑難排解
在執行模型評估程式碼時,出現了一個錯誤,錯誤資訊表明 y_test 的維度不正確。經過檢查,發現是因為 y_test 沒有進行 one-hot 編碼。解決方法是在呼叫 evaluate_model 之前,先對 y_test 進行 one-hot 編碼。
y_test = to_categorical(y_test)
這樣就能夠正確地計算評估指標和混淆矩陣。
此圖示說明瞭模型的訓練流程和評估指標的計算方法。
建構Fashion-MNIST的MLP模型與ChatGPT的協作流程
驗證測試標籤的形狀
首先,我們需要檢查測試標籤(y_test)的形狀,以確保它們符合評估函式的要求:
print("y_test的形狀:", y_test.shape)
這段程式碼幫助我們瞭解標籤的形狀並找出可能的差異。
內容解密:
y_test.shape傳回測試標籤的形狀,這是一個元組,表示標籤陣列的維度。- 檢查標籤形狀有助於我們確認資料是否正確載入,並為後續的模型評估做好準備。
輸出結果與修正評估函式
假設輸出結果為 (9000,),這意味著標籤是一維格式,未進行獨熱編碼。我們需要修改評估函式以適應一維標籤:
# Step 8: 模型評估
def evaluate_model(model, x_test, y_test):
# 預測測試資料的標籤
y_pred = model.predict(x_test)
# 將預測標籤轉換為類別標籤
y_pred_classes = np.argmax(y_pred, axis=1)
# 計算準確率
accuracy = accuracy_score(y_test, y_pred_classes)
# 計算精確率
precision = precision_score(y_test, y_pred_classes, average='weighted')
# 計算召回率
recall = recall_score(y_test, y_pred_classes, average='weighted')
# 計算混淆矩陣
cm = confusion_matrix(y_test, y_pred_classes)
return accuracy, precision, recall, cm
# 評估模型
accuracy, precision, recall, cm = evaluate_model(model, x_test, y_test)
# 列印評估指標
print("準確率:", accuracy)
print("精確率:", precision)
print("召回率:", recall)
print("混淆矩陣:\n", cm)
# 視覺化混淆矩陣
plt.imshow(cm, cmap=plt.cm.Blues)
plt.title('混淆矩陣')
plt.colorbar()
plt.xlabel('預測標籤')
plt.ylabel('真實標籤')
plt.show()
內容解密:
- 我們移除了標籤到獨熱編碼的轉換,直接在評估函式中使用
y_test真實標籤。 - 更新了準確率、精確率和召回率的計算函式,以使用一維標籤。
- 現在,評估函式應該能夠正確處理提供的一維標籤,並準確計算評估指標。
新增層到模型中
現在我們已經有了一個基線模型架構,接下來嘗試新增層到模型中。我們將使用提示策略來改進模型,並請求ChatGPT提供相應的程式碼。
請求ChatGPT提供多層模型的程式碼
我們請求ChatGPT提供具有兩個隱藏層和三個隱藏層的模型的程式碼,並比較它們的效能。
ChatGPT的回應與程式碼實作
# 定義一個具有兩個隱藏層的MLP模型
def create_two_layer_mlp(input_shape, num_classes):
model = Sequential()
# 新增第一個隱藏層,使用ReLU啟用函式
model.add(Dense(128, activation='relu', input_shape=input_shape))
# 新增第二個隱藏層,使用ReLU啟用函式
model.add(Dense(64, activation='relu'))
# 新增輸出層,使用softmax啟用函式進行多類別分類別
model.add(Dense(num_classes, activation='softmax'))
return model
# 定義一個具有三個隱藏層的MLP模型
def create_three_layer_mlp(input_shape, num_classes):
model = Sequential()
# 新增第一個隱藏層,使用ReLU啟用函式
model.add(Dense(128, activation='relu', input_shape=input_shape))
# 新增第二個隱藏層,使用ReLU啟用函式
model.add(Dense(64, activation='relu'))
# 新增第三個隱藏層,使用ReLU啟用函式
model.add(Dense(32, activation='relu'))
# 新增輸出層,使用softmax啟用函式進行多類別分類別
model.add(Dense(num_classes, activation='softmax'))
return model
# 建立兩個隱藏層的MLP模型
two_layer_model = create_two_layer_mlp(input_shape, num_classes)
# 建立三個隱藏層的MLP模型
three_layer_model = create_three_layer_mlp(input_shape, num_classes)
# 訓練兩個隱藏層的MLP模型
two_layer_history = train_model(two_layer_model, x_train, y_train, x_val, y_val)
# 訓練三個隱藏層的MLP模型
three_layer_history = train_model(three_layer_model, x_train, y_train, x_val, y_val)
# 評估兩個隱藏層的MLP模型
two_layer_accuracy, _, _, _ = evaluate_model(two_layer_model, x_test, y_test)
# 評估三個隱藏層的MLP模型
three_layer_accuracy, _, _, _ = evaluate_model(three_layer_model, x_test, y_test)
# 列印模型比較結果
print("單層MLP準確率:", accuracy)
print("雙層MLP準確率:", two_layer_accuracy)
print("三層MLP準確率:", three_layer_accuracy)
內容解密:
- 我們定義了兩個額外的MLP模型,分別具有兩個和三個隱藏層,並使用之前定義的函式進行訓練和評估。
- 比較了不同層數模型的效能,包括準確率等指標。
此圖示顯示了單層、雙層和三層MLP模型的效能比較。
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title MLP模型訓練評估與效能調校
package "機器學習流程" {
package "資料處理" {
component [資料收集] as collect
component [資料清洗] as clean
component [特徵工程] as feature
}
package "模型訓練" {
component [模型選擇] as select
component [超參數調優] as tune
component [交叉驗證] as cv
}
package "評估部署" {
component [模型評估] as eval
component [模型部署] as deploy
component [監控維護] as monitor
}
}
collect --> clean : 原始資料
clean --> feature : 乾淨資料
feature --> select : 特徵向量
select --> tune : 基礎模型
tune --> cv : 最佳參數
cv --> eval : 訓練模型
eval --> deploy : 驗證模型
deploy --> monitor : 生產模型
note right of feature
特徵工程包含:
- 特徵選擇
- 特徵轉換
- 降維處理
end note
note right of eval
評估指標:
- 準確率/召回率
- F1 Score
- AUC-ROC
end note
@enduml
內容解密:
- 圖表清晰地展示了不同層數MLP模型的效能比較,有助於直觀理解模型的表現。
- 透過分析比較結果,我們可以得出關於模型架構對效能影響的結論。
實驗多層感知機模型的層數與效能分析
在深度學習中,多層感知機(MLP)是一種常見的模型架構。為了了解增加層數對模型效能的影響,我們進行了實驗,比較了不同層數的 MLP 模型的效能。
實驗設計
我們定義了三個不同的 MLP 模型,分別具有一層、兩層和三層隱藏層。模型的輸入形狀和輸出類別數保持一致,分別為 input_shape 和 num_classes。
模型定義與訓練
# 定義和訓練具有不同層數的模型
model_single_layer = create_single_layer_mlp(input_shape, num_classes)
history_single_layer = train_model(model_single_layer, x_train, y_train, x_val, y_val)
model_two_layers = create_two_layer_mlp(input_shape, num_classes)
history_two_layers = train_model(model_two_layers, x_train, y_train, x_val, y_val)
model_three_layers = create_three_layer_mlp(input_shape, num_classes)
history_three_layers = train_model(model_three_layers, x_train, y_train, x_val, y_val)
模型評估與比較
# 評估不同層數模型的效能
accuracy_single_layer, _, _, _ = evaluate_model(model_single_layer, x_test, y_test)
accuracy_two_layers, _, _, _ = evaluate_model(model_two_layers, x_test, y_test)
accuracy_three_layers, _, _, _ = evaluate_model(model_three_layers, x_test, y_test)
# 列印模型比較結果
print("單層MLP準確率:", accuracy_single_layer)
print("兩層MLP準確率:", accuracy_two_layers)
print("三層MLP準確率:", accuracy_three_layers)
內容解密:
- 模型定義:
create_single_layer_mlp、create_two_layer_mlp和create_three_layer_mlp分別用於建立具有不同層數的 MLP 模型。 - 模型訓練:
train_model函式用於訓練模型,輸入訓練資料、驗證資料和批次大小等引數。 - 模型評估:
evaluate_model函式用於評估模型的效能,輸出準確率等評估指標。 - 結果比較:透過比較不同層數模型的準確率,瞭解增加層數對模型效能的影響。
實驗結果與分析
實驗結果顯示,兩層 MLP 模型的準確率略高於單層和三層 MLP 模型。然而,不同層數模型之間的準確率差異相對較小,表明在這個案例中,增加層數並沒有顯著改善模型的效能。
調整批次大小的實驗
接下來,我們實驗了不同的批次大小對模型效能的影響。
程式碼範例
# 定義和訓練具有不同批次大小的模型
model_batch_32 = create_single_layer_mlp(input_shape, num_classes)
history_batch_32 = train_model(model_batch_32, x_train, y_train, x_val, y_val, batch_size=32)
model_batch_64 = create_single_layer_mlp(input_shape, num_classes)
history_batch_64 = train_model(model_batch_64, x_train, y_train, x_val, y_val, batch_size=64)
model_batch_128 = create_single_layer_mlp(input_shape, num_classes)
history_batch_128 = train_model(model_batch_128, x_train, y_train, x_val, y_val, batch_size=128)
# 評估不同批次大小模型的效能
accuracy_batch_32, _, _, _ = evaluate_model(model_batch_32, x_test, y_test)
accuracy_batch_64, _, _, _ = evaluate_model(model_batch_64, x_test, y_test)
accuracy_batch_128, _, _, _ = evaluate_model(model_batch_128, x_test, y_test)
# 列印模型比較結果
print("批次大小 = 32 的單層MLP準確率:", accuracy_batch_32)
print("批次大小 = 64 的單層MLP準確率:", accuracy_batch_64)
print("批次大小 = 128 的單層MLP準確率:", accuracy_batch_128)
內容解密:
- 批次大小的影響:實驗比較了不同批次大小(32、64 和 128)對單層 MLP 模型效能的影響。
- 模型訓練與評估:使用不同的批次大小訓練模型,並評估其在測試資料上的效能。
- 結果分析:結果顯示,不同批次大小下的模型準確率差異不大,表明在這個案例中,批次大小對模型效能的影響不顯著。
可能的原因分析
進一步分析顯示,可能的原因包括資料集的大小、模型的複雜度、最佳化演算法的選擇以及模型的收斂性等。
調整隱藏層神經元數量的實驗
最後,我們實驗了不同的隱藏層神經元數量對模型效能的影響。
程式碼範例與內容解密
相關程式碼和詳細解說將在後續章節中提供。