教程 | 使用Tensorflow从视频中揪出皮卡丘!

2,354 阅读8分钟
作者 | Juan De Dios Santos
译者 | Zhiyong Liu
编辑 | Natalie,Debra
AI 前线导读:图像分类和目标检测是计算机视觉两大模块。相比于图像分类,目标检测任务更复杂更困难。图像目标检测在过去几年深度学习的发展背景下取得了巨大的进展,检测性能得到了明显的提升。目标检测不但要检测到具体的目标,还要定位目标的具体位置。不过 Tensorflow models 上大神们的无私奉献已经使得目标检测模型平民化,只需要按照特定的格式准备好训练数据,就可以轻松训练出自己想要的目标检测模型。国外就有一位皮卡丘的粉丝使用 TensorFlow 从视频中检测出皮卡丘,让我们看看人家是怎么做到的?更重要的是,人家放出了完整代码!

更多优质内容请关注微信公众号“AI 前线”,(ID:ai-front)

在 TensorFlow 的许多功能和工具中,有一个名为 TensorFlow Object Detection (目标检测)API 的组件。顾名思义,这个库的目的就是训练一个神经网络,能够识别视频帧中的目标,例如一个图像。

在我之前的一项工作中,我曾发表了一篇文章,阐述了我在 Android 设备上使用 TensorFlow 软件包检测皮卡丘的过程。此外,我还介绍了这个库,并讨论了它提供的不同架构和功能,以及如何使用 TensorBoard 评估训练过程的演示。

AI 前线注:该文章可访问以下链接查看 http://suo.im/4GPhqa

几个月后,我开始着手改进之前训练过的皮卡丘检测的模型,希望能够在视频中检测到皮卡丘,我使用了 Python、OpenCV,当然还有 TensorFlow Object Detection。这个模型的代码可以在 Github 上找到:

https://github.com/juandes/pikachu-detection

超级萌物皮卡丘

本文记录了我为实现这个目标所采取的步骤。首先,我将阐述我在原始模型中注意到的问题,以及为改善这些问题所做的工作。然后,我将继续阐述如何使用这个改进的新模型,并基于它开发了一个视频检测系统。最后,你们将能看到有着几个皮卡丘检测的两个视频。

在我们开始之前,先看一副 gif 动图,演示如何快速检测皮卡丘。

皮卡丘被检测到

绿框处即检测到的皮卡丘

改进模型

如前所述,在之前的工作中,我对一个皮卡丘检测模型进行了最初的训练,目标是在 Android 设备和 Python notebook 使用这个模型。然而,我对这个模型的表现并不是很满意,想做出皮卡丘检测系统的动机驱使我持续改进这个模型,于是便有了本文。

我所关心的主要问题是用来构建该系统所需的皮卡丘图片的数量:230 张。其中约 70% 用于训练,其余 30% 用于测试,因此训练并不太多。尽管这在技术上并不是什么问题(因为该模型的表现是“良好”),但我还是在训练集上增加了 70 多张图片(虽然不是很多,但总比没有好)。

由于我现在有了更多的图片,因此必须延长模型的训练。我并没有从头开始训练,而是使用了早期模型的训练检查点,并从那里继续;前者在 15000 个轮数训练,而新训练则需 20000 个轮数。如下两张图所示,显示了总损失(total loss)和精度(precision)(来源:TensorBoard);从这两张图很容易看出,从 15000 个轮数到 20000 个轮数(特别是在损失中),并没有多少变化。

损失度曲线

精度曲线

我做的最后一个(也是比较小的)改进,是修改了 Android 应用的检测阈值,将默认值 0.6,增加到 0.85。

你可能会问,这些改进能改变什么吗?就算摒弃我的偏见,我也会说,是的!我确实注意到了小小的改进。我注意到的最大变化就是,Android 应用的假正类(False Positive)数量减少了,原因是目标看起来像一个黄色的斑点;当然,也有可能是因为门槛提高所致。

现在,我有了一个最新的(承载着我的希望)改进模型,我已经准备好用它来检测视频中的皮卡丘。在此之前,我想指出的是,我将略过模型冻结和导入的整个过程,因为在我之前的工作中,已经解决了这个问题。

从视频中检测

从视频中进行目标检测并不像听起来那么困难或复杂。从外行的角度来说,我们可以认为视频是由一系列按顺序排列的图像组成的,因此检测过程与从正常图像检测的过程非常相似。为什么会相当相似呢?嗯,由于视频的性质,在将其馈送到检测模型前必须解决帧的预处理和准备还需要几个步骤。在接下来的文章中,我将会解释这一点,再加上我执行检测的过程,以及如何创建一个新视频来展示检测效果。

我的大部分代码都是基于 TensorFlow Object Detection 中提供的 Python notebook;这段代码完成了大部分工作,因为它包含了许多简化检测过程的函数。另外,我建议你看一下我的脚本,并在阅读以下段落时,使用这段脚本作为指导。

从高层次的角度来看,我写的代码完成了三个主要任务:

加载资源

首先,要加载冻结模型、数据标签和视频。为了简单起见,我建议使用一个简短的中型视频,因为处理一整部电影的话可能会需要更多的时间。

遍历视频

该脚本的主要功能是基于循环遍历视频的每一个帧。在每次迭代中,读取帧并更改其颜色空间。接下来,通过实际的检测过程找出所有那些漂亮的皮卡丘。然后返回皮卡丘所在边界框的坐标(如果找到的话)以及检测到的置信度值。随后,这个脚本将创建一个帧的副本,其中包含皮卡丘的边界框,只要置信度的值高于给定阈值即可。对于这个项目,我将置信度的阈值设置为非常低的 20%,因为我注意到在视频中检测到的假正类的数量非常小,所以我决定“冒险”设置这样的阈值,只是为了能够检测到更多的皮卡丘。

创建新的视频

所有新创建的带有前面步骤中所提到的检测框的帧副本,都用来构建新的视频。要构建这个视频,需要一个VideoWriter对象,并在前面所提到的循环的每次迭代中,帧的副本将写入这个对象(没有任何声音)。

结果与讨论

这两个视频展示了模型的表现。

v.qq.com/x/page/a061…

v.qq.com/x/page/q065…

该模型在第一个视频的检测结果非常好。尽管皮卡丘在整个视频中一直拿着番茄酱瓶子,但该模型在大多数场景中都能检测到皮卡丘。另一方面,在 0:22 处没有检测到皮卡丘,而且,0:40~0:44 这段出现飞天螳螂打碎番茄酱瓶子被检测为假正类。

该模型在第二个视频的表现不如第一个视频好,主要问题在于画面上有两个皮卡丘,在这种情况下,这个模型似乎将这两个皮卡丘视为一个,而不是每个皮卡丘都检测为一个:一个明显的例子就是在 0:13 处开始,两个皮卡丘互相抽打耳光。

总结和回顾

在本文中,我谈到了如何使用 TensorFlow Object Detection 包在视频中检测皮卡丘。在本文开头,我谈论了以前的工作,提及我使用早期版本的模型在 Android 设备上进行检测皮卡丘。该模型尽管发挥了作用,但仍存在一些我想解决的问题;这些改进让我得以完成这个新项目,并为视频构建了一个检测皮卡丘的模型。

这个新模型确实按照我的预期发挥了作用。当然,也有检测不到的时候,这与假正类有关,但模型做到了它必须做的事。作为未来的研究方向,我希望在我的训练集中添加更多不同角度的皮卡丘图像,例如,皮卡丘的侧视图和后视图,以使数据更加多样化,从而获得更好的结果。

原文链接:

https://towardsdatascience.com/detecting-pikachu-in-videos-using-tensorflow-object-detection-cd872ac42c1d