在Python中构建您的第一个多标签图像分类模型

Introduction

你在处理图像数据吗? 我们可以使用计算机视觉算法做很多事情:

  • 物体检测
  • 图像分割
  • 图像翻译
  • 对象跟踪(实时),以及更多。

这让我思考 - 如果图像中有多个对象类别,我们该怎么办? 制作图像分类模型是一个良好的开端,但我想扩展我的视野以承担更具挑战性的任务 - 构建多标签图像分类模型!

我不想使用玩具数据集来构建我的模型 - 这太过于通用了。 然后它让我印象深刻 - 电影/电视剧海报包含各种各样的人。 我可以通过查看海报来构建自己的多标签图像分类模型来预测不同的类型吗?

简短的回答 - 是的! 在本文中,我已经解释了多标签图像分类背后的想法。 然后我们将使用电影海报建立我们自己的模型。 你会惊讶于我们模型产生的令人印象深刻的结果。 如果你是复仇者联盟或权力的游戏迷,那么在实施部分你会有一个很棒的(无剧透的)惊喜。

激动吗? 好,让我们潜入!

目录

  • 1什么是多标签图像分类?
  • 2多标签图像分类与多类图像分类有何不同?
  • 3了解多标签图像分类模型体系结构
  • 解决4个步骤构建多标签图像分类模型
  • 5个案例研究:用Python解决多标签图像分类问题

What is Multi-Label Image Classification?

让我们通过一个直观的例子来理解多标签图像分类的概念。 看看下面的图片:

图像1中的对象是汽车。 这是一个明智的选择。 然而,图像2中没有汽车 - 只有一组建筑物。 你能看到我们要去哪里吗? 我们将图像分为两类,即汽车或非汽车。

当我们只有两个类可以对图像进行分类时,这被称为二值图像分类问题。
Let’s look at one more image:

你确定了多少个物体? 有太多的东西 - 一个房子,一个有喷泉的池塘,树木,岩石等等。所以,

当我们可以将图像分类为多个类时(如上图所示),它被称为多标签图像分类问题。

现在,这里有一个问题 - 我们大多数人对多标签和多类图像分类感到困惑。 我第一次遇到这些条款时,甚至连竹子都被扯了下来。 现在我对这两个主题有了更好的理解,让我为你澄清差异。

多标签图像分类与多类图像分类有何不同?

假设给出了我们的动物图像,将其分类为相应的类别。 为了便于理解,我们假设总共有4个类别(猫,狗,兔和鹦鹉)可以对给定的图像进行分类。 现在,可以有两种情况:

  • 1每个图像只包含一个对象(上述4个类别中的任何一个),因此,它只能归入4个类别中的一个
  • 2图像可能包含多个对象(来自上述4个类别),因此图像将属于多个类别

让我们通过示例了解每个场景,从第一个开始:

在这里,我们的图像只包含一个对象。 你们中间的敏锐目光会注意到这个系列中有4种不同类型的物体(动物)。

这里的每张图片只能分为猫,狗,鹦鹉或兔子。 没有单个图像属于多个类别的情况。

  • 1 当有两个以上的类别可以对图像进行分类时,和

  • 2.图像不属于多个类别

如果满足上述两个条件,则称为多类图像分类问题。

现在,让我们考虑第二种情况 - 查看下面的图像:

在这里插入图片描述

  • 第一张图片(左上角)包含一只狗和一只猫
  • 第二张图片(右上角)包含一只狗,一只猫和一只鹦鹉
  • 第三张图片(左下角)包含一只兔子和一只鹦鹉,和
  • 最后一张图片(右下角)包含一只狗和一只鹦鹉

这些都是给定图像的标签。 这里的每个图像都属于多个类,因此它是一个多标签图像分类问题

这两个场景应该可以帮助您了解多类和多标签图像分类之间的区别。 如果您需要进一步说明,请在本文下方的评论部分与我联系。

Before we jump into the next section, I recommend going through this article Build your First Image Classification Model in just 10 Minutes!.. It will help you understand how to solve a multi-class image classification problem.

Steps to Build your Multi-Label Image Classification Model

既然我们对多标签图像分类有直觉,那么让我们深入探讨解决此类问题应遵循的步骤。

第一步是以结构化格式获取数据这适用于二进制和多类图像分类。

您应该有一个文件夹,其中包含您要训练模型的所有图像。 现在,为了训练这个模型,我们还需要真正的图像标签。 因此,您还应该有一个.csv文件,其中包含所有训练图像的名称及其对应的真实标签。

我们将在本文后面学习如何创建此.csv文件。 现在,请记住,数据应采用特定格式。 数据准备好后,我们可以将进一步的步骤划分如下:

Load and pre-process the data

首先,加载所有图像,然后根据项目的要求对其进行预处理。 为了检查我们的模型将如何对看不见的数据(测试数据)执行,我们创建一个验证集。 我们在训练集上训练我们的模型并使用验证集(标准机器学习实践)对其进行验证。

Define the model’s architecture

下一步是定义模型的体系结构。 这包括确定隐藏层的数量,每层中的神经元数量,激活功能等。

Train the model

是时候在训练集上训练我们的模型了! 我们传递训练图像及其相应的真实标签来训练模型。 我们还在此处传递验证图像,这有助于我们验证模型在看不见的数据上的表现。

Make predictions

最后,我们使用训练的模型来预测新图像。

Understanding the Multi-Label Image Classification Model Architecture

现在,多标签图像分类任务的预处理步骤将类似于多类问题的预处理步骤。 关键区别在于我们定义模型架构的步骤。

我们在输出层使用softmax激活函数,用于多类图像分类模型。对于每个图像,我们希望最大化单个类的概率。随着一个类的概率增加,另一个类的概率减小。所以,我们可以说每个类的概率取决于其他类。

但是在多标签图像分类的情况下,我们可以为单个图像设置多个标签。我们希望概率彼此独立。使用softmax激活功能将不合适。相反,我们可以使用sigmoid激活函数。这将独立预测每个班级的概率。它将在内部创建n个模型(这里是n的总类数),每个类一个并预测每个类的概率。

使用sigmoid激活函数会将多标签问题转化为n - 二元分类问题。因此,对于每个图像,我们将获得定义图像是否属于第1类的概率,依此类推。由于我们已将其转换为n - 二元分类问题,因此我们将使用binary_crossentropy损失。 我们的目标是尽量减少这种损失,以提高模型的性能。

这是我们在定义用于解决多标签图像分类问题的模型体系结构时必须进行的主要更改。培训部分将类似于多类问题。我们将传递训练图像及其相应的真实标签以及验证集来验证我们模型的性能。

最后,我们将拍摄一张新图像并使用训练过的模型来预测该图像的标签。和我一起到目前为止?

Case Study: Solving a Multi-Label Image Classification Problem

恭喜你到目前为止! 您的奖励 - 在Python中解决一个令人敬畏的多标签图像分类问题。 那是正确的 - 给你最喜欢的Python IDE加电!

让我们设置问题陈述。 我们的目标是仅使用其海报图像来预测电影的类型。 你能猜到为什么它是一个多标签的图像分类问题吗? 在你看下面之前想一想。

一部电影可以属于多种类型,对吧? 它不仅仅属于一个类别,如动作或喜剧。 电影可以是两种或更多种类型的组合。 因此,多标签图像分类。

我们将使用的数据集包含几个多类型电影的海报图像。 我在数据集中做了一些更改并将其转换为结构化格式,即包含图像的文件夹和用于真实标签的.csv文件。 您可以从此处下载结构化数据集。 以下是我们数据集中的一些海报:

在这里插入图片描述

如果您愿意,可以在此处下载原始数据集以及地面实况值。

我们来编码吧!

首先,导入所有必需的Python库:

import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.utils import to_categorical
from keras.preprocessing import image
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from tqdm import tqdm
%matplotlib inline

Now, read the .csv file and look at the first five rows:

train = pd.read_csv('multi_label_train.csv')    # reading the csv file
train.head()      # printing first five rows of the file

在这里插入图片描述
此文件中有27列。 让我们打印这些列的名称:

train.columns

在这里插入图片描述

流派列包含每个图像的列表,用于指定该电影的类型。 因此,从.csv文件的头部开始,第一个图像的类型是喜剧和戏剧。

其余25列是单热编码列。 因此,如果一部电影属于动作类型,其值将为1,否则为0.该图像可以属于25种不同的类型。

我们将构建一个将返回给定电影海报类型的模型。 但在此之前,您还记得构建任何图像分类模型的第一步吗?

那是对的 - 加载和预处理数据。 那么,让我们读一下所有的训练图像:

train_image = []
for i in tqdm(range(train.shape[0])):
    img = image.load_img('Multi_Label_dataset/Images/'+train['Id'][i]+'.jpg',target_size=(400,400,3))
    img = image.img_to_array(img)
    img = img/255
    train_image.append(img)
X = np.array(train_image)

快速浏览一下数组的形状:

X.shape

在这里插入图片描述
共有7254个海报图像,所有图像都已转换为(400,300,3)形状。 让我们绘制并可视化其中一个图像:

plt.imshow(X[2])

在这里插入图片描述
这是电影“交易场所”的海报。 我们还打印这部电影的类型:


train['Genre'][2]

在这里插入图片描述

这部电影有一个类型 - 喜剧。 我们的模型需要的下一件事是所有这些图像的真实标签。 你能猜出7254图像真实标签的形状是什么吗?

让我们来看看。 我们知道总共有25种可能的类型。 对于每个图像,我们将有25个目标,即电影是否属于该类型。 因此,所有这25个目标的值都为0或1。

我们将从列车文件中删除Id和流派列,并将剩余的列转换为将成为我们图像目标的数组:

y = np.array(train.drop(['Id', 'Genre'],axis=1))
y.shape

输出数组的形状是(7254,25),正如我们预期的那样。 现在,让我们创建一个验证集,它将帮助我们检查模型在看不见的数据上的性能。 我们将随机分离10%的图像作为我们的验证集:

X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42, test_size=0.1)

下一步是定义模型的架构。 输出层将有25个神经元(等于类型的数量),我们将使用sigmoid作为激活函数。

我将使用某种架构(如下所示)来解决这个问题。 您也可以通过更改隐藏层数,激活函数和其他超参数来修改此体系结构。

model = Sequential()
model.add(Conv2D(filters=16, kernel_size=(5, 5), activation="relu", input_shape=(400,400,3)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(filters=32, kernel_size=(5, 5), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(filters=64, kernel_size=(5, 5), activation="relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(filters=64, kernel_size=(5, 5), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(25, activation='sigmoid'))

让我们打印我们的模型摘要:

model.summary()


Quite a lot of parameters to learn! Now, compile the model. I’ll use binary_crossentropy as the loss function and ADAM as the optimizer (again, you can use other optimizers as well):

model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

Finally, we are at the most interesting part – training the model. We will train the model for 10 epochs and also pass the validation data which we created earlier in order to validate the model’s performance:

model.fit(X_train, y_train, epochs=10, validation_data=(X_test, y_test), batch_size=64)


我们可以看到培训损失已降至0.24,验证损失也同步。 下一步是什么? 是时候做出预测了!

所有权力的游戏(GoT)和复仇者联盟的粉丝 - 这一个适合你。 让我们为GoT和Avengers拍摄海报,并将它们提供给我们的模型。 在继续之前下载GOT和Avengers的海报。

在进行预测之前,我们需要使用前面看到的相同步骤预处理这些图像。

img = image.load_img('GOT.jpg',target_size=(400,400,3))
img = image.img_to_array(img)
img = img/255

现在,我们将使用我们训练有素的模型预测这些海报的类型。 该模型将告诉我们每种类型的概率,我们将从中获得前3个预测。

classes = np.array(train.columns[2:])
proba = model.predict(img.reshape(1,400,400,3))
top_3 = np.argsort(proba[0])[:-4:-1]
for i in range(3):
    print("{}".format(classes[top_3[i]])+" ({:.3})".format(proba[0][top_3[i]]))
plt.imshow(img)


令人印象深刻! 我们的模型为权力的游戏提供了戏剧,惊悚和动作类型。 在我看来,这很好地归功于GoT。 让我们在复仇者海报上试试我们的模型吧。 预处理图像:

然后做出预测:

classes = np.array(train.columns[2:])
proba = model.predict(img.reshape(1,400,400,3))
top_3 = np.argsort(proba[0])[:-4:-1]
for i in range(3):
    print("{}".format(classes[top_3[i]])+" ({:.3})".format(proba[0][top_3[i]]))
plt.imshow(img)


我们的模型提出的类型是戏剧,动作和惊悚。 同样,这些都是非常准确的结果。 宝莱坞电影的模特表现同样出色吗? 我们来看看。 我们将使用这张Golmal 3海报。

你知道在这个阶段该做什么 - 加载和预处理图像:

img = image.load_img('golmal.jpeg',target_size=(400,400,3))
img = image.img_to_array(img)
img = img/255

然后预测这张海报的类型:

classes = np.array(train.columns[2:])
proba = model.predict(img.reshape(1,400,400,3))
top_3 = np.argsort(proba[0])[:-4:-1]
for i in range(3):
    print("{}".format(classes[top_3[i]])+" ({:.3})".format(proba[0][top_3[i]]))
plt.imshow(img)

Golmaal 3是一部喜剧,我们的模特已经预测它是最顶级的类型。 其他预测类型是戏剧和浪漫 - 一个相对准确的评估。 我们可以看到该模型只能通过查看他们的海报来预测类型。

Next Steps and Experimenting on your own

这就是我们如何解决多标签图像分类问题。 尽管我们只有大约7000张图像用于训练,但我们的模型表现非常好。

您可以尝试收集更多海报进行培训。 我的建议是以这样的方式制作数据集,使所有类型的类别具有相对平等的分布。 为什么?

好吧,如果某个类型在大多数训练图像中重复出现,我们的模型可能会过度适应该类型。 对于每个新图像,模型可能会预测相同的类型。 要克服这个问题,你应该尝试平等分配类型类别。

这些是您可以尝试提高模型性能的一些关键点。 还有其他你能想到的吗? 让我知道!

End Notes

除了流派预测之外,还存在多标签图像分类的多种应用。 例如,您可以使用此技术自动标记图像。 假设您要预测图像中服装项目的类型和颜色。 您可以构建一个多标签图像分类模型,它可以帮助您预测两者!

我希望这篇文章能帮助您理解多标签图像分类的概念。 如果您有任何反馈或建议,请随时在下面的评论部分分享。 快乐的实验!

original by PULKIT SHARMA
translated by Adam 坤

猜你喜欢

转载自blog.csdn.net/weixin_41697507/article/details/89390675
今日推荐