在本文中,我们将使用TensorFlow和Keras创建一个图像分类器,可以区分猫和狗的图像。为了做到这一点,我们将使用TensorFlow数据集中的cats_vs_dogs数据集。该数据集由25000张打过标签的猫和狗的图像组成,其中80%的图像用于训练,10%用于验证,10%用于测试。
加载数据
我们从使用TensorFlow Datasets加载数据集开始。将数据集拆分为训练集、验证集和测试集,分别占数据的80%、10%和10%,并定义一个函数来显示数据集中的一些样本图像。
import tensorflow as tf
import matplotlib.pyplot as plt
import tensorflow_datasets as tfds
# 加载数据
(train_data, validation_data, test_data), info = tfds.load('cats_vs_dogs',
split=['train[:80%]', 'train[80%:90%]', 'train[90%:]'],
with_info=True,
as_supervised=True)
# 获取图像的标签
label_names = info.features['label'].names
# 定义一个函数来显示一些样本图像
plt.figure(figsize=(10, 10))
for i, (image, label) in enumerate(train_data.take(9)):
ax = plt.subplot(3, 3, i + 1)
plt.imshow(image)
plt.title(label_names[label])
plt.axis('off')
预处理数据
在训练模型之前,需要对数据进行预处理。将把图片的大小调整为150x150像素的统一尺寸,将像素值归一化为0和1之间,并对数据进行批处理,这样就可以将其分批导入模型中。
IMG_SIZE = 150
def format_image(image, label):
image = tf.cast(image, tf.float32) / 255.0 # Normalize the pixel values
image = tf.image.resize(image, (IMG_SIZE, IMG_SIZE)) # Resize to the desired size
return image, label
batch_size = 32
train_data = train_data.map(format_image).shuffle(1000).batch(batch_size)
validation_data = validation_data.map(format_image).batch(batch_size)
test_data = test_data.map(format_image).batch(batch_size)
搭建模型
本文将使用预先训练好的MobileNet V2模型作为基础模型,并在其中添加一个全局平均池化层和一个紧密层来进行分类。本文将冻结基础模型的权重,以便在训练期间只更新顶层的权重。
base_model = tf.keras.applications.MobileNetV2(input_shape=(IMG_SIZE, IMG_SIZE, 3),
include_top=False,
weights='imagenet')
base_model.trainable = False
global_average_layer = tf.keras.layers.GlobalAveragePooling2D()
prediction_layer = tf.keras.layers.Dense(1)
model = tf.keras.Sequential([
base_model,
global_average_layer,
prediction_layer
])
model.compile(optimizer=tf.keras.optimizers.RMSprop(lr=0.0001),
loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
metrics=['accuracy'])
训练模型
本文将对模型进行3个周期的训练,并在每个周期之后在验证集上对其进行验证。我们将在训练后保存模型,这样就可以在以后的测试中使用它。
global_average_layer = tf.keras.layers.GlobalAveragePooling2D()
prediction_layer = tf.keras.layers.Dense(1)
model = tf.keras.Sequential([
base_model,
global_average_layer,
prediction_layer
])
model.compile(optimizer=tf.keras.optimizers.RMSprop(lr=0.0001),
loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
metrics=['accuracy'])
history = model.fit(train_data,
epochs=3,
validation_data=validation_data)
模型历史
如果想知道Mobilenet V2层是如何工作的,如下图所示是该层的一个结果。
评估模型
训练完成后将在测试集上评估该模型,看看它在新数据上的表现如何。
loaded_model = tf.keras.models.load_model('cats_vs_dogs.h5')
test_loss, test_accuracy = loaded_model.evaluate(test_data)
print('Test accuracy:', test_accuracy)
进行预测
最后,本文将使用该模型对测试集中的一些样本图像进行预测,并显示结果。
for image , _ in test_.take(90) :
pass
pre = loaded_model.predict(image)
plt.figure(figsize = (10 , 10))
j = None
for value in enumerate(pre) :
plt.subplot(7,7,value[0]+1)
plt.imshow(image[value[0]])
plt.xticks([])
plt.yticks([])
if value[1] > pre.mean() :
j = 1
color = 'blue' if j == _[value[0]] else 'red'
plt.title('dog' , color = color)
else :
j = 0
color = 'blue' if j == _[value[0]] else 'red'
plt.title('cat' , color = color)
plt.show()
大功告成!我们通过使用TensorFlow和Keras创建了一个图像分类器,可以区分猫和狗的图像。通过一些调整和微调,也可以将这种方法应用于其他图像分类问题。