當前位置: 華文世界 > 科技

機器學習技術:構建摺積神經網路的分步程式碼指南

2024-08-28科技

在今天的文章中,我們將使用 TensorFlow 構建摺積神經網路 (CNN)。本文假設您已經熟悉 CNN 的內部運作和數學基礎。我們在這裏只關註實施,因此先驗知識將幫助您更輕松地進行操作。

我們將建立相同的簡單影像分類器,用於預測給定影像是否為「X」。

我們將在此過程中詳細分解每個步驟,以確保您了解如何以及為什麽!

步驟 1:匯入必要的庫

import tensorflow as tffrom tensorflow.keras.models import Sequentialfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Densefrom tensorflow.keras.optimizers import Adamimport numpy as npimport matplotlib.pyplot as plt

TensorFlow 和 Keras(這是 TensorFlow 中的一個高級 API)將處理我們的 CNN 的建立和訓練,而 NumPy 和 Matplotlib 將幫助我們進行數據操作和視覺化。

註意:為了確保每次執行程式碼時的結果都是一致的,我們將設定一個隨機種子:

# Setting seed for reproducibilitynp.random.seed(42)tf.random.set_seed(42)

設定種子可以確保程式碼中的隨機行程每次都以相同的方式執行,從而確保結果的一致性。把它想象成每次我們玩時以完全相同的順序洗牌。

第 2 步:了解和生成數據

讓我們首先生成我們的模型將學習分類的影像。之前我們看到「X」可以用 5x5 像素的影像表示,如下所示:

讓我們將其轉換為程式碼:

# 'X' patterndef generate_x_image(): return np.array([ [1, 0, 0, 0, 1], [0, 1, 0, 1, 0], [0, 0, 1, 0, 0], [0, 1, 0, 1, 0], [1, 0, 0, 0, 1] ])

此函式生成「X」的簡單 5x5 影像。接下來,我們將建立一個函式,該函式生成不類似於「X」的隨機 5x5 影像:

def generate_not_x_image(): # Ensuring not to generate an 'X' pattern while True: img = np.random.randint(2, size=(5, 5)) if not np.array_equal(img, generate_x_image()): return img

步驟 3:構建數據集

準備好我們的函式後,我們現在可以建立一個包含 1,000 張影像的數據集。我們將相應地標記它們,1 表示「X」的影像,0 表示不是「X」的影像:

# Create a datasetnum_samples = 1000images = []labels = []for _ in range(num_samples): if np.random.rand() > 0.5: images.append(generate_x_image()) labels.append(1) else: images.append(generate_not_x_image()) labels.append(0)images = np.array(images).reshape(-1, 5, 5, 1)labels = np.array(labels)

此程式碼生成 1,000 張影像,其中一半包含「X」,另一半則不包含。然後,我們重塑影像,以確保它們具有適合我們 CNN 的正確尺寸。

為了有效地訓練我們的模型,我們將此數據集分為訓練集和測試集:

# Split the data into training and testing setsfrom sklearn.model_selection import train_test_splitx_train, x_test, y_train, y_test = train_test_split(images, labels, test_size=0.2, random_state=42)

這種拆分保留了 80% 的數據用於訓練模型,20% 的數據用於測試模型。測試集幫助我們評估模型在新的、看不見的數據上的表現。

在我們深入研究模型構建之前,讓我們看一下數據集中的一些影像,以了解我們正在處理的內容。

# Function to display imagesdef display_sample_data(images, labels, num_samples=5): plt.figure(figsize=(10, 2)) for i in range(num_samples): ax = plt.subplot(1, num_samples, i + 1) plt.imshow(images[i].reshape(5, 5), cmap='gray_r') plt.title(f'Label: {labels[i]}') plt.axis('off') plt.show()

此函式顯示來自我們訓練集的影像,幫助我們確認數據已正確標記和格式化。

# Display first 5 samples of our training datadisplay_sample_data(x_train, y_train)

第 4 步:構建 CNN 模型

現在我們的數據已經準備好了,讓我們來構建CNN!下面是我們之前使用的架構:

1 — 摺積層 :對輸入影像套用四個 3x3 濾鏡以檢測特征並建立四個特征圖

2 — 最大池化層 :減小特征圖的維度,使模型更高效

3 — 展平層 :將 2D 數據轉換為 1D 陣列,為神經網路做好準備

4 — 隱藏層 :一個完全連線的隱藏層,有三個神經元,都具有ReLU啟用功能

5 — 輸出層 :具有sigmoid啟用功能的單個神經元

model = Sequential([ # 1 - Convolutional Layer Conv2D(4, (3, 3), activation='relu', input_shape=(5, 5, 1)), # 2 - Max-Pooling Layer MaxPooling2D(pool_size=(2, 2)), # 3 - Flatten Layer Flatten(), # 4 - Hidden Layer Dense(3, activation='relu'), # 5 - Output Layer Dense(1, activation='sigmoid')])

步驟 5:編譯模型

編譯模型至關重要,因為它定義了模型的學習方式。以下是編譯函式的每個部份的作用:

  1. 最佳化器 (Adam) :最佳化器調整模型的權重以最小化損失函式。我們使用 亞當 在這裏,但是這是一個列表可以使用的其他最佳化器。
  2. 損失函式(二元交叉熵) :衡量模型的預測與實際結果之間的差距。由於我們正在處理二元分類(X 或非 X), 二元交叉熵 是合適的。損失值是模型在訓練過程中嘗試最小化的值。損失值越低表示效能越好(即,模型的預測更接近實際值)。損失直接影響模型的訓練方式,最佳化器使用它來更新模型的權重,使其在最小化損失的方向上。
  3. 指標(準確性) :指標用於評估模型的效能。我們使用 準確性 跟蹤正確預測在所有預測中所占的比例。 指標是評估模型效能的附加度量,但最佳化器在訓練期間不會使用它們來調整模型 .它們提供了一種評估模型效能的方法。

註意 雖然準確性是一個常見的指標,但它並不總是最可靠的,尤其是在數據集不平衡等某些情況下。但是,為簡單起見,我們將在此處使用它。如果您有興趣探索其他評估指標,這些指標可能會提供更細致的模型效能檢視,那麽品涵蓋了一些替代方案。

model.compile(optimizer=Adam(), loss='binary_crossentropy', metrics=['accuracy'])

步驟 6:訓練模型

訓練模型涉及多次(紀元)向其提供訓練數據,以便它可以學習做出更好的預測。一個時期是整個訓練數據集的一次完整傳遞。我們將訓練 10 個時期的模型:

history = model.fit(x_train, y_train, epochs=10, validation_data=(x_test, y_test))

步驟 7:評估模型

訓練後,我們在測試數據上評估模型的效能:

loss, accuracy = model.evaluate(x_test, y_test)print(f'Test Accuracy: {accuracy * 100:.2f}%')

準確度指標告訴我們,測試數據中 94.8% 的影像被正確分類。

第 8 步:視覺化訓練過程

最後,讓我們直觀地了解模型的精度在各個時期是如何變化的。這有助於我們了解模型在訓練期間的學習情況:

plt.plot(history.history['accuracy'], label='accuracy')plt.plot(history.history['val_accuracy'], label='val_accuracy')plt.xlabel('Epoch')plt.ylabel('Accuracy')plt.legend()plt.show()

就是這樣。我們已經構建了一個簡單的摺積神經網路,可以在不到 5 分鐘的時間內使用 TensorFlow 預測影像是否為「X」!

參考:

https://towardsdatascience.com/implementing-convolutional-neural-networks-in-tensorflow-bc1c4f00bd34