智客公社

标题: Python中的图像识别初体验:我拿童年马里奥/瓦里奥试试手 [打印本页]

作者: 叶婉莹a    时间: 2022-6-30 19:11
标题: Python中的图像识别初体验:我拿童年马里奥/瓦里奥试试手

点击上方关注,All in AI中国

从我的学前时代开始,我记得花了很多时间在我最喜欢的Game Boy(Game Boy家系是任天堂发售的掌上游戏机家系)上玩游戏。我最喜欢的两个平台游戏是Mario(马里奥)和Wario(瓦里奥)。我记得当我的祖母看了我正在玩的游戏时,问我这是什么。我解释说这是超级马里奥。一段时间后,当她看到我再次播放时,她看着屏幕说道:“马里奥又来了?这场比赛有多长时间?”但实际上,这是一场完全不同的比赛,是瓦里奥。这段记忆激发了我对图像识别的尝试,并试着看看我是否可以训练出一个能够准确识别一些截图的分类器。

[attach]754403[/attach]

在本文中,我使用两种方法。基本的是逻辑回归,而更高级的是卷积神经网络(使用tensorflow后端和Keras)。我不会特别解释算法背后的逻辑或数学,因为在这方面已经有大量的文章。相反,我将展示如何把一个简单、随机的想法快速转换为数据科学项目。

为了简洁起见,会只发布一些代码片段。文末放上全部的代码内容。

数据准备

根据我童年的记忆,我为这个实验选择了两个游戏:《超级马里奥大陆2-6金币》和《超级马里奥大陆3-瓦里奥大陆》我选择这些游戏,是因为它们当时是我的最爱,也是在检查时发现游戏的图像在视觉上非常相似,这会使任务更难!

我想知道从这些游戏中获取大量屏幕截图的最佳方式是什么,于是决定从Youtube上播放的视频中“抓取”它们。 Python的pytube库可以帮助完成这项任务,我可以毫不费力地用几行代码就下载整个视频。

[attach]754404[/attach]

下一步是从视频中剪切帧。为此,我迭代所有帧(使用OpenCV库)并只将第n帧保存到指定的文件夹。并决定使用10k图像(每场5k)。在这两种方法中,我将使用80-20的相同训练测试分组来确保可比性。

[attach]754405[/attach]

在抓取帧时,会跳过视频的前60秒,其中主要包含开场序列和菜单(我不会在视频结尾处这样做,因此可能会包含一些噪音,但我们会看到!)

[attach]754406[/attach]

来自马里奥的示例图像

[attach]754407[/attach]

来自瓦里奥的示例图像

在查看预览之后,很明显图像的大小不同。这就是我将它们重新缩放为64x64像素的原因。此外,对于逻辑回归,我将图像转换为灰度以减少模型的特征数量(CNN将处理3个颜色通道)。

[attach]754408[/attach]

用于逻辑回归的64x64灰度图像

逻辑回归

我将从更简单的模型开始,逻辑回归是基本二元分类器之一,即,使用一组预测器,它分配两个类中的一个。

话虽如此,要使用逻辑回归来解决图像分类问题,首先需要准备数据。输入应与Scikit-Learn中的其他模型完全相同,即特征矩阵X和标签y。

由于本文的目的是展示如何为特定问题构建图像分类器,因此我不专注于调整算法并使用逻辑回归的默认设置。直接跳到结果!

[attach]754409[/attach]

逻辑回归的混淆矩阵对测试集的预测

上面我在测试集上显示结果,因此模型不能用于训练的部分数据(20%的数据)。这看起来非常棒,实际上可能有点太好了。让我们来检查一些正确、错误分类图像的情况。

[attach]754410[/attach]

正确的图像分类

[attach]754411[/attach]

错误分类的图像

5个图像中有4个错误分类的逻辑非常明显。这些是一些过渡屏幕,模型实际上无法做任何事情。第二个屏幕来自超级马里奥的水平地图,它与游戏的其他部分明显不同(这里不是平台游戏)。但是,我们还可以看到模型正确地分类了另一个地图(图像3来自正确分类的图像)。

卷积神经网络

这部分显然比逻辑回归更复杂一些。第一步涉及以特定方式存储图像,因此Keras可以做到这一点:

[attach]754412[/attach]

此目录树显示了我如何为此特定项目构建文件夹和文件。下一部分是数据增强。我们的想法是对可用图像应用一些随机变换,以使网络能够看到更多用于训练的独特图像。这应该可以防止过度拟合并导致更好的泛化。我只使用了一些转换:

在指定图像的路径时,我还确定了要提供给神经网络的图像的大小(64x64,与逻辑回归相同)。

[attach]754413[/attach]

下面我展示了应用一些变换后的图像示例,我们看到了图像在两侧伸展。

[attach]754414[/attach]

现在是定义CNN的时候了。首先,初始化3个卷积层,在第一个中,还需要指定输入图像的形状(64x64,3个RGB通道)。之后,Keras自动处理大小,对于所有这些都使用ReLU(整流线性单元)激活功能。

卷积层变平后。由于最后两层基本上是常规ANN分类器,需要将卷积层中的数据转换为1D向量。在两个密集层之间,我也使用了drop,简而言之,在训练期间,drop忽略了指定数量的神经元(随机选择)。这是一种防止过度拟合的方法。最后一个密集层使用sigmoid激活函数,并返回给定观察属于其中一个类的概率。最后一步基本上是逻辑回归的作用。

[attach]754415[/attach]

现在是时候运行CNN了(这可能需要一段时间......)。我使用ADAM作为优化器,选择二进制交叉熵作为此二进制分类任务的损失函数,并使用准确度来评估结果(不需要使用不同的度量,因为在这种特殊情况下,准确性是我感兴趣的部分)。

[attach]754416[/attach]

那么神经网络是如何运作的呢?让我们来看看!

[attach]754417[/attach]

CNN对测试集的预测的混淆矩阵

嗯,准确性低于逻辑回归的情况,但对于这种快速构建的模型来说仍然非常好。可以通过改变卷积/密集层的数量,改变drop,对图像执行额外的转换等来微调网络。也可能是转换隐藏了图像中的一些数据(例如图像底部的摘要栏)。实际上,我最初怀疑这个栏可能在识别图像方面发挥重要作用,因为它几乎存在于所有截图中,并且两个游戏之间略有不同。

现在是时候检查一些正确/错误分类的图像的例子了。乍一看不同的是,在这种情况下,没有像屏幕转换这样明显的错误分类示例。

[attach]754418[/attach]

正确分类的图像

[attach]754419[/attach]

错误分类的图像

用LIME解释分类

作为奖励,我尝试用LIME(Local Interpretable Model-Agnostic Explanations)解释CNN的图像分类。与模型无关意味着LIME可以应用于任何机器学习模型。它基于修改单个观察的特征值并观察对预测的影响的想法。

[attach]754420[/attach]

下面我展示了对图像应用LIME解释的结果。绿色区域表示对预测类别的积极影响,红色为负。从正确分类的案例中我们看到角色总是在绿色区域,这符合逻辑。但是,对于不正确的否定情况,一些图像上只有一种颜色。这提供了一些见解,但我认为可以通过额外的修补从LIME解释中提取更多信息。

[attach]754421[/attach]

正确分类图像的LIME说明

[attach]754422[/attach]

LIME对错误分类图像的解释

结论

在本文中,我介绍了如何快速将随机想法转换为图像分类项目。两种被考虑过的方法在数据集上都表现良好,我相信CNN可以在一些调整后获得更好的分数。

还有一些进一步改进的想法:

附上全部的代码地址:https://github.com/erykml/mario_vs_wario

作者:Eryk Lewinson

[attach]754423[/attach]

翻译出品
作者: xfsky2012    时间: 2022-7-1 07:01
小白一个 顶一下
作者: xuanfengko    时间: 2022-7-3 18:38
我觉得不错,太厉害了




欢迎光临 智客公社 (http://bbs.cnaiplus.com/) Powered by Discuz! X3.4