2024-05-26|閱讀時間 ‧ 約 28 分鐘

[深度學習][Python]多層感知器(MLP)模型使用不同激活函數(ReLU 和 Sigmoid)的效果

本文將展示使用不同激活函數(ReLU 和 Sigmoid)的效果。

一個簡單的多層感知器(MLP)模型來對 Fashion-MNIST 資料集進行分類。

relu vs sigmoid

函數定義

Sigmoid 函數

Sigmoid 函數將輸入壓縮到 0到 1 之間:

特性:

  • 輸出範圍是 (0,1)(0, 1)(0,1)。
  • 當 xxx 趨向無窮大時,輸出趨向於 1;當 xxx 趨向負無窮大時,輸出趨向於 0。

ReLU 函數

ReLU 函數只保留正數,將負數輸出為 0:

特性:

  • 輸出範圍是 [0,∞]。
  • 將所有負輸入值壓縮為 0,正輸入值保持不變。

2. 梯度特性

Sigmoid 函數

  • Sigmoid 函數的梯度在輸入值非常大或非常小時會趨近於 0,這會導致梯度消失問題(Gradient Vanishing Problem)。
  • 當激活值接近 0 或 1 時,導數值變得非常小,從而導致梯度傳遞到前幾層時變得幾乎為零,訓練變得非常緩慢。

ReLU 函數

  • ReLU 的梯度在正值範圍內為 1,在負值範圍內為 0。
  • ReLU 避免了梯度消失問題,因為在正值範圍內梯度不會變小。
  • 但是,ReLU 存在「神經元死亡」問題,即如果一個神經元的輸出總是負值,它的梯度將永遠是 0,該神經元將不再更新。

3. 計算效率

Sigmoid 函數

  • 計算 Sigmoid 涉及到指數運算,這在計算上相對比較昂貴。

ReLU 函數

  • ReLU 只需簡單的比較和取最大值運算,計算效率非常高。

4. 適用場景

Sigmoid 函數

  • 常用於輸出層,特別是在二元分類問題中。

ReLU 函數

  • 常用於隱藏層,在大多數現代神經網絡架構中是首選激活函數。

程式範例

import tensorflow as tf
from tensorflow.keras.datasets import fashion_mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten
import matplotlib.pyplot as plt

# 載入 Fashion-MNIST 資料集
(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()

# 標準化影像數據到 [0, 1] 範圍
x_train = x_train / 255.0
x_test = x_test / 255.0

# 定義模型架構
def create_model(activation):
model = Sequential([
Flatten(input_shape=(28, 28)),
Dense(128, activation=activation),
Dense(10, activation='softmax')
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
return model

# 創建兩個模型,一個使用 ReLU,另一個使用 Sigmoid
model_relu = create_model('relu')
model_sigmoid = create_model('sigmoid')

# 訓練模型
history_relu = model_relu.fit(x_train, y_train, epochs=5, validation_data=(x_test, y_test), verbose=2)
history_sigmoid = model_sigmoid.fit(x_train, y_train, epochs=5, validation_data=(x_test, y_test), verbose=2)

# 評估模型
test_loss_relu, test_acc_relu = model_relu.evaluate(x_test, y_test, verbose=2)
test_loss_sigmoid, test_acc_sigmoid = model_sigmoid.evaluate(x_test, y_test, verbose=2)

print(f"ReLU Model Test Accuracy: {test_acc_relu}")
print(f"Sigmoid Model Test Accuracy: {test_acc_sigmoid}")

# 繪製訓練過程中的準確度和損失
plt.figure(figsize=(12, 5))

plt.subplot(1, 2, 1)
plt.plot(history_relu.history['accuracy'], label='ReLU Train Accuracy')
plt.plot(history_relu.history['val_accuracy'], label='ReLU Val Accuracy')
plt.plot(history_sigmoid.history['accuracy'], label='Sigmoid Train Accuracy')
plt.plot(history_sigmoid.history['val_accuracy'], label='Sigmoid Val Accuracy')
plt.title('Model Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()

plt.subplot(1, 2, 2)
plt.plot(history_relu.history['loss'], label='ReLU Train Loss')
plt.plot(history_relu.history['val_loss'], label='ReLU Val Loss')
plt.plot(history_sigmoid.history['loss'], label='Sigmoid Train Loss')
plt.plot(history_sigmoid.history['val_loss'], label='Sigmoid Val Loss')
plt.title('Model Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()

plt.tight_layout()
plt.show()

繪製訓練過程

繪製訓練過程中的準確度和損失

準確率高


結果與比較

  • ReLU(Rectified Linear Unit):通常在深度學習中效果更好,因為它在正值範圍內有較好的梯度傳遞效果,能夠減少梯度消失問題。
  • Sigmoid:在多層神經網絡中可能會遇到梯度消失問題,使得訓練變慢且難以收斂。

透過這個程式範例,你可以觀察到使用不同激活函數的模型在準確度ReLU 0.875Sigmoid 0.872好一點,由繪製訓練過程上來看ReLU收斂速度比Sigmoid來的快收斂。通常來說,ReLU 會比 Sigmoid 表現更好一點。




分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.