卷積神經網絡 (Convolutional Neural Network, CNN) 是一種專門用於處理結構化網格數據(如圖像、聲音)的深度學習模型。與傳統的多層感知器 (MLP) 不同,CNN 通過卷積層來提取數據的局部特徵,從而提高模型的效率和準確性,特別適合於圖像分類、物體檢測和語音識別等任務。
CNN 主要由三種核心層組成:卷積層 (Convolutional Layer)、池化層 (Pooling Layer) 和 全連接層 (Fully Connected Layer)。
卷積操作:卷積層的核心是卷積操作,它通過滑動小的濾波器 (filter) 或 卷積核 (kernel) 在輸入數據上進行點積運算,提取局部特徵。每個濾波器能夠檢測不同的模式或特徵,如邊緣、角點等。
輸出特徵圖 (Feature Map):卷積操作後生成的結果稱為特徵圖,它保留了數據中重要的局部模式信息。
激活函數 (Activation Function):通常在卷積操作後應用非線性激活函數(如 ReLU)來增加模型的表達能力。
池化操作:池化層用來減少特徵圖的尺寸,從而降低計算量並增強模型的抗干擾能力。最常用的池化方式是最大池化 (Max Pooling) 和 平均池化 (Average Pooling)。
下采樣:池化層通過選擇局部區域內的最大值或平均值來對特徵圖進行下采樣,保留最重要的特徵,同時減少數據維度。
扁平化:在卷積和池化操作後,特徵圖被展平為一維向量,並傳遞到全連接層。
分類/迴歸:全連接層中的神經元與前一層的所有神經元相連,並生成最終的輸出(如分類概率)。
輸入圖像:輸入層接收原始圖像數據,如一個 RGB 圖像。
卷積層:多個卷積層提取圖像中的不同層次特徵(從邊緣到更高階的物體部分)。
池化層:通過池化層逐步降低特徵圖的空間維度,同時保留重要的特徵。
全連接層:扁平化特徵圖並通過全連接層,進行分類或迴歸。
輸出層:根據任務需求,輸出最終的結果(如圖像的分類標籤)。
CNN 在計算機視覺領域非常流行,常見的應用包括:
pip install tensorflow
import tensorflow as tf
from tensorflow.keras import layers, models
import matplotlib.pyplot as plt
# 載入 CIFAR-10 數據集
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()
# 資料預處理:正規化像素值到 [0, 1] 區間
x_train, x_test = x_train / 255.0, x_test / 255.0
# 定義 CNN 模型
model = models.Sequential([
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)), # 卷積層 1
layers.MaxPooling2D((2, 2)), # 池化層 1
layers.Conv2D(64, (3, 3), activation='relu'), # 卷積層 2
layers.MaxPooling2D((2, 2)), # 池化層 2
layers.Conv2D(64, (3, 3), activation='relu'), # 卷積層 3
layers.Flatten(), # 扁平化
layers.Dense(64, activation='relu'), # 全連接層
layers.Dense(10, activation='softmax') # 輸出層
])
# 編譯模型
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# 訓練模型
history = model.fit(x_train, y_train, epochs=10,
validation_data=(x_test, y_test))
# 評估模型
test_loss, test_acc = model.evaluate(x_test, y_test, verbose=2)
print(f'\n測試集準確率: {test_acc:.4f}')
# 繪製訓練過程中的準確率和損失
plt.figure(figsize=(12, 4))
# 準確率
plt.subplot(1, 2, 1)
plt.plot(history.history['accuracy'], label='訓練準確率')
plt.plot(history.history['val_accuracy'], label='驗證準確率')
plt.title('訓練和驗證準確率')
plt.xlabel('Epoch')
plt.ylabel('準確率')
plt.legend()
# 損失
plt.subplot(1, 2, 2)
plt.plot(history.history['loss'], label='訓練損失')
plt.plot(history.history['val_loss'], label='驗證損失')
plt.title('訓練和驗證損失')
plt.xlabel('Epoch')
plt.ylabel('損失')
plt.legend()
plt.show()
# 預測示例
import numpy as np
# 從測試集中選取前5張圖片
samples = x_test[:5]
labels = y_test[:5]
predictions = model.predict(samples)
# 繪製預測結果
class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']
for i in range(5):
plt.imshow(samples[i])
plt.title(f'真實標籤: {class_names[labels[i][0]]}, 預測: {class_names[np.argmax(predictions[i])]}')
plt.axis('off')
plt.show()