找回密码
 立即注册
搜索

Python中的图像识别初体验:我拿童年马里奥/瓦里奥试试手


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

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



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

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

数据准备

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

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



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



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



来自马里奥的示例图像



来自瓦里奥的示例图像

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



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

逻辑回归

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

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

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



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

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



正确的图像分类



错误分类的图像

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

卷积神经网络

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



此目录树显示了我如何为此特定项目构建文件夹和文件。下一部分是数据增强。我们的想法是对可用图像应用一些随机变换,以使网络能够看到更多用于训练的独特图像。这应该可以防止过度拟合并导致更好的泛化。我只使用了一些转换:
    rescale - 在任何其他处理之前将数据相乘,原始图像由0-255范围内的RGB系数组成。这些值对于模型来说可能太高(具有典型的学习速率),因此乘以因子1/255会将变量重新调整为0-1范围shear_range - 用于随机应用剪切变换zoom_range - 用于随机缩放图片内部horizo​​ntal_flip - 用于水平地随机翻转一半图像(当没有水平不对称假设时,例如真实世界的图片)。我决定不使用此功能,因为在视频游戏截图的情况下这没有意义(数字等)

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



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



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

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



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



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



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

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

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



正确分类的图像



错误分类的图像

用LIME解释分类

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



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



正确分类图像的LIME说明



LIME对错误分类图像的解释

结论

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

还有一些进一步改进的想法:
    添加更多游戏来研究模型在多级环境中的表现不同的数据准备方法 - 我可以通过从当前图像的中间切割它们来拍摄更大的图像(128x128,因为两个视频都具有更大的分辨率)。这也可以解决底部汇总栏的潜在问题。在CNN的数据生成步骤中添加额外的图像变换尝试在图像中检测马里奥/瓦里奥(物体检测问题)

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

作者:Eryk Lewinson



翻译出品

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

大神点评2

xfsky2012 2022-7-1 07:01:18 显示全部楼层
小白一个 顶一下
回复

使用道具 举报

xuanfengko 2022-7-3 18:38:24 来自手机 显示全部楼层
我觉得不错,太厉害了
回复

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies