神经网络:caffe特征可视化的代码样例

来源:互联网 发布:破解摄像头软件下载 编辑:程序博客网 时间:2024/06/09 03:31

caffe特征可视化的代码样例

不少读者看了我前面两篇文章

总结一下用caffe跑图片数据的研究流程

deep learning实践经验总结2--准确率再次提升,到达0.8,再来总结一下

之后,想知道我是怎么实现特征可视化的。


简单来说,其实就是让神经网络正向传播一次,然后把某层的特征值给取出来,然后转换为图片保存。


下面我提供一个demo,大家可以根据自己的需求修改。


先看看我的demo的使用方法。

visualize_features.bin net_proto pretrained_net_proto iterations  [CPU/GPU]  img_list_file dstdir laydepth

visualize_features.bin是cpp编译出来的可执行文件

下面看看各参数的意义:

1 net_proto:caffe规定的一种定义网络结构的文件格式,后缀名为".prototxt"。这个文件定义了网络的输入,已经相关参数,还有就是整体的网络结构。

2 pretrained_net_proto:这个是已经训练好了的模型

3 iterations:迭代次数

4 [CPU/GPU]:cpu还是gpu模式

5 img_list_file:待测试的文件名列表。我这里需要这个主要是为了得到图片的类名。

6 dstdir:图片输出的文件夹

7 laydepth:需要输出哪一层的特征


下面是一个实例例子:

./visualize_features.bin /home/linger/linger/caffe-action/caffe-master/examples/cifar10/cifar10_full_test.prototxt /home/linger/linger/caffe-action/caffe-master/examples/cifar10/cifar10_full_iter_60000 20 GPU /home/linger/linger/testfile/skirt_test_attachment/image_filename /home/linger/linger/testfile/innerproduct/ 7


下面是源代码:

[cpp] view plaincopy
  1. // Copyright 2013 Yangqing Jia  
  2. //  
  3. // This is a simple script that allows one to quickly test a network whose  
  4. // structure is specified by text format protocol buffers, and whose parameter  
  5. // are loaded from a pre-trained network.  
  6. // Usage:  
  7. //    test_net net_proto pretrained_net_proto iterations [CPU/GPU]  
  8.   
  9. #include <cuda_runtime.h>  
  10. #include <fstream>  
  11. #include <iostream>  
  12. #include <cstring>  
  13. #include <cstdlib>  
  14. #include <algorithm>  
  15. #include <vector>  
  16. #include <utility>  
  17. #include "caffe/caffe.hpp"  
  18. #include <opencv2/highgui/highgui.hpp>  
  19. #include <opencv2/highgui/highgui_c.h>  
  20. #include <opencv2/imgproc/imgproc.hpp>  
  21.   
  22. using std::make_pair;  
  23. using std::pair;  
  24. using namespace caffe;  // NOLINT(build/namespaces)  
  25. using namespace std;  
  26.   
  27. vector<string> fileNames;  
  28. char * filelist;  
  29.   
  30. /* 
  31.  * 读入的文件的内容格式类似这样子的:全局id 类名_所在类的id.jpg 
  32. 0 一步裙_0.jpg 
  33. 1 一步裙_1.jpg 
  34. 2 一步裙_10.jpg 
  35.  */  
  36. void readFile()  
  37. {  
  38.     if(fileNames.empty())  
  39.     {  
  40.         ifstream read(filelist);  
  41.         //"/home/linger/linger/testfile/test_attachment/image_filename"  
  42.         // "/home/linger/imdata/test_files_collar.txt"  
  43.         //  "/home/linger/linger/testfile/testfilename"  
  44.         if(read.is_open())  
  45.         {  
  46.             while(!read.eof())  
  47.             {  
  48.                 string name;  
  49.                 int id;  
  50.                 read>>id>>name;  
  51.                 fileNames.push_back(name);  
  52.             }  
  53.         }  
  54.     }  
  55. }  
  56.   
  57. /* 
  58.  * 根据图片id获取类名 
  59.  */  
  60. string getClassNameById(int id)  
  61. {  
  62.     readFile();  
  63.     int index = fileNames[id].find_last_of('_') ;  
  64.     return fileNames[id].substr(0, index);  
  65. }  
  66.   
  67.   
  68.   
  69. void writeBatch(const float* data,int num,int channels,int width,int height,int startID,const char*dir)  
  70. {  
  71.     for(int id = 0;id<num;id++)  
  72.     {  
  73.         for(int channel=0;channel<channels;channel++)  
  74.         {  
  75.             cv::Mat mat(height,width, CV_8UC1);//高宽  
  76.             vector<vector<float> > vec;  
  77.             vec.resize(height);  
  78.             float max = -1;  
  79.             float min = 999999;  
  80.             for(int row=0;row<height;row++)  
  81.             {  
  82.                 vec[row].resize(width);  
  83.                 for(int col=0;col<width;col++)  
  84.                 {  
  85.                     vec[row][col] =  
  86.                             data[id*channels*width*height+channel*width*height+row*width+col];  
  87.                     if(max<vec[row][col])  
  88.                     {  
  89.                         max = vec[row][col];  
  90.                     }  
  91.                     if(min>vec[row][col])  
  92.                     {  
  93.                         min = vec[row][col];  
  94.                     }  
  95.   
  96.   
  97.                 }  
  98.             }  
  99.   
  100.             for(int row=0;row<height;row++)  
  101.             {  
  102.                 for(int col=0;col<width;col++)  
  103.                 {  
  104.                     vec[row][col] = 255*((float)(vec[row][col]-min))/(max-min);  
  105.                     uchar& img = mat.at<uchar>(row,col);  
  106.                     img= vec[row][col];  
  107.   
  108.                 }  
  109.             }  
  110.             char filename[100];  
  111.             string label = getClassNameById(startID+id);  
  112.             string file_reg =dir;  
  113.             file_reg+="%s%05d_%05d.png";  
  114.             snprintf(filename, 100, file_reg.c_str(), label.c_str(),startID+id,channel);  
  115.             //printf("%s\n",filename);  
  116.             cv::imwrite(filename, mat);  
  117.         }  
  118.   
  119.     }  
  120. }  
  121.   
  122. int main(int argc, char** argv)  
  123. {  
  124.   if (argc < 4)  
  125.   {  
  126.     LOG(ERROR) << "visualize_features.bin net_proto pretrained_net_proto iterations "  
  127.         << "[CPU/GPU] img_list_file dstdir laydepth";  
  128.     return 0;  
  129.   }  
  130.   /* 
  131.  
  132.   ./visualize_features.bin /home/linger/linger/caffe-action/caffee-ext/Caffe_MM/prototxt/triplet/triplet_test_simple.prototxt /home/linger/linger/caffe-action/caffee-ext/Caffe_MM/snapshorts/_iter_100000 8 GPU /home/linger/linger/testfile/test_attachment/image_filename /home/linger/linger/testfile/innerproduct/ 6 
  133.  
  134.   */  
  135.   
  136.   filelist = argv[5];  
  137.   cudaSetDevice(0);  
  138.   Caffe::set_phase(Caffe::TEST);  
  139.   
  140.   if (argc == 5 && strcmp(argv[4], "GPU") == 0)  
  141.   {  
  142.     LOG(ERROR) << "Using GPU";  
  143.     Caffe::set_mode(Caffe::GPU);  
  144.   }  
  145.   else  
  146.   {  
  147.     LOG(ERROR) << "Using CPU";  
  148.     Caffe::set_mode(Caffe::CPU);  
  149.   }  
  150.   
  151.   NetParameter test_net_param;  
  152.   ReadProtoFromTextFile(argv[1], &test_net_param);  
  153.   Net<float> caffe_test_net(test_net_param);  
  154.   NetParameter trained_net_param;  
  155.   ReadProtoFromBinaryFile(argv[2], &trained_net_param);  
  156.   caffe_test_net.CopyTrainedLayersFrom(trained_net_param);  
  157.   
  158.   int total_iter = atoi(argv[3]);  
  159.   LOG(ERROR) << "Running " << total_iter << " Iterations.";  
  160.   
  161.   double test_accuracy = 0;  
  162.   vector<Blob<float>*> dummy_blob_input_vec;  
  163.   
  164.   int startID = 0;  
  165.   int nums;  
  166.   int dims;  
  167.   int batchsize = test_net_param.layers(0).layer().batchsize();  
  168.   
  169.   int laynum = caffe_test_net.bottom_vecs().size();  
  170.   printf("num of layers:%d\n",laynum);  
  171.   
  172.   for (int i = 0; i < total_iter; ++i)  
  173.   {  
  174.     const vector<Blob<float>*>& result =  
  175.         caffe_test_net.Forward(dummy_blob_input_vec);  
  176.   
  177.     int laydepth = atoi(argv[7]);  
  178.   
  179.     Blob<float>* features = (*(caffe_test_net.bottom_vecs().begin()+laydepth))[0];//调整第几层即可  
  180.   
  181.     nums = features->num();  
  182.     dims= features->count()/features->num();  
  183.   
  184.     int num = features->num();  
  185.     int channels = features->channels();  
  186.     int width = features->width();  
  187.     int height = features->height();  
  188.     printf("channels:%d,width:%d,height:%d\n",channels,width,height);  
  189.     writeBatch(features->cpu_data(),num,channels,width,height,startID,argv[6]);  
  190.     startID += nums;  
  191.   
  192.   }  
  193.   
  194.   return 0;  
  195. }  






版权声明:本文为博主原创文章,未经博主允许不得转载。

5
0
主题推荐
神经网络可视化深度学习经验图片数据
猜你在找
数据结构(C版)
移动手机APP测试从零开始(初级篇)
3D游戏开发基础
JDBC视频教程
jQuery 视频教程
准备好了么? 更多职位尽在 
C++初级研发工程师
广州市新文溯科技有限公司
4-8K/月
我要跳槽
数据抓取工程师(JAVA,Python)
广州酷旅旅行社有限公司
6-12K/月
我要跳槽
C++工程师
广州华工邦元信息技术有限公司
5-10K/月
我要跳槽
高级C++研发工程师
上海暗沙网络科技有限公司
10-18K/月
我要跳槽
查看评论
13楼 caszhao 2015-05-29 11:29发表 [回复]
请教一下博主这个怎么编译?需要配合caffe什么库吗?能否请博主指点一下编译的方法。多谢
g++ xxx.cpp -p xxx
貌似缺少指定很多库,如:
fatal error: cuda_runtime.h: No such file or directory
12楼 nel2009 2015-04-21 15:31发表 [回复]
博主你好,非常感谢你的博客,学到很多,有几个问题希望给指导下哈。有参数你说的是待测试的文件名列表具体是指什么呢?是要训练的图片转成levelDB格式的文件夹吗?最后那个参数层数,什么怎么算的层数呢,卷积一层,pooling一层,全连接算一层吗?
11楼 NAME 2015-01-20 15:41发表 [回复]
看了楼主上面的代码,实现过后有很多张图像(32张),也是第七层,不知道怎么回事
10楼 大脸的帅松松 2015-01-05 19:06发表 [回复]
你好,你的visualize_feature.bin 是caffe自带的吗?
Re: lingerlanlan 2015-01-13 23:59发表 [回复]
回复u011547448:不是,这个我自己写的
9楼 qinhuafengfeng 2015-01-04 18:15发表 [回复]
非常谢谢博主。我的测试集包含在Val文件夹,其下又含有objectio和background两个子文件夹,每个文件夹有1.bmp到100.bmp共100幅。两类标签分别为0和1。img_list_file格式为0 objection_1.bmp,请问是不是提取的objection下面的第一幅的特征啊?我检查了一下感觉不对头啊?
Re: nel2009 2015-04-21 17:00发表 [回复]
回复qinhuafengfeng:你好,你这个解决了吗?那个第5个参数待训练的文件名列表是啥啊?谢谢了
Re: lingerlanlan 2015-01-14 00:03发表 [回复]
回复qinhuafengfeng:我的命名规则跟你的不一样。你根据你的需求修改一下吧
8楼 qinhuafengfeng 2014-12-29 03:12发表 [回复]
SET GLOG_logtostderr=1
extract_features_my.exe D:\Caffe\examples\cifar10\cifar10_quick_test.prototxt D:\Caffe\examples\cifar10\cifar10_quick_iter_4000 20 GPU D:\Caffe\examples\cifar10\tmp\1.bmp D:\Caffe\examples\cifar10\output 7
pause
当我运行上面的bat文件后,就一直运行,等了很长时间,最后都死机了还是没有得到1.bmp的特征,请问博主这是怎回事啊,谢谢你。
Re: lingerlanlan 2015-01-01 16:01发表 [回复]
回复qinhuafengfeng:你这里第5个参数跟我的不同。
5 img_list_file:待测试的文件名列表。
最好读懂代码,灵活使用。我实现的功能并不一定刚好符合你的需求。
Re: 大脸的帅松松 2015-01-06 16:35发表 [回复]
回复linger2012liu:你好,你的visualize_feature.bin 是caffe自带的吗? caffe 下面没有这个bin啊
7楼 qinhuafengfeng 2014-12-29 03:11发表 [回复]
博主你好!经常关注你的帖子,最近准备用你的方法提取个卷积层的特征。我编译的你上面的这个.ccp文件生成了extract_features_my.exe 文件。然后,我写了如下一个bat文件以提取1.bmp图像第7层的特征。我用的框架就是caffe的cifar的demo。
6楼 fengye607 2014-11-26 02:21发表 [回复]
博主,我想实现双GPU的并行,请问可以交流一下吗,我的QQ是492545607
Re: lingerlanlan 2015-01-14 00:01发表 [回复]
回复fengye607:双GPU和集群我也没实践过。只知道,多GPU时,一个CPU的一个线程来调度一个GPU。
5楼 u010445738 2014-11-22 17:59发表 [回复]
请问卷积核怎么可视化吖?
Re: lingerlanlan 2014-11-22 18:19发表 [回复]
回复u010445738:从layer里取出weight就可以了
4楼 u010445738 2014-11-19 22:36发表 [回复]
vector<Blob<float>*> dummy_blob_input_vec 直接是空的进去吗?
Re: lingerlanlan 2014-11-20 00:49发表 [回复]
回复u010445738:是的
Re: u010445738 2014-11-20 09:59发表 [回复]
回复linger2012liu:但是我输出的图片都是黑乎乎一片啵,请大师指点
Re: u010445738 2014-11-20 10:13发表 [回复]
回复u010445738:已成功画出图例,谢谢楼主分享
Re: qinhuafengfeng 2015-01-04 18:23发表 [回复]
你好,你的file_list.txt格式怎么弄的啊,能交流一下吗
我qq271107933
Re: zhangvvok 2014-12-12 10:56发表 [回复]
回复u010445738:我画出来也是全黑乎乎的,请问你是如何解决的?
3楼 man5610652 2014-11-08 11:47发表 [回复] [引用] [举报]
fatal error: cuda_runtime.h: 没有那个文件或目录 亲,我在编译的时候报错。请问是怎么回事呢?
2楼 鼬花园 2014-08-20 10:45发表 [回复]
博主你好,看了你很多文章,想问一下如何应用我们训练好的网络(准确率99%)呢?比如说在mnist中,我们有一张数字3的图片,我们应该怎么操作才能输入图片3(leveldb格式)然后用网络返回3这个数字呢?
Re: lingerlanlan 2014-08-20 17:31发表 [回复]
回复jjff46:参考test_net.cpp。让你的图片正向传播一次就得出就结果了。
Re: 鼬花园 2014-08-20 18:46发表 [回复]
回复linger2012liu:谢谢博主!
1楼 bawangflower 2014-08-12 16:03发表 [回复]
我试了一下总是出这个错误:terminate called after throwing an instance of 'std::bad_alloc',好像是内存溢出,您是否遇到过类似的问题
Re: lingerlanlan 2014-08-13 14:23发表 [回复]
回复u010301494:试试把batchsize调小一
0 0
原创粉丝点击