正文
将 1 中图片的右下角截取出来,作为机器学习的训练资料
运行机器学习代码,训练出可以识别不同英雄技能的模型
从待识别的直播流中抽取画面,截取右下角的技能画面,用 3 中的模型去识别看是哪个英雄的技能,从而完成对直播流英雄的识别
流程已然清晰,但后面的工作量才是最大的,先来看看如何获取训练资料吧。
做机器学习的都知道,写代码不是最难的部分,收集优质的训练素材才是。如何能够快速获得 60 多个英雄分别对应的 1000 张图片呢?且不说找到 6 万多张图片的难度,找到后难道要我人肉来标记哪张图片是哪个英雄?如果真要这么做,估计一个人是很难完成了。
这一次想出的取巧方法是直接去优酷上搜索「王者荣耀」+「英雄名字」,就能搜到很多玩家录好的英雄视频。于是让团队里的同学帮忙,很快收集齐了所有英雄的对战视频各 1 个。然后用 Adapter 这样的软件将视频按一秒一帧转化为几千张图片。(不过一开始没有发现 Adapter 这个软件,当时是用 OpenCV 去一帧帧把视频里的画面读取出来的。)
唯一的坑是优酷上的视频往往并不只是对战过程本身,还会有一些制作者加入的视频特效、文字、转场动画啥的。一开始没留意,污染了一小批训练素材,后来重新找了几个干净的视频解决此问题。
于是就这样,轻松获得了含有英雄标记信息的近 10 万张图片。
后面的事情就简单了,用 OpenCV 统一对图片进行裁剪。一开始是裁到三个技能的区域,但因为这个区域覆盖的面积较大,会包含进来很多不必要的图像信息,导致训练出来的结果不理想。在后期调优时,想到每个英雄的技能其实是唯一的,没必要识别全部,于是将素材全都裁剪到第二个技能,果然大大提升了识别准确度。
早有耳闻 Google 家 TensorFlow 上手容易且性能还不错,加上是 G 家产品,自然和 Python 配合度最好,适合常年写 Python 的我。于是果断开始读 TensorFlow 的文档。
不得不说周末那个晚上有很多时间花在了如何在 virtualenv 里安装 TensorFlow 和 OpenCV。网上的教程没有一个是可以完全顺利在 Mac 上跑完的,还好最后在 Google 和 Stack Overflow 的双重加持下,这俩个组件都在我 Mac 上编译成功了。
很快,在 TensorFlow 官方教程里找到一篇关于图片识别的文章。跑了一下 demo,运行正常。于是开始研究如何训练自己的模型。
既然都按照官方教程走了,所以直接用了 Inception V3 的网络结构。近 10 万张图片,在没有 GPU 加持的 Macbook Pro 上,差不多得跑 10 个小时才能跑完第一次训练。
不过其中最耗时是计算 Bottleneck 值,因为这个值在每次训练时其实都不会变。所以教程中会让在第一次计算每张图片的 Bottleneck 值后,将之保存下来,这样下次训练只需要计算新增图片素材的 Bottleneck 值即可,不需要每次都全量计算。这样优化之后,效率飞升。
到此时,已经是周日凌晨 3 点了,赶紧让模型跑起来,睡觉去。
周日中午醒来,第一次训练已经跑完了,赶紧拿新模型去做各种测试,准确率超乎想象的高。但如「收集素材」那一段里提到,一开始是识别三个技能,所以在某些英雄的识别上不太理想。
将所有素材调整为单个技能截图后,又跑了一次,出结果时已经是周日晚上。这个时候的准确率靠我找到的测试图片已经没有失败的例子了。
截止这个时候,识别单张图片大概需要 5 秒,倒也不是不能接受,但还想更快。在没有 Nvidia 显卡的情况下,只能依赖于在本地编译 TensorFlow,从而让 TensorFlow 能用上本地 CPU 的 SSE、AVX 这类指令,加快运算速度。如何在 Mac 上编译 TensorFlow,可以参考这里。