手把手教你用Python构建你的第一个多标签图像分类模型(附案例)

本文明确了多标签图像分类的概念,并讲解了如何构建多标签图像分类模型。html

介绍

你正在处理图像数据吗?咱们可使用计算机视觉算法来作不少事情:算法

  • 对象检测
  • 图像分割
  • 图像翻译
  • 对象跟踪(实时),还有更多……

这让我思考——若是一个图像中有多个对象类别,咱们该怎么办?制做一个图像分类模型是一个很好的开始,但我想扩展个人视野以承担一个更具挑战性的任务—构建一个多标签图像分类模型!编程

制做一个图像分类模型数组

www.analyticsvidhya.com/blog/2019/0…架构

我不想使用简单玩具数据集来构建个人模型—这太普通了。而后,它打动了我—包含各类各样的人的电影/电视剧海报。我能够仅经过看海报就能来构建我本身的多标签图像分类模型来预测不一样的流派吗?app

image.png

答案很简单——是的!在本文中,我解释了多标签图像分类背后的思想。咱们将使用电影海报构建咱们本身的模型。你将会对咱们的模型产生的使人印象深入的结果感到惊讶。若是你是《复仇者联盟》或《权力的游戏》的粉丝,那么在实现部分会有一个很棒的惊喜(无剧透的)给你。dom

激动吗?很好,咱们开始吧!机器学习

目录

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

6.接下来的步骤和你的实验;函数

7.尾记。性能

1. 什么是多标签图像分类?

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

image.png

图1中的对象是一辆汽车。这是显而易见的。然而,在图2中没有汽车,只有一组建筑物。你能看出咱们要怎么作吗?咱们将图像分为两类,即,有车仍是没车。

当咱们只有两类图像能够分类时,这就称为二值图像分类问题。

让咱们再看一个图片:

image.png

在这个图片中,你识别出了多少个物体?有太多了——房子、带喷泉的池塘、树木、岩石等等。因此,当咱们能够将一个图像分类为多个类(如上图所示)时,就称为多标签图像分类问题。

如今,这里有一个问题——咱们大多数人对多标签和多类图像分类感到困惑。当我第一次遇到这些术语时,我也被迷惑了。如今我对这两个主题有了更好的理解,让我来为大家澄清一下区别。

2. 多标签图像分类与多类图像分类有何不一样?

假设给咱们一些动物的图片,让咱们把它们分红相应的类别。为了便于理解,咱们假设一个给定的图像能够分为4类(猫、狗、兔子和鹦鹉)。如今,可能有两种状况:

  • 每一个图像只包含一个对象(上述4个类别中的任何一个),所以,它只能被纳入4个类别中的一个。
  • 图像可能包含多个对象(来自上述4个类别),所以该图像将属于多个类别。

让咱们经过例子来了解每种状况,从第一个场景开始:

image.png

这里,咱们的每一个图像都只包含一个对象。敏锐的你会注意到在这个集合中有4种不一样类型的对象(动物)。

这里的每张图片只能被分类为猫、狗、鹦鹉或兔子。没有任何一个图像属于多个类别的状况。

  • 当图像可分类的类别超过两种时
  • 一个图像不属于一个以上的类别

若是知足上述两个条件,则称为多类图像分类问题。

如今,让咱们思考第二种状况 —— 看看下面的图像:

image.png

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

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

这两种状况应该有助于你理解多类和多标签图像分类之间的区别。若是你须要进一步的说明,请在本文下面的评论部分与我联系。

在进入下一节以前,我建议你通读这篇文章——在10分钟内构建你的第一个图像分类模型!它将帮助你了解如何解决一个多类图像分类问题。

在10分钟内构建你的第一个图像分类模型:

www.analyticsvidhya.com/blog/2019/0…

3. 构建多标签图像分类模型的步骤

如今咱们已经对多标签图像分类有了一个直观的认识,让咱们深刻讨论解决这个问题应该遵循的步骤。

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

你应该有一个文件夹,其中包含您想要训练模型的全部图像。如今,为了训练这个模型,咱们还须要图像的真实标签。所以,你还应该有一个.csv文件,其中包含全部训练图像的名称及其对应的真实标签。

咱们将在本文后面学习如何建立这个.csv文件。如今,只要记住数据应该是一种特定的格式。数据准备好后,咱们能够将进一步的步骤划分以下:

加载和预处理数据

首先,加载全部图像,而后根据项目的需求对它们进行预处理。为了检查咱们的模型将如何对不可见的数据(测试数据)执行,咱们建立了一个验证集。咱们在训练集上训练咱们的模型并使用验证集对其进行验证(标准的机器学习方法)。

定义模型的结构

下一步是定义模型的结构。这包括决定隐藏层的数量、每层神经元的数量、激活函数等等。

训练模型

是时候在训练集上训练咱们的模型了!咱们输入训练图像及其对应的真标签对模型进行训练。咱们还在这里传入验证图像,以帮助咱们验证模型在不可见数据上的性能。

做出预测

最后,咱们使用训练过的模型对新图像进行预测。

4. 了解多标签图像分类模型结构

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

对于多类图像分类模型,咱们在输出层使用softmax激活函数。对于每一个图像,咱们想要最大化单个类的几率。当一个类的几率增大时,另外一个类的几率就减少。因此,咱们能够说每一个类的几率都依赖于其余类。

可是在多标签图像分类的状况下,单个图像能够有多个标签。咱们但愿几率彼此独立。使用softmax激活函数并不合适。相反,咱们可使用sigmoid激活函数。这将独立地预测每一个类的几率。它将在内部建立n个模型(这里的n是总类数),每一个类一个模型,并预测每一个类的几率。

利用sigmoid激活函数将多标签问题转化为n-二分类问题。所以对于每幅图像,咱们将获得几率来肯定图像是否属于第一类,以此类推。因为咱们已经将其转换为一个n-二分类问题,咱们将使用binary_cross-sentropy损失。咱们的目标是尽可能减小这种损失,以提升模型的性能。

这是咱们在定义用于解决多标签图像分类问题的模型结构时必须作的主要更改。训练部分将相似于一个多类问题。咱们将传入训练图像及其对应的真实标签,以及验证集来验证模型的性能。

最后,咱们将获取一张新的图像,并使用训练过的模型来预测该图像的标签。还跟得上吗?

5. 案例研究:用Python解决多标签图像分类问题

祝贺你来到这一步!你的奖励——用Python解决一个可怕的多标签图像分类问题。是时候启动你最喜欢的Python IDE了!

让咱们明确问题陈述。咱们的目标是经过电影的海报图像来预测电影的类型。你能猜到为何这是一个多标签图像分类问题吗?在你往下看以前想一下。

一部电影能够属于多种类型,对吧?它不只仅属于一个类别,如动做片或喜剧片。电影能够是两种或多种类型的结合。所以,它是多标签图像分类。

咱们将使用的数据集包含多个多类型电影的海报图像。我对数据集作了一些更改,并将其转换为结构化格式,即一个包含图像的文件夹和一个存储真正标签的.csv文件。你能够从这里下载结构化数据集。下面是一些来自咱们数据集的海报:

这里

drive.google.com/file/d/1dNa…

image.png

若是你愿意,能够在这里下载原始数据集和基准真值。

这里

www.cs.ccu.edu.tw/~wtchu/proj…

让咱们开始编程!

首先,导入全部须要的Python库:

  1. import keras
  2. from keras.models import Sequential
  3. from keras.layers import Dense, Dropout, Flatten
  4. from keras.layers import Conv2D, MaxPooling2D
  5. from keras.utils import to_categorical
  6. from keras.preprocessing import image
  7. import numpy as np
  8. import pandas as pd
  9. import matplotlib.pyplot as plt
  10. from sklearn.model_selection import train_test_split
  11. from tqdm import tqdm
  12. %matplotlib inline

如今,读取.csv文件并查看前五行的内容:

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

image.png

这个文件中有27列。 让咱们输出这些列的名字看看:

  1. train.columns

image.png

Genre列包含每一个图像的列表,其中明确了每一个图像对应的电影的类型。所以,从.csv文件的头部开始,第一个图像的类型是喜剧和戏剧。

剩下的25列是独热码列。所以,若是一部电影属于动做类型,它的值将为1,不然为0。每一个图像能够属于25种不一样的类型。

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

没错——就是正确的加载和预处理数据。因此,让咱们看看全部的训练图片:

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

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

  1. X.shape

image.png

这里共有7254个海报图像,全部图像都已转换为(400,300,3)的形状。 让咱们绘制并可视化其中一个图像:

  1. plt.imshow(X[2])

image.png

这是电影《交易场所》的海报。让咱们输出这部电影的类型:

  1. train'Genre'

image.png

这部电影仅有一个类型——喜剧。咱们的模型所需的下一步是全部图像的真实标签。你能猜出这7254个图像真实标签的形状是什么吗?

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

咱们将从训练文件中删除Id和Genre列,并将剩余的列转换为将成为咱们图像目标的数组:

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

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

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

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

我将使用某一结构(以下所示)来解决这个问题。 你也能够经过更改隐藏层数,激活函数和其余超参数来修改此架构。

  1. model = Sequential()
  2. model.add(Conv2D(filters=16, kernel_size=(5, 5), activation="relu", input_shape=(400,400,3)))
  3. model.add(MaxPooling2D(pool_size=(2, 2)))
  4. model.add(Dropout(0.25))
  5. model.add(Conv2D(filters=32, kernel_size=(5, 5), activation='relu'))
  6. model.add(MaxPooling2D(pool_size=(2, 2)))
  7. model.add(Dropout(0.25))
  8. model.add(Conv2D(filters=64, kernel_size=(5, 5), activation="relu"))
  9. model.add(MaxPooling2D(pool_size=(2, 2)))
  10. model.add(Dropout(0.25))
  11. model.add(Conv2D(filters=64, kernel_size=(5, 5), activation='relu'))
  12. model.add(MaxPooling2D(pool_size=(2, 2)))
  13. model.add(Dropout(0.25))
  14. model.add(Flatten())
  15. model.add(Dense(128, activation='relu'))
  16. model.add(Dropout(0.5))
  17. model.add(Dense(64, activation='relu'))
  18. model.add(Dropout(0.5))
  19. model.add(Dense(25, activation='sigmoid'))

让咱们显示咱们的模型总结:

  1. model.summary()

image.png

有至关多的参数要学习! 如今,编译模型。 我将使用binary_crossentropy做为损失函数,使用ADAM做为优化器(一样,你也可使用其余优化器):

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

最后,咱们最有趣的部分——训练模型。咱们将训练模型10个循环,并传入咱们以前建立的验证数据,以验证模型的性能:

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

image.png

咱们能够看到训练损失已降至0.24,验证损失也下降了。 下一步是什么? 是时候作预测了!

全部《权力的游戏(GoT)》和《复仇者联盟(Avengers)》的粉丝——这是给大家的礼物。 让我获取GoT和Avengers的海报,并将它们提供给咱们的模型。 在继续以前下载GOT和Avengers的海报。

GOT

drive.google.com/file/d/1cfI…

Avengers

drive.google.com/file/d/1buN…

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

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

如今,咱们将使用咱们训练好的模型预测这些海报的类型。该模型将告诉咱们每种类型的几率,咱们将从中得到前3个预测结果。

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

image.png

真棒!咱们的模型为《权力的游戏》预测了戏剧,惊悚和动做类型。在我看来,这个分类很好。让咱们在《复仇者联盟》海报上试试咱们的模型。图像预处理:

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

而后作预测:

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

image.png

咱们的模型给出的类型是戏剧、动做和惊悚。一样,这些都是很是准确的结果。这个模型能在好莱坞电影分类上表现的同样优秀吗?让咱们来看看。咱们将使用这张Golmal 3的海报。

image.png

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

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

而后为这个海报预测电影类型:

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

image.png

《Golmaal 3》是一部喜剧,咱们的模型预测它为最受欢迎的类型。其余预测类型是剧情片和浪漫片——相对准确的评估。咱们能够看到该模型可以仅经过海报预测电影类型。

6. 接下来的步骤和你本身的实验

这就是如何解决多标签图像分类问题。尽管咱们只有大约7000张图片来训练模型,但咱们的模型表现得很是好。

你能够尝试收集更多的训练海报。个人建议是使全部的流派类别有相对平等的分布的数据集。为何?

若是某一类型在大多数训练图像中重复出现,那么咱们的模型可能会与该类型过分匹配。对于每一张新图片,该模型均可能预测出相同的类型。为了克服这个问题,你应该尝试均衡的流派类别分布。

这些是你能够尝试改进模型性能的一些关键点。你还能想到别的吗?告诉我!

7. 尾记

除了流派类型预测外,多标签图像分类还有多种应用。例如,你可使用此技术自动标记图像。假设你想预测图像中服装的类型和颜色。你能够创建一个多标签图像分类模型,这将帮助你预测同时二者!


文章来自阿里云开发者社区

原文连接:developer.aliyun.com/article/715…

相关文章
相关标签/搜索