在上一篇中安装好了OpenCV3.1的环境后,继续研究官方文档中关于contrib库的教程。
DNN即Deep Neural Networks,也就是深层神经网络,是目前深度学习概念中最基本的一种技术框架。
相对于传统的人工神经网络(包括多层神经网络),对DNN的关键不同点的一种解释是:其在做有监督学习前要先做非监督学习,然后将非监督学习学到的权值当作有监督学习的初值进行训练。
1. 准备工作
这次要看的教程是Load Caffe framework models。
在VS中新建一个名为caffe_googlenet
的win32控制台项目,将opencv_contrib\modules\dnn\samples
目录下的4个文件拷贝至项目文件夹内覆盖。
另外还差一个bvlc_googlenet.caffemodel
文件需要单独下载,即训练好的分类器模型。
其中Caffe是一个深度学习框架,由Berkeley大学研究并发布。
官方教程中给出的下载链接貌似被墙了,可以到我的云盘分享去下载,提取码1d6e。
此时已经可以编译运行了。
输入的图像为:
得到结果如下:
Net Outputs(1):
prob
Best class: #812 'space shuttle'
Probability: 99.9799%
即输入图片属于分类space shuttle的可能性为99.9799%。
2. 代码分析
源码就不贴了,opencv_contrib\modules\dnn\samples
文件夹下有现成的cpp文件。
几个关键步骤如下:
(1)载入Caffe模型
Ptr importer;
importer = dnn::createCaffeImporter(modelTxt, modelBin);
(2)创建神经网络并初始化
dnn::Net net;
importer->populateNet(net);
importer.release();
(3)读取输入图像并转化为GoogleNet可识别的blob格式
Mat img = imread(imageFile);
resize(img, img, Size(224, 224));
dnn::Blob inputBlob = dnn::Blob(img);
(4)将图像数据输入网络
net.setBlob(".data", inputBlob);
(5)计算输出
net.forward();
(6)取出prob层的输出,确定最终的分类
dnn::Blob prob = net.getBlob("prob");
int classId;
double classProb;
getMaxClass(prob, &classId, &classProb);
3. 进一步分析
我们来分析一下例程中提供的几个文件。
bvlc_googlenet.caffemodel
刚刚已经说过,是训练好的分类器模型。bvlc_googlenet.prototxt
根据存储的内容来看应该是记录了生成的深度神经网络结构。synset_words.txt
存储了该分类模型可以识别的图像内容的种类。
我们从synset_words.txt
中随机选取几个其他类别的物品来试一试。
第一张图片:
识别结果:
Best class: #817 'sports car, sport car'
Probability: 81.8836%
第二张图片:
识别结果:
Best class: #2 'great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias'
Probability: 87.1443%
第三张图片并没有对应给出的分类,而是从新闻联播中随机拉了一张截图:
识别结果:
Best class: #624 'library'
Probability: 11.234%
并没有适合的分类,但至少识别出了这是一个室内的场景。
用单一分类器可以识别这么多种类的东西,效果还是挺感人的。
4. 后续
目前只是调用了已经训练好的分类器,后边会研究一下如何自己来训练所需要的分类器。
也许实现人工智能真的不再是科学幻想了,而就在即将到来的时代。