32

作为一项自我开发练习,我想开发一个简单的分类算法,给定呆伯特卡通的特定单元格,它能够识别卡通中存在哪些角色(呆伯特、PHB、Ratbert 等)。

我认为最好的方法是(1)对图像应用一些算法,将其转换为一组特征,(2)使用训练集和许多可能的机器学习算法之一来关联存在/单元格中不存在具有特定特征的某些特征。

所以我的问题是——(a)这是正确的方法吗,(b)因为有许多分类算法和机器学习算法需要测试,什么是找到正确方法的好方法,以及(c)你会开始使用哪些算法考虑到我们实际上是在对卡通进行分类练习。

4

4 回答 4

25

因此,我认为您在第 1 步中走在正确的轨道上(将一些算法应用于图像,将其转换为一组特征)

这个项目比大多数 ML 问题更具挑战性,因为在这里您实际上必须从原始数据(组成卡通的各个帧)创建训练数据集。例如,抓取一个帧,识别该帧中的两个字符,呆伯特和有角的字符(我相信呆伯特的老板,不知道他的名字),从该帧中提取这两个字符并附加到每个适当的类标签(例如,“1”代表 Dlibert)。

第1步

为了从构成呆伯特卡通的每个帧中提取单个字符,我建议对每个帧进行光谱分解。如果您不熟悉这种技术,那么它的核心就是一个特征向量分解。

如果您喜欢 python(或 R,因为您可以使用RPy之类的 python-to-R 绑定),那么我强烈建议您查看sklearn。特别是这个优秀的库(最初是在SciPy scikits项目保护伞下开发的,因此使用 NumPy + SciPy 进行矩阵计算)具有多种图像分割算法,其中一种是基于光谱聚类的算法。对于您项目中的这一步,您很可能希望查看这两个 scikits.learn 模块

  • sklearn.feature_extraction(尤其是图像子模块)

  • sklearn.cluster.spectral_clustering

这两个模块包括两个很好的示例脚本,一个分割数码照片另一个分割由三个部分叠加的圆圈组成的图像,彼此之间的对比度最小,背景为 w/r/t——我怀疑两者都是您需要执行的分解的更困难的问题。换句话说,sklearn有两个完整的、有据可查的示例脚本包含在源代码分发中,它们都处理与您的数据相似的数据。任何一个或两者都将是此步骤的绝佳模板。

第2步

这是第一步;这是第二个:将分解图像的所有组件分组,每个 Dilbert 字符一。接下来,为每个组分配一个类标签,例如,如果分解步骤中有四个字符,那么类标签的合适选择是“0”、“1”、“2”和“3”。将这些类标签附加到组件矩阵(步骤 1 中的分解产物),以便将每个字符矩阵映射到其对应的类(Dilbert 字符)。

第 3 步

选择合适的机器学习技术。这一步你有很多选择;唯一的标准是该技术属于受监督类别(因为您已为数据分配了类标签)并且它充当分类器(即,它返回类标签,而不是输出数值的回归器)。鉴于这是一个个人项目,我会选择你觉得最有趣的一个。满足我刚才提到的标准的一些是:多层感知器(神经网络)、支持向量机(SVM)和k 近邻(kNN)。

第4步

训练、验证和测试您的分类器

替代技术模板匹配

一旦步骤 1 完成(每个图像被分解成一组对象,其中一些无疑将代表角色),您可以手动筛选这些分解产物并为卡通中的每个角色收集样本。是模板

接下来,您将从图像中分割的对象与这组独特的模板进行比较。在scikit-image,另一个 scipy scikit 中,您可以使用方法match_template,您将模板图像和候选图像传递给该方法,并且此方法返回显示逐像素相关性的 2D 数组(在 -1 和 1 之间)。

于 2011-11-13T15:51:32.113 回答
2

我认为,总的来说,这是正确的方法,你可以看看两种技术。

  • Eigenfaces,所有使用特征向量进行面部识别的算法的名称。
  • 词袋或视觉词方法。
于 2011-11-13T10:47:06.443 回答
1

您可以尝试通过将训练数据(漫画图像)上传到demo.nanonets.ai(免费使用)来构建模型

然后使用以下(Python 代码)查询 API:

import requests
import json
import urllib
model_name = "Enter-Your-Model-Name-Here"
url = "http://static5.businessinsider.com/image/525464f969bedd0b0422cfb6/dilbert-creator-scott-adams-presents-his-10-favorite-comics-of-all-time.jpg"
files = {'uploadfile': urllib.urlopen(url).read()}
url = "http://demo.nanonets.ai/classify/?appId="+model_name
r = requests.post(url, files=files)
print json.loads(r.content)

响应如下:

{
  "message": "Model trained",
  "result": [
    {
      "label": "Dilbert",
      "probability": 0.97
    },
    {
      "label": "PHB",
      "probability": 0.025
    },
    {
      "label": "Ratbert",
      "probability": 0.005
    }
  ]
}
于 2016-12-13T11:08:24.150 回答
0

这个问题是 5 年前提出的,因此鉴于深度学习在过去 3-4 年中改变了计算机视觉的面貌,因此上面提供的答案已经过时。基于深度学习的解决方案将涉及训练卷积神经网络,该网络将学习特征并在端到端学习框架中执行分类。但是,由于同一图像中可能存在多个卡通,因此图像分类中使用的标准 softmax 交叉熵损失可能不合适。因此,应该使用独立的逻辑回归作为损失函数。每个类别的阈值可以基于在保留的验证集上获得的准确度来获得。即使对于卡通,最好使用使用 imagenet 初始化的预训练模型,而不是从头开始训练(https://arxiv.org/pdf/1611.05118v1.pdf,虽然本文的最终任务不同,但他们仍然对卡通进行处理)。如果你有丰富的数据,预训练可能没那么重要。可以使用标准库(如caffe / torch等)执行此任务。

于 2016-12-27T20:11:10.660 回答