在 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")
输出:
Downloading and preparing dataset Unknown size (download: Unknown size, generated: Unknown size, total: Unknown size) to C:\Users\ksaty\tensorflow_datasets\rock_paper_scissors\3.0.0…
Dl Completed…: 100%
2/2 [00:50<00:00, 25.01s/ url]
Dl Size…: 100%
219/219 [00:50<00:00, 4.38 MiB/s]
Dataset rock_paper_scissors downloaded and prepared to C:\Users\ksaty\tensorflow_datasets\rock_paper_scissors\3.0.0. Subsequent calls will reuse this data.
一些例子
第 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 是一个持续学习的过程。