深度学习项目:CIFAR-10图像分类(附完整代码)
CIFAR-10图像分类
先决条件:
- 图像分类
- 卷积神经网络,包括基本的池化、带有神经网络中的归一化的卷积层和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')
更多推荐
所有评论(0)