返回文章列表

MLP模型訓練評估與效能調校

本文探討如何使用 TensorFlow 和 Keras 訓練和評估多層感知器(MLP)模型,並深入研究調整層數、批次大小和神經元數量對模型效能的影響。文章提供程式碼範例,詳細說明如何使用 one-hot 編碼、交叉熵損失函式和 Adam

機器學習 深度學習

深度學習模型的訓練和評估是模型開發的關鍵步驟。本文以多層感知器(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)

內容解密:

  1. 匯入必要的模組:從 TensorFlow.keras 中匯入 to_categorical 函式,用於將類別標籤進行 one-hot 編碼。
  2. 定義訓練函式train_model 函式負責模型的訓練過程,包含編譯模型和訓練模型的步驟。
  3. one-hot 編碼:將類別標籤轉換為二元類別矩陣,這是因為模型的輸出層使用了 softmax 啟用函式,需要與 one-hot 編碼的標籤進行比較。
  4. 編譯模型:使用交叉熵損失函式和 Adam 最佳化器,交叉熵損失函式適合於多類別分類別問題,而 Adam 最佳化器是一種常見且有效的最佳化演算法。
  5. 訓練模型:使用 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()

內容解密:

  1. 匯入必要的模組:匯入 matplotlib.pyplot 用於視覺化混淆矩陣,以及 sklearn.metrics 中的評估指標函式。
  2. 定義評估函式evaluate_model 函式用於評估模型的效能,包括預測、計算評估指標和傳回結果。
  3. 預測和轉換標籤:使用模型對測試資料進行預測,並將預測結果和真實標籤轉換為類別標籤。
  4. 計算評估指標:計算準確率、精確率、召回率和混淆矩陣,這些指標能夠全面評估模型的效能。
  5. 輸出和視覺化結果:輸出評估指標,並使用 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_shapenum_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)

內容解密:

  1. 模型定義create_single_layer_mlpcreate_two_layer_mlpcreate_three_layer_mlp 分別用於建立具有不同層數的 MLP 模型。
  2. 模型訓練train_model 函式用於訓練模型,輸入訓練資料、驗證資料和批次大小等引數。
  3. 模型評估evaluate_model 函式用於評估模型的效能,輸出準確率等評估指標。
  4. 結果比較:透過比較不同層數模型的準確率,瞭解增加層數對模型效能的影響。

實驗結果與分析

實驗結果顯示,兩層 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)

內容解密:

  1. 批次大小的影響:實驗比較了不同批次大小(32、64 和 128)對單層 MLP 模型效能的影響。
  2. 模型訓練與評估:使用不同的批次大小訓練模型,並評估其在測試資料上的效能。
  3. 結果分析:結果顯示,不同批次大小下的模型準確率差異不大,表明在這個案例中,批次大小對模型效能的影響不顯著。

可能的原因分析

進一步分析顯示,可能的原因包括資料集的大小、模型的複雜度、最佳化演算法的選擇以及模型的收斂性等。

調整隱藏層神經元數量的實驗

最後,我們實驗了不同的隱藏層神經元數量對模型效能的影響。

程式碼範例與內容解密

相關程式碼和詳細解說將在後續章節中提供。