先决条件:

  • 图像分类
  • 卷积神经网络,包括基本的池化、带有神经网络中的归一化的卷积层和dropout。
  • 数据增强。
  • 神经网络。
  • Numpy数组。

在这篇文章中,我们将讨论如何使用TensorFlow对图像进行分类。图像分类是一种将图像分类到其相应的类别类中的方法。CIFAR-10数据集如其名称所示,其中包含10种不同类别的图像。总共有60000张10个不同类别的图像,分别是飞机、汽车、鸟、猫、鹿、狗、青蛙、马、船、卡车。所有的图像大小都是32×32。总共有50000张训练图像和10000张测试图像。

为了构建一个图像分类器,我们使用tensorflow的keras API来构建我们的模型。为了构建一个模型,建议有GPU支持,或者你也可以使用Google colab笔记本。

Python实现

首先,我们需要导入所有必需的库和模块。这包括导入tensorflow和其他模块,如numpy。如果模块不存在,你可以在命令提示符上使用pip install tensorflow来下载它,或者如果你使用的是jupyter笔记本,只需在单元格中输入!pip install tensorflow并运行它,以下载模块。其他模块也可以类似地导入。

import tensorflow as tf
print(tf.__version__)
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.layers import Input, Conv2D, Dense, Flatten, Dropout
from tensorflow.keras.layers import GlobalMaxPooling2D, MaxPooling2D
from tensorflow.keras.layers import BatchNormalization
from tensorflow.keras.models import Model

如下:
在这里插入图片描述

现在我们已经有了所需的模块支持,让我们加载我们的数据。CIFAR-10的数据集可以在tensorflow keras API上找到,我们可以使用tensorflow.keras.datasets.cifar10在我们的本地机器上下载它,然后使用load_data()函数将其分配给训练和测试集。

cifar10 = tf.keras.datasets.cifar10
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
print(x_train.shape, y_train.shape, x_test.shape, y_test.shape)

如下所示:在这里插入图片描述
到目前为止,我们已经有了数据。但是,我们还不能直接将其发送到我们的神经网络。我们需要处理数据,然后再发送给网络。首先,我们需要减少像素值。目前,所有的图像像素都在1-256的范围内,我们需要将这些值减少到0和1之间的值。这使得我们的模型更容易跟踪趋势和有效的训练。我们可以简单地通过将所有像素值除以255.0来实现这一点。

我们还想使用flatten()函数将标签值展平(简单地说,将它们重新排列成一行的形式)。

x_train, x_test = x_train / 255.0, x_test / 255.0
y_train, y_test = y_train.flatten(), y_test.flatten()

现在是查看我们数据集中的几张图像的好时机。我们可以使用matplotlib的subplot()函数在子图网格形式中进行可视化,并循环遍历我们的训练数据集部分的前25张图像。

fig, ax = plt.subplots(5, 5)
k = 0
for i in range(5):
    for j in range(5):
        ax[i][j].imshow(x_train[k], aspect='auto')
        k += 1
plt.show()

如下所示:
在这里插入图片描述
完成所有步骤后,现在是构建我们的模型的时候了。我们将使用卷积神经网络或CNN来训练我们的模型。这包括使用卷积层,这是Conv2d层,以及池化和归一化方法。最后,我们将其传递到一个密集层和最后的密集层,这是我们的输出层。我们使用’relu’激活函数。输出层使用“softmax”函数。

K = len(set(y_train))
print("number of classes:", K)
i = Input(shape=x_train[0].shape)
x = Conv2D(32, (3, 3), activation='relu', padding='same')(i)
x = BatchNormalization()(x)
x = Conv2D(32, (3, 3), activation='relu', padding='same')(x)
x = BatchNormalization()(x)
x = MaxPooling2D((2, 2))(x)
x = Conv2D(64, (3, 3), activation='relu', padding='same')(x)
x = BatchNormalization()(x)
x = Conv2D(64, (3, 3), activation='relu', padding='same')(x)
x = BatchNormalization()(x)
x = MaxPooling2D((2, 2))(x)
x = Conv2D(128, (3, 3), activation='relu', padding='same')(x)
x = BatchNormalization()(x)
x = Conv2D(128, (3, 3), activation='relu', padding='same')(x)
x = BatchNormalization()(x)
x = MaxPooling2D((2, 2))(x)
x = Flatten()(x)
x = Dropout(0.2)(x)
x = Dense(1024, activation='relu')(x)
x = Dropout(0.2)(x)
x = Dense(K, activation='softmax')(x)
model = Model(i, x)
model.summary()

输出如下所示:
在这里插入图片描述
我们的模型现在已经准备好了,现在是编译它的时候了。我们使用model.compile()函数来编译我们的模型。对于参数,我们使用:

  • adam优化器
  • sparse_categorical_crossentropy作为损失函数
  • metrics=[‘accuracy’]
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

现在让我们使用model.fit()来拟合我们的模型,将所有的数据传递给它。我们将训练我们的模型直到50个时代,这给了我们一个公平的结果,尽管你可以调整它。

r = model.fit(
  x_train, y_train, validation_data=(x_test, y_test), epochs=50)

如下所示:
在这里插入图片描述
此后,我们的模型已经训练好了。尽管它工作得很好,但为了使我们的模型更加准确,我们可以在我们的数据上添加数据增强,然后再次训练它。再次调用model.fit()将从之前的地方继续训练。我们将使用32的批量大小,并将宽度和高度的范围移动0.1,并水平翻转图像。然后再次调用model.fit,进行50个迭代。

batch_size = 32
data_generator = tf.keras.preprocessing.image.ImageDataGenerator(
  width_shift_range=0.1, height_shift_range=0.1, horizontal_flip=True)
train_generator = data_generator.flow(x_train, y_train, batch_size)
steps_per_epoch = x_train.shape[0] // batch_size
r = model.fit(train_generator, validation_data=(x_test, y_test),
              steps_per_epoch=steps_per_epoch, epochs=50)

如下所示:
在这里插入图片描述
现在我们已经训练了我们的模型,在使用model.predict()函数从中进行任何预测之前,让我们为了更好地分析模型,可视化每次迭代的准确性。尽管还有其他方法,包括混淆矩阵,用于更好地分析模型。

plt.plot(r.history['accuracy'], label='acc', color='red')
plt.plot(r.history['val_accuracy'], label='val_acc', color='green')
plt.legend()

如下所示:
在这里插入图片描述

让我们使用model.predict()函数对我们的模型进行一次预测。在将图像发送到我们的模型之前,我们需要再次减少像素值在0和1之间,并将其形状改为(1,32,32,3),因为我们的模型只期望输入是这种形式的。为了简化,让我们从数据集中选择一张图像。它已经是减少像素格式的,但我们仍然需要使用reshape()函数将其重塑为(1,32,32,3)。因为我们使用的是数据集中的数据,所以我们可以比较预测的输出和原始的输出。

labels = '''airplane automobile bird cat deerdog frog horseship truck'''.split()
image_number = 0
plt.imshow(x_test[image_number])
n = np.array(x_test[image_number])
p = n.reshape(1, 32, 32, 3)
predicted_label = labels[model.predict(p).argmax()]
original_label = labels[y_test[image_number]]
print("Original label is {} and predicted label is {}".format(
    original_label, predicted_label))

如下所示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

最后,让我们使用model.save()函数将我们的模型保存为h5文件。如果你使用的是Google colab,你可以从文件部分下载你的模型。

model.save('geeksforgeeks.h5')
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐