caffe之网络权重可视化(C++实现)
来源:互联网 发布:java 转二进制 编辑:程序博客网 时间:2024/06/18 10:02
在上一篇博客中,已经介绍了caffe用训练好的model对一副测试图片进行分类的c++实现过程。
今天,我们来看对一个训练好的model,用c++进行model的网络权值的可视化,比如看看网络中的第一个卷积层conv1、第一个卷积层pool1到底学到的是什么特征。
正如上一篇博客结尾处说的,网络权值的可视化,是不需要网络的前向传播就能看到的,因为学到的参数已经事实存在了,只要加载这个model,把相关的参数提取出来就ok啦,所以,为了简单起见,这里就不在classification.cpp里去添加代码实现,而是在一个新的cpp文件里实现这个功能(当然,最好是可以将权值可视化功能封装在classification.cpp这个文件里,这样子的话,该文件就提供了分类、可视化等功能,同理,还可以将提取某一层特征向量,特征图可视化也集成在这个文件里,这样的话对以后的需求就能方便的使用了,比如讲第一个全连接层的特征向量提取出来,再送进更精准的分类器(如SVM)去分类,而只把cnn当成特征提取器);
不失一般性,我们借用caffe中已经训练好的模型caffenet(2012年的alexnet的修改版),对该model进行可视化
// File: test.cpp
#include <caffe/caffe.hpp> //为了能正常编译,需要引入caffe的头文件#include <opencv2/core/core.hpp> //这三行是为了引用opencv#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <algorithm>#include <iosfwd>#include <memory> //使用c++智能指针,必须包含该目录#include <string>#include <utility>#include <vector>
using namespace caffe; // NOLINT(build/namespaces)using namespace cv;using namespace std;int main(){ //初始化一个网络,网络结构从caffenet_deploy.prototxt文件中读取,TEST表示是测试阶段 Net<float> net("caffenet_deploy.prototxt",TEST); net.CopyTrainedLayersFrom("caffenet.caffemodel"); //读取已经训练好的model的参数 vector<shared_ptr<Blob<float> > > params=net.params(); //获取网络的各个层学习到的参数(权值+偏置) //打印出该model学到的各层的参数的维度信息 cout<<"各层参数的维度信息为:\n"; for(int i=0;i<params.size();++i) cout<<params[i]->shape_string()<<endl; return 0;}
此时,我们需要编译该文件,假设该文件取名test.cpp,则执行以后命令编译该文件
g++ -o netapp.bin test.cpp `pkg-config --libs --cflags opencv` -I ~/caffe/include/ -I ~/caffe/src/ -I ~/caffe/build/src/ -I /usr/local/cuda-8.0/include/ -L ~/caffe/build/lib/ -lprotobuf -lcaffe -lglog -lboost_system解释下这条指令,前面几个是g++编译cpp文件的命令,`pkg-config --libs --cflags` 是引用opencv库,前三个-I(大写的i)表示指定三个包含目录(因为会引用很多caffe里的文件),第四个-I,是指定用cuda的包含目录,-L表示该文件需要引用的库目录,而接下来的四个-l 则表示具体链接的四个动态库了。(如果你没有GPU,只要用cpu来运行的话,则删除第四个-I,以及在命令中,加一条 -D CPU_ONLY就可以正常编译了)
好了,此时已经编译成功,生成了netapp.bin可执行文件,我们再把caffenet的deploy.prototxt和caffenet.model文件放在这个目录下,运行 ./netapp.bin,打印出一系列blog后,会输出以下信息:
96 3 11 11 (34848)96 (96)256 48 5 5 (307200)256 (256)384 256 3 3 (884736)384 (384)384 192 3 3 (663552)384 (384)256 192 3 3 (442368)256 (256)4096 9216 (37748736)4096 (4096)4096 4096 (16777216)4096 (4096)1000 4096 (4096000)1000 (1000)
我们都知道alexnet模型的网络结构,由数据层、5个卷积层+池化层+ReLU层交叉、3个全连接层组成,而这个网络需要学习的参数(权重+偏置),则只有5个卷积层+3个全连接层(池化层和Relu层是不用学习权重参数的),从打印的信息来看,分别是第一个卷积层权重参数的维度,第一个卷积层偏置参数的维度;第一个卷积层权重参数的维度,第一个卷积层偏置参数的维度;.......以此类推,刚好16行,没层输出2行,所以一共8层(5卷积+3全连接)。
所以,我们可以对某一个层的权重进行可视化了,继续往test.cpp文件中添加代码
//对第一个卷积层进行可视化,第一个卷积层"conv1"的维度信息是96*3*11*11,即96个卷积核,每个卷积核是3通道的,每个卷积核尺寸为11*11//故我们可以认为,该卷积层有96个图,每个图是11*11的三通道BGR图像int ii=0; //我们提前第1层的参数,此时为conv1层int width=params[ii]->shape(2); //宽度,第一个卷积层为11 int height=params[ii]->shape(3); //高度,第一个卷积层为11 int num=params[ii]->shape(0); //卷积核的个数,第一个卷积层为96
//我们将num个图,放在同一张大图上进行显示,此时用OpenCV进行可视化,声明一个大尺寸的图片,使之能容纳所有的卷积核图int imgHeight=(int)(1+sqrt(num))*height; //大图的尺寸int imgWidth=(int)(1+sqrt(num))*width;Mat img1(imgHeight,imgWidth,CV_8UC3,Scalar(0,0,0));//同时,我们注意到各层的权值,是一个可正可负的实数,而在OpenCV里的一般图片,每个像素的值在0~255之间//因为我们还需要对权值进行归一化到0~255才能正常显示float maxValue=-1000,minValue=10000;const float* tmpValue=params[ii]->cpu_data(); //获取该层的参数,实际上是一个一维数组for(int i=0;i<params[ii]->count();i++){ //求出最大最小值 maxValue=std::max(maxValue,tmpValue[i]); minValue=std::min(minValue,tmpValue[i]);}//对最终显示的大尺寸图片,进行逐个像素赋值int kk=0; //此时在画第kk个卷积核for(int y=0;y<imgHeight;y+=height){ for(int x=0;x<imgWidth;x+=width){ if(kk>=num) continue; Mat roi=img1(Rect(x,y,width,height)); for(int i=0;i<height;i++){ for(int j=0;j<width;j++){ for(int k=0;k<3;k++){ float value=params[ii]->data_at(kk,k,i,j);
roi.at<Vec3b>(i,j)[k]=(value-minValue)/(maxValue-minValue)*255; //归一化到0~255} } } ++kk; }}resize(img1,img1,Size(500,500)); //将显示的大图,调整为500*500尺寸imshow("conv1",img1); //显示waitKey(0);
此时,第一个卷积层的96个权重图如上所示,可以看出,这个跟用python或者matlab接口可视化的权重是一样的。
- caffe之网络权重可视化(C++实现)
- 深度学习Caffe实战(16)MATLAB实现模型参数权重可视化
- 深度学习Caffe实战笔记(17)MATLAB实现卷积层卷积核权重的可视化
- 【Caffe特征图可视化】【caffemodel 权重图】
- Caffe网络可视化
- Caffe 网络结构可视化
- Caffe-网络结构可视化
- caffe网络结构可视化
- Caffe 网络结构可视化
- caffe网络结构可视化
- Caffe 的可视化 (二)网络结构可视化
- caffe学习笔记14-caffe可视化特征与权重
- caffe模型weights&featureMap 可视化(c++)
- caffe for windows的matlab接口(三):权重和特征图的可视化
- caffe for windows的matlab接口(四):权重和特征图可视化的一个例子
- caffe中带权重的softmaxloss实现(一)
- 【caffe-matlab】权重以及特征图的可视化
- 【caffe-matlab】权重以及特征图的可视化
- 关于equal和==
- 中石油多校联赛(最后一水) Pong’s Birds(dp)
- JavaScript中的闭包
- 做好网站结构优化细节,只需4点
- java-对象的多态
- caffe之网络权重可视化(C++实现)
- nginx+tomcat负载均衡以及redis共享session综合解决方案(By Centos 7)
- python如何查看编码类型
- sikuli在selenium的应用
- Spring MVC 下设置默认访问页面的3种方式
- c-free 5.0 菜单,工具条丢失解决
- Android全局获取Context
- 亚马逊的VR购物新体验!网购者的福利来了!
- 2017年省赛前最后一水---A题