当前位置: 华文世界 > 科技

机器学习技术:构建卷积神经网络的分步代码指南

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