iT邦幫忙

2025 iThome 鐵人賽

DAY 17
0
生成式 AI

《AI 新手到職場應用:深度學習 30 天實戰》系列 第 17

實戰專案:用 CIFAR-10 玩轉影像分類(簡易版)

  • 分享至 

  • xImage
  •  

在過去的幾天,我們一步步認識了神經網路的基本組件,
並且在第7天時透過 MNIST 的手寫數字辨識體驗了第一個深度學習實作。

而在今天,我們要更進一步挑戰更貼近現實世界的影像資料集 - CIFAR-10

這是一個常見於研究與教學的影像分類資料集,
它比 MNIST 更複雜,因為資料不是黑白的數字,而是彩色的真實物件。

我們將會用 Keras 建立一個簡單的卷積神經網路(CNN),體驗影像分類的第一步。


什麼是 CIFAR-10?

CIFAR-10 是由加拿大多倫多大學機器學習研究所(CIFAR)提供的一個公開影像資料集。
它包含了 60,000 張 32x32 彩色圖片,分為 10 個類別,每個類別有 6,000 張圖片。

這些類別包含了日常生活常見的東西,例如:飛機(airplane)、汽車(automobile)、
鳥(bird)、貓(cat)、鹿(deer)、狗(dog)等等 ,如下圖:

https://ithelp.ithome.com.tw/upload/images/20250925/20169196lWwTWzOlw4.jpg

相較於 MNIST 的手寫數字,CIFAR-10 的挑戰更高,
因為資料是彩色的(RGB 三通道),不像 MNIST 是單色灰階。
圖片內容相較文字更複雜,有背景、形狀差異,甚至角度也會有不同。

除此之外,辨識的對象從單純數字變成了生活中會見到的物體,
也是一個用膝蓋想也清楚的難度躍升。


實作流程

1. 載入資料

深度學習的第一步當然就是載入資料了,我們的程式碼如下:

from tensorflow.keras.datasets import cifar10
import matplotlib.pyplot as plt
import numpy as np

# 載入 CIFAR-10
(x_train, y_train), (x_test, y_test) = cifar10.load_data()

print("訓練資料形狀:", x_train.shape)
print("測試資料形狀:", x_test.shape)

在這段程式碼中,我們會得到 50,000 張訓練圖片10,000 張測試圖片
每張圖片的尺寸是 (32, 32, 3),
也就是高 32、寬 32、3 個顏色通道(RGB)。

2. 資料前處理

對於資料前處理部分,我們先看程式碼,後解釋:

from tensorflow.keras.utils import to_categorical

# 標籤轉換成 one-hot encoding
y_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)

# 正規化圖片像素值到 [0,1]
x_train = x_train.astype("float32") / 255.0
x_test = x_test.astype("float32") / 255.0

在這段程式碼中,我們做了兩件事:
第一個就是我們講過好幾次的「one-hot encoding」,
就是讓標籤變成像 [0,0,0,1,0,0,0,0,0,0] 的形式,方便模型處理分類問題。
詳細解釋也可以去翻閱我之前的文章,這裡省略一萬字。

再者,我們一樣對數值進行「正規化」,避免數值太過分散導致不好訓練。
這也是我們每次執行實作都會進行的前置作業。

3. 建立模型

接著就是建立模型啦!!!
話不多說,上程式碼:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense

model = Sequential([model = models.Sequential([
    layers.Conv2D(32, (3, 3), padding='same', input_shape=(32, 32, 3)),
    layers.BatchNormalization(),
    layers.Activation('relu'),
    layers.MaxPooling2D((2, 2)),

    layers.Conv2D(64, (3, 3), padding='same'),
    layers.BatchNormalization(),
    layers.Activation('relu'),
    layers.MaxPooling2D((2, 2)),

    layers.Conv2D(64, (3, 3), padding='same'),
    layers.BatchNormalization(),
    layers.Activation('relu'),

    layers.Flatten(),
    layers.Dense(64),
    layers.BatchNormalization(),
    layers.Activation('relu'),
    layers.Dense(10, activation='softmax')
])
    Conv2D(32, (3,3), activation='relu', input_shape=(32,32,3)),
    MaxPooling2D((2,2)),
    Conv2D(64, (3,3), activation='relu'),
    MaxPooling2D((2,2)),
    Flatten(),
    Dense(64, activation='relu'),
    Dense(10, activation='softmax')
])

上面的程式碼就是一個簡單的卷積神經網路(CNN)
這裡的資訊比較多一點,就稍微解釋一下:

- 第一層 Conv2D (32 filters)

在這一層中,我們使用 32 個「濾鏡」去掃描輸入的彩色圖片。
每個濾鏡的大小是 3x3,用來捕捉圖片最基本的特徵,例如邊緣、線條或顏色的變化。

而在這一層中也設定了 nput_shape=(32, 32, 3),代表輸入的影像大小是 32x32 ,
且有三個顏色通道 (RGB)。

激活函數則是使用 relu
(在「神經元大解密」那篇文章有詳細介紹過,可點選下方連結前往),

神經元大解密:
https://ithelp.ithome.com.tw/articles/10383027

- BatchNormalization

在這一層,我們對卷積層的輸出進行「正規化」,也就是讓數值分布維持在比較穩定的範圍。
這個是我們前一篇文章就討論過的概念,這樣做的好處就是
能加快訓練速度,並且減少梯度消失或梯度爆炸的問題。

(文章連結: )

- MaxPooling2D (2x2)

這一層則會將特徵圖縮小。具體做法是取 2x2 的小區塊,
並從中選出一個代表值 (最大值)。
這樣能保留主要特徵,同時降低運算量,讓後續的計算更有效率。

- 第二層 Conv2D (64 filters)

接下來再加入一個卷積層,這次使用 64 個濾鏡。
這時候模型已經能從圖片中抽取更進一步的特徵,
例如形狀或紋理,而不只是單純的顏色變化。

- 第三層 Conv2D (64 filters)

我們再堆疊一層卷積層,依舊使用 64 個濾鏡。
這時候模型會更聚焦於影像中的細節與更高階的模式,
例如某些物體的局部結構。

- Flatten

這一步將 2D 的特徵圖「攤平」成一個一維的向量,
方便送入後面的全連接層(Dense 層)。
這就像是把圖片拆解後的一堆特徵,全部排成一列。

- Dense (64, relu)

這是一個全連接層,擁有 64 個神經元。
它的工作是將前面抽取到的特徵進行組合
進一步學習圖片中更抽象的表示方式。

激活函數同樣使用 ReLU,能有效提升模型的表現能力。

- Dense (10, softmax)

最後是輸出層,擁有 10 個神經元,分別對應 CIFAR-10 資料集中 10 個類別
激活函數則是 Softmax,會將輸出的數值轉換成機率分布
讓我們可以知道圖片屬於每一個類別的可能性。

以上的結構就是一個最基本的 CNN 架構,能夠處理彩色影像並做分類,
我們之後也會繼續做相關的內容創作,還請大家期待。

4. 編譯模型

model.compile(optimizer='adam',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

參數解釋:

optimizer="adam":

Adam 是一種自動調整學習率的最佳化方法,通常收斂快且表現穩定。

loss="categorical_crossentropy":

分類任務常用的損失函數,會量化模型預測機率與真實標籤差多少。

metrics=["accuracy"]:

訓練/驗證時會顯示正確率(accuracy)作為衡量指標。

5. 訓練模型

history = model.fit(x_train, y_train,
                    epochs=50,
                    batch_size=64,
                    validation_split=0.2,
                    verbose=2)

接著在這裡就是正式開始訓練了,
我們分別要設定訓練次數(epochs)訓練數量(batch_size)
驗證集比率(validation_split)
以及訓練過程的進度資訊(verbose)

以上四個也分別代表從上到下的參數。

6. 評估模型

test_loss, test_acc = model.evaluate(x_test, y_test, verbose=2)
print("測試集損失:", test_loss)
print("測試集正確率:", test_acc)

最後我們用測試資料來檢驗模型的表現,
會使用到前面介紹過的「loss」以及「accuracy」,
分別代表損失值(越低越好)以及正確率(越高越好)。

7. 額外練習:可視化

其實原本只有到上一步就結束了,
但我想到似乎前幾天才做過可視化的相關介紹,不如也融入到今天的內容中,
於是乎我新增了以下程式碼:

# 繪製 Loss 與 Accuracy 曲線
plt.figure(figsize=(12, 5))

# Loss 曲線
plt.subplot(1, 2, 1)
plt.plot(history.history['loss'], label='訓練 Loss')
plt.plot(history.history['val_loss'], label='驗證 Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Loss 曲線')
plt.legend()

# Accuracy 曲線
plt.subplot(1, 2, 2)
plt.plot(history.history['accuracy'], label='訓練 Accuracy')
plt.plot(history.history['val_accuracy'], label='驗證 Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.title('Accuracy 曲線')
plt.legend()

plt.show()

8. 成果演示

最後最後,我們就來看成果吧:

https://ithelp.ithome.com.tw/upload/images/20250926/20169196XwZP7XcYU4.png

可以看到,由於是訓練較複雜的模型,我們的準確率只有約72%,
算是還有很大的進步空間。

9. 檢討

在參考其他的資訊後,我認為還有幾個可以加入實作的地方:

- Dropout

Dropout 是一種常見的正則化方法,用來減少過擬合(overfitting)。
它的做法是在訓練過程中,隨機「關閉」部分神經元,讓網路不能過度依賴某些特定的特徵。
這樣的隨機屏蔽會迫使模型學習到更普遍、更穩健的特徵,而不是只記住訓練資料。

- 資料增強(Data Augmentation)

資料增強的目的是「讓訓練資料變多、變多樣化」,
而且這些資料是透過對原始圖片進行合理變形而來的。

在 CIFAR-10 中,雖然原始有 5 萬張訓練圖片,但對於深度學習模型來說仍然可能不足。
藉由隨機旋轉、平移、翻轉、亮度或對比度調整,
我們能模擬不同的攝影條件或角度,讓模型學會更強的辨識能力

這些我查閱到的內容似乎可以幫助我的模型訓練得更好,但這篇篇幅炸了,
所以請容許我在下次實作時再加入這些東西,抱歉啦......


參考資料:
https://medium.com/@charlie910417/cifar10-classifer-using-vgg19-d948a4df6b20](http://)
https://medium.com/%E6%89%8B%E5%AF%AB%E7%AD%86%E8%A8%98/%E4%BD%BF%E7%94%A8-tensorflow-%E4%BA%86%E8%A7%A3-dropout-bf64a6785431
https://chtseng.wordpress.com/2017/11/11/data-augmentation-%E8%B3%87%E6%96%99%E5%A2%9E%E5%BC%B7/
https://yhhuang1966.blogspot.com/2018/04/keras-cifar-10.html


上一篇
Batch Normalization:讓訓練更穩定的小秘訣
下一篇
圖片辨識的秘密武器:卷積神經網路(CNN)直觀理解
系列文
《AI 新手到職場應用:深度學習 30 天實戰》18
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言