1.简介
现在这个时代吧,你说你不知道大数据,不知道深度学习,都不敢说自己是做软件的。。。可是深度学习这东西吧,虽然有诸如Caffe、Torch、Tensorflow等架构,但也不是一两天就能入门的,再者说这东西也吃硬件,没个金刚钻,也做不好这瓷器活。
不过话说回来,大部分人也只是使用模型,并不会自己训练模型。深度学习架构中,资历老、“活”还好的Caffe一直被大部分人使用(貌似是大神贾杨清的博士毕设。。。)。众所周知,有个叫Caffe Model Zoo的伊甸园,里面不仅仅包括在ImageNet上训练的模型,还有许多别的模型,能满足你的大部分需求。传送门:https://github.com/BVLC/caffe/wiki/Model-Zoo
然而新的问题来了,怎么用模型呢?caffemodel文件是啥,prototxt又是啥?正常情况下,我们肯定是用Caffe架构中已经写好的函数,或者使用PyCaffe中的python接口。可是你可以去尝试配置一下Caffe。。。(博主身边有个大牛就喜欢干这种事,所以复不复杂自己去试试吧)
这里就需要感谢一下国外的大牛了啊,他们开发出了opencv_contrib包,里面的dnn模块可以直接使用caffemodel。(差距啊。。。)
最后就是博主写这篇文章的最终原因了。。。为毛dnn模块里不能加载均值文件,至于啥是均值文件我会在下文中讲。
2.“爱”之初体验
有一个ImageNet-1K的数据集,即数据集中共有1K个类别的实际生活中东东。那我们如何让机器进行分类呢?分类,说白了就是让机器告诉我这个图片里主要是啥。好,装X开始,你只需要编译好你的opencv_contrib(我使用的是3.2版本)包,然后ctrl+c,ctrl+v链接中的代码:
装X代码传送门:http://docs.opencv.org/master/d5/de7/tutorial_dnn_googlenet.html
当机器返回给你space shuttle的时候,是不是非常激动?你的机器居然认识了航天飞机,还是在你啥事没做的情况下。。。在这里我们也不去吹嘘CNN为啥这么牛逼之类的,毕竟这不是本文的初衷。这个时候,有些做过Caffe模型训练的人就会问了,均值文件呢?Caffe在实际训练的过程中,图像的各个通道都会减去均值文件进行训练,会提高速度和精度。可是为什么Opencv官方的demo里压根就没提及?
无奈,去看了dnn类是如何实现的。。。
看完了之后,除了惊讶还是惊讶。第一个惊讶是因为,居然还能读Tensorlfow的checkpoint和Torch的model。第二个惊讶是,压根没法读取均值文件。。。它的函数就是dnn::readNetFromCaffe(const string protofile, const string model)。。。那均值文件怎么办?
3.“爱”之思考
我个人只想到两个办法,反正均值文件不就记录了图像通道中的像素值吗,会protobuf读取不就好了?(忘了说了,我们正常使用的均值文件都是.binaryproto文件)可惜,我并不会。。。
第二个办法就是我现在用的,借助Caffe接口,利用PyCaffe将binaryproto转成npy,至于这个代码,网上一大把。。。npy文件,直接用np.load就好。我直接把它转成图片存储了下来,注意在存储的时候,需要用np.transpose(2,0,1)转置一下,至于为啥,你用np.shape自己看看就知道了,这里我给出我的均值文件生成的图像:
这个时候你应该知道我要做啥了吧,剩下来的就是把我们自己进行测试图片与这张图片做减法咯,首先将这张图片以及测试图片resize到网络的输入尺寸,然后进行cv::substract操作。然后将这个Mat丢入到blobFromImage中就大功告成了。
实际测试中,我们发现均值文件对分类的结果影响不是很大,但是置信度提升还是有的。
其实我一直想规避Caffe接口,但是我个人看源码得出的结论是无法使用均值文件的,也许是因为我水平不够吧!
4.莫名奇妙看到的
前两天刚刚考了设计模式,今天看到了有人问Caffe使用了哪种设计模式?
答案貌似是抽象工厂。。。
长年写脚本语言的人,看着类啊类的真是累啊累。。。