看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

本文来自AI新媒体量子位(QbitAI)

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

 Who’s that Pokémon?

还记得去年异常火爆,然而最终也没能入华的Pokémon Go么?我们今天要讲的,就和《口袋妖怪》有关。

这一系列游戏是由任天堂发行的,官方名字叫精灵宝可梦,可以说是近20多年来世界上第二畅销的电子游戏(第一当然是超级马里奥),现在已经发行到第七世代,精灵数量也从第一代的151只增加到了802只。

玩家在游戏中扮演着精灵训练师的角色,捕捉精灵然后与它们并肩作战。

802只精灵不知道有没有人认得全,反正量子位编辑们只认识比卡丘等等最常见的,比如说初学者系列:

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

△ 图1:妙蛙种子、小火龙和杰尼龟(从左到右)

就算能认全802只也还没完。这些小精灵们,每只都具有一两种特殊的属性,来表明其“元素亲和力”,当它们对抗其他属性的精灵时都存在自己的优势及弱点。这种设定就像是复杂版的石头剪刀布,构成了战斗系统的基础,大大提高了游戏的趣味性(和记忆难度)。如下图所示,最新版本口袋妖怪共有18种属性:

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

△ 图2:18种口袋妖怪的属性,用它们常用背景颜色来进行区分

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

来个中文版

想不起来这只小精灵是什么属性,我会去求助精灵图鉴,不过一位认真好学的外国Geek想到了卷积神经网络。

他写了一篇博客文章,通过卷积神经网络ConvNets实现口袋妖怪中精灵属性的分类任务,该网络可通过某个精灵的图像来判断该游戏精灵的属性。

他在博客中详细介绍了数据集构建、预处理过程和训练步骤,以及分析所选模型的性能指标,同时在GitHub上公开了所有的数据,实现代码和分析结果。

在公众号会话界面回复“口袋妖怪”,我们会把英文版PDF、GitHub地址全部发给你。

以下内容译自博客
Journal of Geek Studies

数据预处理

数据集特征

为了训练网络模型,我在Veekun(https://veekun.com/)上获得了所有游戏精灵的数据集。这个数据集包括了游戏第一代到第五代出现的精灵。后来发布的第六、七代游戏中有新的精灵,但这些精灵使用了三维动画模型,从游戏中提取精灵图像比较困难,机器学习的方法不支持对这种格式进行训练。因此在本文中,我们将只使用Pokémon前五代所推出的649个精灵图像。

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

△ 图3:三只关都地区的初学者精灵,在历代游戏中的变化

我们可以看到,由于游戏机硬件和功能的不同,游戏中的原画精细程度不同。在任天堂的Game Boy游戏机里,第一代版本的每一个精灵几乎没有色调变化,但是数据集中提供了一些色调信息,如Bulbasaur是绿色的,Charmander是红色的,Squirtle是蓝色的。从Game Boy到Nintendo DS,我们发现随着版本的更新,小精灵的精细程度突飞猛进,不只色调有了变化,形状都不太一样了。

同时,我们遇到了图像分类任务中的一个典型问题,即图像具有不同的分辨率。虽然所有图像的长宽比都是1:1,但是请注意看上图中每个子画面上的边框刻度,在第一代游戏中,图像还是40像素宽,到第五代已经增加到96像素。

此外,所有精灵在每个图像中的所占空间也不尽相同。早期版本的精灵似乎填充了图像中的更大空间。在同一个版本中,随着精灵的进化,其大小也会发生相应的变化。

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

△ 图4:第五代游戏中,随着妙蛙种子进化成妙蛙草、妙蛙花,它的体型也在增大,占据图片空间的比例也随之增大

图像居中

当我们应用计算机视觉技术来识别图像中的主要对象,需要确定它的边界框,并将图像进行居中处理,其步骤是:

1. 将彩色图像转换成灰度图;

2. 用Sobel滤波器处理图像,突出精灵的轮廓。Sobel滤波器是一个3×3的卷积核,它能够通过图像的梯度,得到主体的轮廓坐标;

3. 填充图像中的空白,获得精灵的轮廓;

4. 计算轮廓中能够包含所有像素的最小面积;

5. 根据精灵轮廓确定方形边界框的大小;

6. 将方形边界框调整为64x64像素;

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

△ 图5:对小精灵图像居中处理的完整步骤

在执行上述步骤后,我们获得主体填充率最大化的精灵图像。这个过程是基于Python的图像处理库skimage来进行实现的。

针对精灵的居中处理,这种方法是非常有效的。因为我们要处理图片很简单,由精灵形象和白色背景构成。

最后,我们用这种方法处理了所有的精灵图像。

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

△ 图6:多个第五代精灵居中后的结果

目标变量

现在我们处理好了所有的精灵图像,来建立我们的图像数据集,接下来我们根据要预测的变量来对它们进行分类。在本文中,我们将仅使用其图像来判断出每个精灵的正确属性。在图7中,我们尝试使用边界框内的图像,将小精灵正确地分类到18个属性中的一种。

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

△ 图7:精灵及其对应属性
上行:妙蛙草(左)和波波(右)
下行:大钢蛇(左)和菊石兽(右)

但是仍然存在一个问题,大多数精灵具有双重属性,也就是说,一个精灵的正确属性是在18种属性中某两种不同属性的组合。例如在图7中,妙蛙草的属性是草和毒,同时具有两种属性的优点和弱点。

如果要解决这类情况,我们就需要对组合属性进行分类。即使我们忽视属性顺序,把[火 岩石]属性与[岩石 火]属性分为同一个类,除去不存在的组合,我们最终会得到154个可能的类。

更糟的是,如图8所示,一些组合是罕见的,只有一个或两个神奇宝贝,这样限制了可供学习的样本。

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

△ 图8:一些罕见的属性组合
上行:熔岩蜗牛(左)和溜溜糖球(右)
下行:花岩怪(左)和火钢兽(右)

由于上述原因,我决定忽略精灵的组合属性。因此,我们只考虑精灵的主要属性。以图7中的小精灵为例,我们将这样设置:

妙蛙草:草

波波:一般

大钢蛇:钢

菊石兽:岩石

模型训练

选择模型

我将通过卷积神经网络实现对数据集的预测。首先,我们来了解一下神经网络。

根据*的介绍,神经网络是一种常用的机器学习预测模型,本质上是由称为神经元的简单单位组成的互连网络。通过对生物系统内部运作的简单模拟,神经网络能够通过这些神经元来实现复杂的函数和模式。

神经元的最简单形式只是一个输入的线性函数,可以通过组合实现非线性激活函数,如下图:

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

△ 图9:神经网络的基本单元

然而,通过加深网络层数,神经网络能够在独立变量和因变量之间构建越来越复杂的对应关系,如下图:

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

△ 图10:一个稍微复杂的,具有一个隐藏层的神经网络结构

从1940年开始,就已经有学者研究神经网络,但是存在局部最优和计算量过大的问题,所以一直发展缓慢。近年来,随着计算性能的大大提高,以及反向传播算法的提出和发展,神经网络又再一次受到了大量学者的关注。

好的,我们已经比较了解神经网络了。但是“卷积”指的是什么呢?我们先来介绍一下内核。

在图像处理中,内核,也叫作卷积矩阵,是在模糊、锐化、边缘检测等任务中使用的小型矩阵。我们通过设定合适的内核进行矩阵的卷积运算,产生新的图像从而实现目的效果。在前边的步骤中,我们已经用过了一种内核:在数据预处理中用Sobel内核来检测精灵的边缘。

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

△ 图11:精灵妙蛙花在应用Sobel算子后的效果

卷积运算可以看作是卷积核在图像上的遍历。将内核的值按照逐个元素,乘以图像中的灰度值,并将结果相加即可得到该卷积的最终值。在应用中,我们可以使用垂直Sobel滤波器来检测颜色强度的明显变化。

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

△ 图12:应用垂直边缘滤波器对突出显示的红色区域进行卷积,从而在生成矩阵上获得红色最终值

但是这些卷积核与神经网络有什么关系?神经网络的卷积层实际上就是通过巧妙的方式来实现神经元之间的连接关系,进而实现一种分类器,其能够通过有监督学习来识别这些特殊的滤波器。在预处理步骤中,我们会使用一种特定结构的内核,因为我们了解何种结构的内核能够完成提取轮廓的任务。但在卷积神经网络中,我们会让训练算法自动找到特殊结构的滤波器,并能通过多级组合来表示越来越复杂的高级特征。

我们的神经网络结构

对于精灵分类任务,我使用了一个四层的卷积神经网络。

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

△ 图13:本文中精灵分类所用到的神经网络结构

上图中的每一层,都对应着卷积网络中的一个层。在每个层后,我们获得表示该层输出的状态张量,每个层的右侧写明了该张量维度。

然后,在卷积层通过卷积核进行卷积运算。在第一层,我们对输入图像应用32个维度为5的卷积核,产生了32个大小为60×60的输出矩阵。对图像应用卷积运算产生边界效应,造成输出矩阵维度减小。

我们还使用了最大池化层,通过对某个张量区域提取最大值,将其用单值代替。因此,在应用2×2最大池化操作后,我们得到新的张量,其大小只有原始张量的四分之一。

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

△ 图14:最大池化操作的示例

最后,我们将张量展开为一维向量,接以全连接层进行预测。最后一层的输出节点数为18,与精灵属性的个数相同。

训练和验证

为了训练精灵分类模型,我们将数据集划分为两个部分:

1)训练网络时将使用训练集,从数据中学习模型参数;

2)验证集用来验证所得到模型的预测性能。

这样,我们将能够通过正确率、测试误差来判断网络训练是否陷入过拟合。

但是我们不能通过随机划分来确定这两个数据集。因为在不同《口袋妖怪》游戏中,特别是在同一代的不同游戏之间,同一精灵的原画非常相似。

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

△ 图15:大比鸟在宝石版本(左)和钻石版本(右)里的原画。你能看出两者的区别吗?

如果对原始数据集进行随机划分,验证集和训练集中可能存在若干个样本几乎相同,这将导致对网络模型性能的高估。因此,我将整个精灵的全部图像集合都分配给同一个数据集,而不是将精灵图像随机划分。也就是说,如果喷火龙被分配给验证集,那么它的所有图像将被分在验证集,这样就可以消除了模型高估的问题。

我将20%的精灵作为测试集,80%的精灵作为训练集,也就是训练集中有2727个精灵样本。

性能指标

本文将使用三个性能指标来评估该模型的分类性能:

1)准确度(accuracy):在预测过程中,能对精灵属性正确分类的百分比;

2)精度(precision):真正属于该类的图像占所有归于该类图像的百分比;

3)召回率(recall):该类正确归类的图像占该类全部图像的百分比;

虽然准确性已经能够评估所训练模型的大体质量,但是精确度和记忆力帮助我们衡量模型对每个类具体的预测效果。

第一个模型:简单训练

第一次尝试时,在保持训练集和验证集互相独立的条件下,用原始精灵图像对神经网络进行训练。 该算法运行了20步,只用了大约一分钟,训练正确率已经全部达到了100%。第一次训练结果如下图所示。

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

△ 图16:第一个模型对训练集的分类性能

好激动,所有的精灵分类都是完全正确的!但是这些指标代表这个网络模型的预测性能吗?其实这些指标是在暗示我们,该模型已经完全拟合了训练集数据,但是不能很好地预测新数据。让我们来验证一下:下图展示了该模型对验证集的预测性能。

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

△ 图17:第一个模型对验证集的分类性能

虽然目前模型的分类效果优于随机猜测,但是网络确实存在过拟合问题。

奇怪的是,为什么飞行属性没有对应的精灵呢?事实上,只有精灵龙卷云是属于飞行属性的,但是它被划分到了训练集。

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

△ 图18:我们的数据集中,龙卷云是唯一的飞行属性精灵.

第二个模型:图像增强

在对验证集的预测上,第一个模型表现不佳。正如在介绍中提到的,计算机仍在努力解决图像分类的问题。我们的数据集存在数量太少和变化不多的问题,使得此算法训练得到的模型不具备特征泛化能力。

为了解决这个问题,我们应用了图像增强技术。我们通过对训练集图像进行随机变换,来增强它们的变化。无论皮卡丘的方向是颠倒的或者是一定程度倾斜,人类都能够准确识别,我们希望训练出的模型也有这个功能。

因此,我们对训练集数据进行以下变换:

1)高达40度的随机旋转;

2)高达20%的图像宽度的随机水平移位;

3)高达20%的图像高度的随机垂直移位;

4)高达20%的随机放大;

5)垂直镜像;

6)在0.2弧度范围内,进行剪切变换。

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

△ 图19:对妙蛙种子进行图像增强操作后获得的一系列图像

我将上述的增强变换应用于训练集中的所有精灵,每个精灵图像能够生成10个新图像。这样,我们把训练集的样本量扩展到了27,270个。经过这样的操作,是否能够正确分类?该算法运行超过30步,用了超过10分钟的时间,训练结果如下图所示:

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

△ 图20:第二个模型对训练集的分类性能.

咦,我们的模型性能下降了?图像增强技术不是应该使我的网络模型预测性能变得更好么?

别着急下结论,我们不能根据对训练集的分类效果来下定论。该模型预测性能的整体下降是由于训练集变化的增加,如果它能转化为对验证集更好的分类性能,这应该是个好消息。

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

△ 图21:第二个模型对验证集的分类性能.

我们证明了,图像增强技术有助于提高模型的预测性能,对验证集的预测准确率提高了14%,达到了39%。我们可以通过改动该模型的超参数或优化卷积网络的结构,来获得更好的预测模型,但我们希望将后续的工作交给读者来完成。

对分类结果进行研究

我们要从结果中提取到关键的规律。预测精度较高的属性如下:

火:61%

水:54%

毒:54%

草:47%

电:46%

召回率较高的属性如下:

恶:92%

火:74%

水:55%

一般:49%

草:42%

这个结果并不奇怪,火、水和草这三种主要属性在这两个指标中均位列前五。这是由于这些属性与颜色具有关联性,这是从精灵图像里容易提取到的信息。同时属于这三种属性的精灵也很多,所以有很多的训练样本可供模型进行学习。

现在来看看容易被正确分类和不容易被正确分类的精灵:

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

△ 图22:正确率较高的精灵
上行:杰尼龟(左),比卡丘(中),口呆花(右)
下行:火焰鸟(左),班吉拉(中),Shedinja(右)

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

△ 图23:正确率较低的精灵
上行:豪力(左),菊石神(中),洛奇亚(右)
下行:沙奈朵(左),饭匙蛇(中),水伊布(右)。

即使在这个样本量较小的数据集中,我们可以看到,颜色在精灵分类中起着重要的作用。例如在容易被错误分类的精灵中,豪力很大可能被划分为毒型,可能是由主体色为紫色导致分类错误。同样地,可能由于饭匙蛇为深色,所以被误分为恶型。

好吧,我们可能永远不知道为什么会出现这样的结果。使用深层神经网络进行分类的一个缺点是该网络模型相当于一个“黑盒”,目前有很多学者在研究神经网络在图像分类中学习到的抽象特征。

现在,我们可以来观察下通过第一层卷积核获取到的特征图谱,尝试理解下卷积核在寻找什么样的图像特征。但是随着深度神经网络层数的加深,我们越来越难辨识出组合而成的高级抽象特征。

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

△ 图24:用第一卷积层的内核来处理第一代初学者精灵图像所得到的效果

结论

该模型的预测正确率只有39%,可能不那么尽如人意。但是想要利用小样本数据集实现18类精灵的分类问题,并不是那么简单。我们的模型比零规则基线高出了20%的分类准确度。表1列出了在测试集上每个精灵属性出现的频率,比零规则基线高出了19.5%的精度。

看图猜口袋妖怪属性,这个神经网络可能比你强!(教程)

△表1:测试集里精灵出现的频率

但是,如果我们期望计算机有一天能够成为地球上的机器人霸主,我们就不应该用这种笨拙的方法来衡量它们。如果计算机想比我弟弟更好地认出精灵宝贝,那他还需要好好努力。

本文作者:王新民
原文发布时间:2017-03-19
上一篇:设计模式(八)装饰器模式Decorator(结构型)


下一篇:带你读《软件定义网络之旅:构建更智能、更快速、更灵活的未来网络》译者序