📜  在 TensorFlow 中训练卷积神经网络 (CNN)

📅  最后修改于: 2022-05-13 01:54:56.891000             🧑  作者: Mango

在 TensorFlow 中训练卷积神经网络 (CNN)

在本文中,我们将使用 TensorFlow 一个大型机器学习库来实现和训练卷积神经网络 CNN。

现在在本文中,我们将处理一个名为“rock_paper_sissors”的数据集,我们需要简单地将手势分类为石头纸或剪刀。

逐步实施

第 1 步:导入库

我们将从导入一些重要的库开始。它们是 TensorFlow、NumPy、Matplotlib,最后来自 TensorFlow,我们需要 TensorFlow 数据集和 Keras

Python
pip install -q tensorflow tensorflow-datasets
 
# Importing the packages
import matplotlib.pyplot as plt
import numpy as np
 
import tensorflow as tf
import tensorflow_datasets as tfds
 
from tensorflow import keras


Python
tfds.list_builders()


Python
# Getting info about the dataset
Dataset = tfds.builder('rock_paper_scissors')
info = Dataset.info
 
print(info)


Python
# Loading the dataset
ds_train = tfds.load(name="rock_paper_scissors", split="train")
ds_test = tfds.load(name="rock_paper_scissors", split="test")


Python
# Iterating over the images and storing
# it in train and test datas
train_images = np.array([image['image'].numpy()[:, :, 0]
                         for image in ds_train])
train_labels = np.array([image['label']
                         .numpy() for image in ds_train])
 
test_images = np.array([image['image'].numpy()[:, :, 0] for image in ds_test])
test_labels = np.array([image['label'].numpy() for image in ds_test])


Python
# Reshaping the images
train_images = train_images.reshape(2520, 300, 300, 1)
test_images = test_images.reshape(372, 300, 300, 1)
 
# Changing the datatype
train_images = train_images.astype('float32')
test_images = test_images.astype('float32')
 
# getting the values down to 0 and 1
train_images /= 255
test_images /= 255


Python
# A convolutional neural network
 
# Defining the model
model = keras.Sequential([
    keras.layers.Conv2D(64, 3, activation='relu',
                        input_shape=(300, 300, 1)),
    keras.layers.Conv2D(32, 3, activation='relu'),
    keras.layers.Flatten(),
    keras.layers.Dense(3, activation='softmax')
])
 
# Compiling the model
model.compile(optimizer='adam',
              loss=keras.losses.SparseCategoricalCrossentropy(),
              metrics=['accuracy'])
 
# Fitting the model with data
model.fit(train_images, train_labels, epochs=5,
          batch_size=32)


Python
model.evaluate(test_images, test_labels)


Python
# A better convolutional neural network
 
# Model defining
model = keras.Sequential([
    keras.layers.AveragePooling2D(6, 3,
                                  input_shape=(300, 300, 1)),
    keras.layers.Conv2D(64, 3, activation='relu'),
    keras.layers.Conv2D(32, 3, activation='relu'),
    keras.layers.MaxPool2D(2, 2),
    keras.layers.Dropout(0.5),
    keras.layers.Flatten(),
    keras.layers.Dense(128, activation='relu'),
    keras.layers.Dense(3, activation='softmax')
])
 
# Compiling a model
model.compile(optimizer='adam',
              loss=keras.losses.SparseCategoricalCrossentropy(),
              metrics=['accuracy'])
 
# Fitting the model
model.fit(train_images, train_labels, epochs=5,
          batch_size=32)


第 2 步:加载数据集

在选择数据集之前,请随意探索 TensorFlow 中可用的所有数据集

Python

tfds.list_builders()

输出:

['abstract_reasoning',
 'accentdb',
 'aeslc',
 'aflw2k3d',
 'ag_news_subset',
 'ai2_arc',
 'ai2_arc_with_ir',
 'amazon_us_reviews',
 'anli',
 'arc',
 'bair_robot_pushing_small',
 'bccd',
 'beans',
 'big_patent',
 ....
 ..
 .

在加载数据集之前,我们将看到有关数据集的一些信息,以便我们轻松处理数据并收集一些非常重要的信息。

Python

# Getting info about the dataset
Dataset = tfds.builder('rock_paper_scissors')
info = Dataset.info
 
print(info)

输出:

tfds.core.DatasetInfo(
    name='rock_paper_scissors',
    full_name='rock_paper_scissors/3.0.0',
    description="""
    Images of hands playing rock, paper, scissor game.
    """,
    homepage='http://laurencemoroney.com/rock-paper-scissors-dataset',
    data_path='C:\\Users\\ksaty\\tensorflow_datasets\\rock_paper_scissors\\3.0.0',
    download_size=Unknown size,
    dataset_size=Unknown size,
    features=FeaturesDict({
        'image': Image(shape=(300, 300, 3), dtype=tf.uint8),
        'label': ClassLabel(shape=(), dtype=tf.int64, num_classes=3),
    }),
    supervised_keys=('image', 'label'),
    disable_shuffling=False,
    splits={
    },
    citation="""@ONLINE {rps,
    author = "Laurence Moroney",
    title = "Rock, Paper, Scissors Dataset",
    month = "feb",
    year = "2019",
    url = "http://laurencemoroney.com/rock-paper-scissors-dataset"
    }""",
)

最后加载数据集,

Python

# Loading the dataset
ds_train = tfds.load(name="rock_paper_scissors", split="train")
ds_test = tfds.load(name="rock_paper_scissors", split="test")

输出:

一些例子

第 3 步:分析和预处理图像

首先,为了保持干净,我们将遍历数据并将其存储为 NumPy 数组并取消图像的维度并将其存储为 train_images,并使用标签测试图像。

Python

# Iterating over the images and storing
# it in train and test datas
train_images = np.array([image['image'].numpy()[:, :, 0]
                         for image in ds_train])
train_labels = np.array([image['label']
                         .numpy() for image in ds_train])
 
test_images = np.array([image['image'].numpy()[:, :, 0] for image in ds_test])
test_labels = np.array([image['label'].numpy() for image in ds_test])

然后,现在我们将重塑图像,然后将数据类型从 uint8 转换为 float32,然后我们将所有值降低到 0 到 1,以便模型更容易从中学习。

Python

# Reshaping the images
train_images = train_images.reshape(2520, 300, 300, 1)
test_images = test_images.reshape(372, 300, 300, 1)
 
# Changing the datatype
train_images = train_images.astype('float32')
test_images = test_images.astype('float32')
 
# getting the values down to 0 and 1
train_images /= 255
test_images /= 255

第 4 步:一个基本的卷积神经网络

现在我们将创建一个基本的 CNN,它只有 2 个卷积层,带有一个 relu 激活函数和 64 和 32 个内核,内核大小为 3,并将图像展平为一维数组,卷积层直接连接到输出层。

对于编译,我们使用 Adam 优化器,对于损失,我们使用 SparseCategoricalCrossentropy(),对于度量,我们使用准确度并拟合数据。

Python

# A convolutional neural network
 
# Defining the model
model = keras.Sequential([
    keras.layers.Conv2D(64, 3, activation='relu',
                        input_shape=(300, 300, 1)),
    keras.layers.Conv2D(32, 3, activation='relu'),
    keras.layers.Flatten(),
    keras.layers.Dense(3, activation='softmax')
])
 
# Compiling the model
model.compile(optimizer='adam',
              loss=keras.losses.SparseCategoricalCrossentropy(),
              metrics=['accuracy'])
 
# Fitting the model with data
model.fit(train_images, train_labels, epochs=5,
          batch_size=32)

输出:

并评估模型

Python

model.evaluate(test_images, test_labels)

如您所见,未见数据的准确性非常低,这称为模型过度拟合,这意味着模型被训练数据过度拟合,因此它无法处理未见数据来解决这个问题,我们可以稍微修改模型。

更好的卷积神经网络

我们可以通过添加以下内容来改进此模型:

  • 辍学节点
  • 汇集
  • 全连接密集层

Python

# A better convolutional neural network
 
# Model defining
model = keras.Sequential([
    keras.layers.AveragePooling2D(6, 3,
                                  input_shape=(300, 300, 1)),
    keras.layers.Conv2D(64, 3, activation='relu'),
    keras.layers.Conv2D(32, 3, activation='relu'),
    keras.layers.MaxPool2D(2, 2),
    keras.layers.Dropout(0.5),
    keras.layers.Flatten(),
    keras.layers.Dense(128, activation='relu'),
    keras.layers.Dense(3, activation='softmax')
])
 
# Compiling a model
model.compile(optimizer='adam',
              loss=keras.losses.SparseCategoricalCrossentropy(),
              metrics=['accuracy'])
 
# Fitting the model
model.fit(train_images, train_labels, epochs=5,
          batch_size=32)

现在,如果我们评估我们的模型,您可以看到模型已经改进了很多。

这些是训练卷积神经网络的步骤。

注意:您仍然可以对模型进行一些调整和转向以提高准确性。 IT 是一个持续学习的过程。