使用fastai构建食物图像分类器

在本文中,将探讨如何使用fastai库来构建一个基于PyTorch的食物图像分类器。fastai是一个开源的深度学习库,它为实践者提供了高级组件,可以快速且轻松地在传统深度学习领域产生最先进的结果。同时,它也为研究人员提供了低级组件,可以混合和组合以创造新的技术。fastai是用Python编写的,并且基于PyTorch,因此理解本文需要具备Python知识。将在Google Colab中运行此代码。除了fastai,还将使用图形处理单元(GPU)以尽可能快地获得结果。

首先,需要安装fastai库。可以使用以下命令来安装:

!pip install -Uqq fastai

如果使用的是Anaconda,可以使用以下命令:

conda install -c fastchan fastai anaconda

接下来,将导入分类任务所需的包。fastai库被分为多个模块,其中最常见的是tabular、text和vision。由于任务涉及到视觉,将从vision库中导入所有需要的函数。

from fastai.vision.all import *

fastai库提供了许多学术数据集。其中之一是FOOD,它列在URLs下。获取和提取所需数据的第一步是使用untar_data函数,该函数将自动下载数据集并解压缩。

foodPath = untar_data(URLs.FOOD)

此数据集包含101,000张图片,分为101个食物类别,每个类别有250张测试图片和750张训练图片。训练中的图片没有被清理。所有图片都被调整到每边最大512像素。可以从下载数据集。

接下来的命令将告诉需要处理多少张图片。

len(get_image_files(foodPath))

此外,使用以下命令,将打印出Food数据集的meta目录的内容。

print(os.listdir(foodPath))

meta文件夹包含八个文件,其中四个是文本文件:train.txt、test.txt、classes.txt和labels.txt。train.txt和test.txt文件分别包含训练和测试集的图片列表。classes.txt文件包含所有食物类别的列表,而labels.txt提供所有食物图片标签的列表。该目录还包含一个.h5文件,其中包含预训练模型,以及一个包含101,000张JPG格式图片的images文件夹。最后,训练和测试集以JSON格式提供。

要查看所有图片类别,将运行以下命令:

image_dir_path = foodPath/'images' image_categories = os.listdir(image_dir_path) print(image_categories)

然后,将执行以下命令以查看101,000张图片中的一个样本图片。

img = PILImage.create('/root/.fastai/data/food-101/images/frozen_yogurt/1942235.jpg') img.show();

将使用pandas函数以JSON格式读取训练和测试文件。JSON是一种数据格式,以人类可读的形式存储信息。以下代码读取目录中的train.json文件,并将结果保存在df_train数据框中。

df_train=pd.read_json('/root/.fastai/data/food-101/train.json') df_train.head()

类似地,使用pandas函数,将读取test.json文件并将其存储在df_test数据框中。

df_test=pd.read_json('/root/.fastai/data/food-101/test.json') df_test.head()

创建了三个标签,分别包含选择的食物名称,以对食物图片进行分类。

labelA = 'cheesecake' labelB = 'donuts' labelC= 'panna_cotta'

现在,将创建一个for循环,该循环将遍历下载的所有图片。借助此循环,正在移除没有标签A、B或C的图片。同时,正在使用以下函数通过使用各自的标签重命名图片。

for img in get_image_files(foodPath): if labelA in str(img): img.rename(f"{img.parent}/{labelA}-{img.name}") elif labelB in str(img): img.rename(f"{img.parent}/{labelB}-{img.name}") elif labelC in str(img): img.rename(f"{img.parent}/{labelC}-{img.name}") else: os.remove(img)

让检查运行循环后得到的图片数量。

len(get_image_files(foodPath))

让尝试检查三个选定的食物菜肴中的一个样本标签,并查看重命名是否正确。

def GetLabel(fileName): return fileName.split('-')[0] GetLabel("cheesecake-1092082.jpg")

输出:

以下代码生成一个DataLoaders对象,它代表训练和验证数据的混合。

dls = ImageDataLoaders.from_name_func( foodPath, get_image_files(foodPath), valid_pct=0.2, seed=42, label_func=GetLabel, item_tfms=Resize(224)) dls.train.show_batch()

在这种情况下,将:

- 使用path选项指定下载和解压缩数据的位置。

- 使用get_image_files函数从指定位置收集所有文件名。

- 对数据集进行80-20的分割。

- 使用GetLabel函数从文件名中提取标签。

- 将所有图片调整到相同的大小,即224像素。

- 使用show_batch函数生成一个输出窗口,显示带有分配标签的训练图片网格。

是时候让模型发挥作用了。将使用ResNet34架构构建一个卷积神经网络,重点关注一个名为vision_learner()的单一函数调用。vision_learner函数(也称为cnn_learner)对于训练计算机视觉模型非常有益。它包括原始图像数据集、预训练模型resnet34和一个度量误差率,该误差率决定了在验证数据上错误识别的图片比例。resnet34中的34指的是这种架构类型的层数(其他选项是18、50、101和152)。使用更多层的模型需要更长的时间来训练,并且更容易过拟合。

fastai提供了一个‘fine_tune’函数,用于调整预训练模型以解决选择的数据的特定问题。对于训练模型,将设置训练周期的数量为10。

learn = vision_learner(dls, resnet34, metrics=error_rate, pretrained=True) learn.fine_tune(epochs=10)

同样,也可以通过将度量替换为‘accuracy’来检查模型的准确性。

从上述结果中,可以说,即使只有10个周期,预训练的ResNet34模型也显示出对于多标签分类任务的>85%的良好准确性。如果增加周期的数量,模型的准确性可能会提高。

现在,让测试一些样本图片,以检查模型性能如何。

样本图片 #1

样本图片 #2

样本图片 #3

从上述结果中,可以说,模型能够正确识别样本图片。

训练模型后,可以将其部署为Web应用程序供其他人使用。尽管fastai主要用于模型训练,但可以快速导出PyTorch模型以在生产中使用‘learn.export’函数。本教程的代码可在中找到。

结论:

在本教程中,学习了如何使用基于PyTorch的fastai构建食物图像分类器。可以使用Heroku或Netlify等服务部署此模型,使其作为Web应用程序可用。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485