王小新 编译自 Medium 量子位 出品 | 公众号 QbitAI
Alexandre Attia是《辛普森一家》的狂热粉丝,在之前他已经写了一篇用卷积神经网络来识别20个辛普森人物的教程。给定一个人物图片后,该模型能返回该图片的所属类别,识别效果相当好,F1分值可达96%。
量子位翻译过这篇教程:刷剧不忘学CNN:TF Keras识别辛普森一家人物 | 教程 代码 数据集
相关数据集已经在Kaggle上开源,但是该CNN模型每次只能识别单个人物,且不能指出该人物的图片位置。
作者不满足于只构建了一个简单的分类器,所以在本文中,作者创建了一个能检测和分类图片中每个人物的新模型,该模型将比之前的模型复杂得多,并且能为每个人物绘制对应的边框。
接下来让我们跟着他的文章来了解下该如何建立一个具有定位加识别功能的网络模型。
一开始,我考虑使用滑动窗口的方法来分类图片中的多个人物。为了检测出每个人物,我们组合不同大小的窗口进行多次判断。该算法可以预测每张图片中的大量子图片,但是计算十分耗时。
因此,在这篇文章中,我会使用更快速且最先进的深度学习模型Faster R-CNN,听起来非常有趣。本文仍然使用了以TensorFlow为后端的Keras库。
Faster R-CNN网络
目标检测网络是基于区域提案(region proposal)算法来进行假设,得到目标的位置。
该模型的主体为区域提案网络,结合能同时预测目标边界和每个位置目标评分的完全卷积网络来实现的。
Faster R-CNN是R-CNN和Fast R-CNN的升级版本,其结构类似于Fast R-CNN网络,但是使用ConvNet取代了区域提案部分。
△ Faster R-CNN网络示意图
下面是前馈通道的信息流:
1.卷积网络从末个卷积层得到特征图谱;
2.区域提案网络(RPN)通过convnet结构提出感兴趣区域RoI(Region of Interest),用来处理特征图谱;
3.每个所提出的区域都会被传递到一个RoI池化层中;
4.通过全连接层来分类各区域;
Yann Henon曾经用Keras库实现了上述Faster R-CNN网络。
你也可以查看量子位之前编译过的《卷积神经网络在图像分割中的发展历程:从R-CNN到Mask R-CNN》,来详细了解图像分割技术。
完善数据集
第一部分中所使用的数据集还存在一定问题,因此我们仍需要为训练集中每个人物确定对应的边界框。
我们可以通过点击鼠标和matplotlib库,为每张图片标记出边界框。已标记的训练集和相关说明已经上传至Kaggle平台。
△ 确定每个图片中人物的边界框坐标
我们不仅保存了图片形式的训练集,还将边界框坐标和对应类别保存为一个文本文件:
对于每个人物,要确定该人物边界框的左上角和右下角坐标。
△ 人物的样本量分布
数据预处理
训练集中的子图片可能具有不同的长宽比和分辨率,因此需要进行预处理。
首先要调整图片的分辨率,使最小边的分辨率为300像素,同时保持相同的长宽比。然后通过减去每个通道的数据平均值来归一化图像,使训练集数值居中。通过以上操作,使每个特征的变化范围相似,减少发生梯度失控现象。
定义网络
本文以ResNet网络为基础,构建了区域提案网络RPN。同时也使用基本网络层定义了人物分类器。
训练模型
在训练时,该模型基于训练集迭代训练了50步,每次迭代的长度为1000。还使用了两种数据增强方法,分别是水平翻转和90度旋转。
想要在CPU上训练该网络是不可能的,所以我使用了AWS EC2的Tesla K80:每次迭代需要390秒。
△ 训练时的正确率和Loss值
模型测试
△ 训练模型的效果图1
△ 训练模型的效果图2
在每张图片中,该模型能正确定位图中人物并对其进行分类,同时还能预测每个定位人物的边界框坐标。
根据效果图可以看出,该模型能很好地检测出图中人物,但是确定人物的边界框时较为粗糙。实际上,该模型确定出的人物边界框过大,所以当图片中有多个人物时,边界框可能会重叠。针对这一点,通过调整overlap_threshold值和Non-Maximum Suppression函数可以改善。
当然,与第一部分中只对训练集中人物图片分类的convnet网络相比,该模型的正确率有一定的降低。
使用笔记本电脑CPU进行预测,速度非常慢,每张图片耗时8秒;使用型号为Tesla K80 的GPU进行预测,每张图片耗时0.98秒。
我们可以简单地和结合滑动窗口的简单卷积网络比较,如第一部分使用的CNN网络,结果看起来很有趣。对于一张640x460大小的图片,滑动窗口设置为64x128(水平步幅为8像素,垂直步幅为4像素),仍需要处理6000张子图片。即使某网络的预测速度很快,每张子图片耗时只有0.01s,此时处理每张图片仍需要60秒。另外,如果结合了滑动窗口方法,就只能得到固定长宽比的多张子图片。
改进方向
接下来,我将继续标注相关图片来扩大训练集,如果有新方法会继续进行更新。
相关链接
1.用keras实现的Faster RCNN: https://github.com/yhenon/keras-frcnn
2.完整项目代码: https://github.com/alexattia/SimpsonRecognition