宠物真实生活图像分类#
来自 AI for Beginners Curriculum 的实验任务。
现在是时候处理一个更具挑战性的任务了——对原始的 Oxford-IIIT 数据集 进行分类。让我们从加载和可视化数据集开始吧。
!wget https://www.robots.ox.ac.uk/~vgg/data/pets/data/images.tar.gz
!tar xfz images.tar.gz
!rm images.tar.gz我们将定义通用函数以从列表中显示一系列图像:
import matplotlib.pyplot as plt
import os
from PIL import Image
import numpy as np
def display_images(l,titles=None,fontsize=12):
n=len(l)
fig,ax = plt.subplots(1,n)
for i,im in enumerate(l):
ax[i].imshow(im)
ax[i].axis('off')
if titles is not None:
ax[i].set_title(titles[i],fontsize=fontsize)
fig.set_size_inches(fig.get_size_inches()*n)
plt.tight_layout()
plt.show()您可以看到所有图像都位于一个名为images的目录中,并且它们的名称包含类别(品种)的名称:
fnames = os.listdir('images')[:5]
display_images([Image.open(os.path.join('images',x)) for x in fnames],titles=fnames,fontsize=30)为了简化分类并使用与上一部分相同的方法加载图像,让我们将所有图像排序到相应的目录中:
for fn in os.listdir('images'):
cls = fn[:fn.rfind('_')].lower()
os.makedirs(os.path.join('images',cls),exist_ok=True)
os.replace(os.path.join('images',fn),os.path.join('images',cls,fn))让我们也定义数据集中的类别数量:
num_classes = len(os.listdir('images'))
num_classes37为深度学习准备数据集#
在开始训练我们的神经网络之前,我们需要将所有图像转换为张量,同时创建与标签(类别编号)对应的张量。大多数神经网络框架都提供了处理图像的简单工具:
- 在 Tensorflow 中,可以使用
tf.keras.preprocessing.image_dataset_from_directory - 在 PyTorch 中,可以使用
torchvision.datasets.ImageFolder
正如你从上面的图片中看到的那样,所有图片的比例都接近正方形,因此我们需要将所有图像调整为正方形尺寸。此外,我们还可以将图像组织成小批量数据。
# PREPARE THE DATASET现在我们需要将数据集分为训练集和测试集:
# SPLIT INTO TRAIN-TEST DATASETS现在定义数据加载器:
# DEFINE DATA LOADERS if needed# [OPTIONAL] Plot the dataset定义一个神经网络#
对于图像分类,你可能需要定义一个具有多层的卷积神经网络。需要注意以下几点:
- 牢记金字塔结构,也就是说,随着网络加深,滤波器的数量应该增加。
- 不要忘记在层之间添加激活函数(如 ReLU)和最大池化(Max Pooling)。
- 最终的分类器可以有隐藏层,也可以没有,但输出神经元的数量应该等于类别的数量。
一个重要的点是要正确设置最后一层的激活函数和损失函数:
- 在 Tensorflow 中,你可以使用
softmax作为激活函数,并使用sparse_categorical_crossentropy作为损失函数。稀疏分类交叉熵和非稀疏的区别在于,前者期望输出为类别编号,而不是 one-hot 向量。 - 在 PyTorch 中,最后一层可以不使用激活函数,直接使用
CrossEntropyLoss作为损失函数。这个函数会自动应用 softmax。
提示: 在 PyTorch 中,你可以使用
LazyLinear层代替Linear,以避免手动计算输入的数量。它只需要一个n_out参数,即该层的神经元数量,输入数据的维度会在第一次forward传递时自动确定。
# DEFINE NEURAL NETWORK ARCHITECTURE训练神经网络#
现在我们可以开始训练神经网络了。在训练过程中,请在每个训练周期收集训练数据和测试数据的准确率,然后绘制准确率图表,以观察是否存在过拟合现象。
# TRAIN THE NEURAL NETWORK# PLOT THE RESULT: Train and Test Accuracy迁移学习#
为了提高准确率,我们可以使用预训练的神经网络作为特征提取器。可以尝试使用 VGG-16/VGG-19 模型、ResNet50 等。
由于这种训练速度较慢,可以先尝试用较少的训练轮次(例如 3 轮)来训练模型。如果需要进一步提高准确率,可以随时继续训练。
在迁移学习中,我们需要以不同的方式对数据进行归一化,因此需要使用一组不同的变换重新加载数据集:
# LOAD THE DATASET
# Perform standard transformations for VGG-16/VGG-19 if needed # vgg = ...现在为您的问题定义分类模型:
- 在 PyTorch 中,有一个名为
classifier的模块,您可以将其替换为适用于目标类别数量的自定义分类器。 - 在 TensorFlow 中,使用 VGG 网络作为特征提取器,并构建一个
Sequential模型,将 VGG 作为第一层,并在其上添加您的自定义分类器。
# BUILD MODEL for your problem with your own linear layers确保将 VGG 特征提取器的所有参数设置为不可训练
# MAKE VGG Layers not trainable现在我们可以开始训练了。请非常耐心,因为训练需要很长时间,而且我们的训练函数在一个周期结束之前不会打印任何内容。
# TRAIN THE MODEL现在看起来好多了!
可选:计算 Top 3 准确率#
我们也可以使用之前练习中的相同代码来计算 Top 3 准确率。
# CALCULATE TOP-3 Accuracy of the model免责声明:
本文档使用AI翻译服务Co-op Translator进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于关键信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。