版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014230646/article/details/51934150

如何使用Caffe

Caffe教程(http://robots.princeton.edu/courses/COS598/2015sp/slides/Caffe/caffe_tutorial.pdf)

预备知识

Google Protocol Buffer

https://developers.google.com/protocol-buffers/docs/cpptutorial 
Caffe数据的读取、运算、存储都是采用Google Protocol Buffer来进行的。PB是一种轻便、高效的结构化数据存储格式,可以用于结构化数据串行化,很适合做数据存储或 RPC 数据交换格式。它可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。是一种效率和兼容性都很优秀的二进制数据传输格式,目前提供了 C++、Java、Python 三种语言的 API。Caffe采用的是C++和Python的API。

转载自https://github.com/shicai/Caffe_Manual/blob/master/ReadMe.md

初始化网络

#include "caffe/caffe.hpp"
#include <string>
#include <vector>
using namespace caffe;char *proto = "H:\\Models\\Caffe\\deploy.prototxt"; /* 加载CaffeNet的配置 */
Phase phase = TEST; /* or TRAIN */
Caffe::set_mode(Caffe::CPU);
// Caffe::set_mode(Caffe::GPU);
// Caffe::SetDevice(0);//! Note: 后文所有提到的net,都是这个net
boost::shared_ptr< Net<float> > net(new caffe::Net<float>(proto, phase));

加载已训练好的模型

char *model = "H:\\Models\\Caffe\\bvlc_reference_caffenet.caffemodel";
net->CopyTrainedLayersFrom(model);

读取模型中的每层的结构配置参数

char *model = "H:\\Models\\Caffe\\bvlc_reference_caffenet.caffemodel";
NetParameter param;
ReadNetParamsFromBinaryFileOrDie(model, &param);
int num_layers = param.layer_size();
for (int i = 0; i < num_layers; ++i)
{// 结构配置参数:name,type,kernel size,pad,stride等LOG(ERROR) << "Layer " << i << ":" << param.layer(i).name() << "\t" << param.layer(i).type();if (param.layer(i).type() == "Convolution"){ConvolutionParameter conv_param = param.layer(i).convolution_param();LOG(ERROR) << "\t\tkernel size: " << conv_param.kernel_size()<< ", pad: " << conv_param.pad()<< ", stride: " << conv_param.stride();}
}

读取图像均值

char *mean_file = "H:\\Models\\Caffe\\imagenet_mean.binaryproto";
Blob<float> image_mean;
BlobProto blob_proto;
const float *mean_ptr;
unsigned int num_pixel;bool succeed = ReadProtoFromBinaryFile(mean_file, &blob_proto);
if (succeed)
{image_mean.FromProto(blob_proto);num_pixel = image_mean.count(); /* NCHW=1x3x256x256=196608 */mean_ptr = (const float *) image_mean.cpu_data();
}

根据指定数据,前向传播网络

//! Note: data_ptr指向已经处理好(去均值的,符合网络输入图像的长宽和Batch Size)的数据
void caffe_forward(boost::shared_ptr< Net<float> > & net, float *data_ptr)
{Blob<float>* input_blobs = net->input_blobs()[0];switch (Caffe::mode()){case Caffe::CPU:memcpy(input_blobs->mutable_cpu_data(), data_ptr,sizeof(float) * input_blobs->count());break;case Caffe::GPU:cudaMemcpy(input_blobs->mutable_gpu_data(), data_ptr,sizeof(float) * input_blobs->count(), cudaMemcpyHostToDevice);break;default:LOG(FATAL) << "Unknown Caffe mode.";} net->ForwardPrefilled();
}

根据Feature层的名字获取其在网络中的Index

//! Note: Net的Blob是指,每个层的输出数据,即Feature Maps
// char *query_blob_name = "conv1";
unsigned int get_blob_index(boost::shared_ptr< Net<float> > & net, char *query_blob_name)
{std::string str_query(query_blob_name);    vector< string > const & blob_names = net->blob_names();for( unsigned int i = 0; i != blob_names.size(); ++i ) { if( str_query == blob_names[i] ) { return i;} }LOG(FATAL) << "Unknown blob name: " << str_query;
}

读取网络指定Feature层数据

//! Note: 根据CaffeNet的deploy.prototxt文件,该Net共有15个Blob,从data一直到prob
char *query_blob_name = "conv1"; /* data, conv1, pool1, norm1, fc6, prob, etc */
unsigned int blob_id = get_blob_index(net, query_blob_name);boost::shared_ptr<Blob<float> > blob = net->blobs()[blob_id];
unsigned int num_data = blob->count(); /* NCHW=10x96x55x55 */
const float *blob_ptr = (const float *) blob->cpu_data();

根据文件列表,获取特征,并存为二进制文件

详见get_features.cpp文件:

主要包括三个步骤 
- 生成文件列表,格式与训练用的类似,每行一个图像 
包括文件全路径、空格、标签(没有的话,可以置0) 
- 根据train_val或者deploy的prototxt,改写生成feat.prototxt 
主要是将输入层改为image_data层,最后加上prob和argmax(为了输出概率和Top1/5预测标签) 
- 根据指定参数,运行程序后会生成若干个二进制文件,可以用MATLAB读取数据,进行分析

根据Layer的名字获取其在网络中的Index

//! Note: Layer包括神经网络所有层,比如,CaffeNet共有23层
// char *query_layer_name = "conv1";
unsigned int get_layer_index(boost::shared_ptr< Net<float> > & net, char *query_layer_name)
{std::string str_query(query_layer_name);    vector< string > const & layer_names = net->layer_names();for( unsigned int i = 0; i != layer_names.size(); ++i ) { if( str_query == layer_names[i] ) { return i;} }LOG(FATAL) << "Unknown layer name: " << str_query;
}

读取指定Layer的权重数据

//! Note: 不同于Net的Blob是Feature Maps,Layer的Blob是指Conv和FC等层的Weight和Bias
char *query_layer_name = "conv1";
const float *weight_ptr, *bias_ptr;
unsigned int layer_id = get_layer_index(net, query_layer_name);
boost::shared_ptr<Layer<float> > layer = net->layers()[layer_id];
std::vector<boost::shared_ptr<Blob<float>  >> blobs = layer->blobs();
if (blobs.size() > 0)
{weight_ptr = (const float *) blobs[0]->cpu_data();bias_ptr = (const float *) blobs[1]->cpu_data();
}//! Note: 训练模式下,读取指定Layer的梯度数据,与此相似,唯一的区别是将cpu_data改为cpu_diff

修改某层的Weight数据

const float* data_ptr;          /* 指向待写入数据的指针, 源数据指针*/
float* weight_ptr = NULL;       /* 指向网络中某层权重的指针,目标数据指针*/
unsigned int data_size;         /* 待写入的数据量 */
char *layer_name = "conv1";     /* 需要修改的Layer名字 */unsigned int layer_id = get_layer_index(net, query_layer_name);
boost::shared_ptr<Blob<float> > blob = net->layers()[layer_id]->blobs()[0];CHECK(data_size == blob->count());
switch (Caffe::mode())
{
case Caffe::CPU:weight_ptr = blob->mutable_cpu_data();break;
case Caffe::GPU:weight_ptr = blob->mutable_gpu_data();break;
default:LOG(FATAL) << "Unknown Caffe mode";
}
caffe_copy(blob->count(), data_ptr, weight_ptr);//! Note: 训练模式下,手动修改指定Layer的梯度数据,与此相似
// mutable_cpu_data改为mutable_cpu_diff,mutable_gpu_data改为mutable_gpu_diff

保存新的模型

char* weights_file = "bvlc_reference_caffenet_new.caffemodel";
NetParameter net_param;
net->ToProto(&net_param, false);
WriteProtoToBinaryFile(net_param, weights_file);

Caffe中添加新的层

https://github.com/BVLC/caffe/wiki/Development 

用预训练网络参数初始化

caffe的参数初始化是根据名字从caffemodel读取的,只要修改名字,自己想要修改的层就能随机初始化。

  • 修改名字,保留前面几层的参数,同时后面的参数设置较高的学习率,基础学习率大概0.00001左右。

学习Caffe(二)使用Caffe:Caffe加载模型+Caffe添加新层+Caffe finetune相关推荐

  1. Tensorflow学习(二)之——保存加载模型、Saver的用法

    1. Saver的背景介绍 我们经常在训练完一个模型之后希望保存训练的结果,这些结果指的是模型的参数,以便下次迭代的训练或者用作测试.Tensorflow针对这一需求提供了Saver类. Saver类 ...

  2. OpenGL教程翻译 第二十二课 使用Assimp加载模型

    第二十二课 使用Assimp加载模型 原文地址:http://ogldev.atspace.co.uk/(源码请从原文主页下载) 背景 到现在为止我们都在使用手动生成的模型.正如你所想的,指明每个顶点 ...

  3. mxnet保存模型,加载模型来预测新数据

    mxnet保存模型,以及用模型来预测新数据 我们希望训练好之后的模型,可以保存下来,然后需要预测新数据的时候,就可以拿来用,可以这样做.  我们以线性回归的例子来讲:  1,训练并保存模型. impo ...

  4. OpenGL深入探索——使用Assimp加载模型

    转载自:第二十二课 使用Assimp加载模型 背景 到现在为止我们都在使用手动生成的模型.正如你所想的,指明每个顶点的位置和其他属性有点时候并不是十分方便.对于一个箱子.锥体和简单平面还好,但是像人们 ...

  5. Spring Boot基础学习笔记04:Spring Boot加载自定义配置文件

    文章目录 零.学习目标 1.熟悉使用@PropertySource加载配置文件 2.熟悉使用@ImportResource加载XML配置文件 3.掌握使用@Configuration编写自定义配置类 ...

  6. 网页怎么预先加载模型_使用预先训练的模型进行转移学习

    网页怎么预先加载模型 深度学习 (Deep Learning) 什么是转学? (What is Transfer Learning?) Transfer learning is a research ...

  7. Android4.0图库Gallery2代码分析(二) 数据管理和数据加载

    Android4.0图库Gallery2代码分析(二) 数据管理和数据加载 2012-09-07 11:19 8152人阅读 评论(12) 收藏 举报 代码分析android相册优化工作 Androi ...

  8. away3d 4.0.9Gold 学习笔记 加载模型(6)

    学习笔记提供模型和贴图请勿用于商业用途. 1 package 2 { 3 import away3d.containers.ObjectContainer3D; 4 import away3d.con ...

  9. jQuery-瀑布流-绝对定位布局(二)(延迟AJAX加载图片)

    jQuery-瀑布流-绝对定位布局(二)(延迟AJAX加载图片) 瀑布流-绝对定位布局,与浮动布局的区别在于 1.布局不一样: 绝对定位:一个UL里面放置所有的绝对定位的LI: 浮动布局:多个(一般三 ...

最新文章

  1. 多名分析师上调苹果目标股价,网络推广外包下苹果发展前景仍可观
  2. ios开发基础之通讯录系统实战-20
  3. Java关于Properties用法的总结(一)
  4. sans serif_Sans和Serif相遇可爱
  5. 30分钟掌握 C#7
  6. Codeforces 835 F Roads in the Kingdom(树形dp)
  7. 移动Web体验月报(6月):MIP 核心代码升级,增加基于 Vue 开发能力
  8. PHP强制类型定义数组,php – 如何强制Doctrine更新数组类型字段?
  9. lucene索引并搜索mysql数据库[转]
  10. css修改输入框的placeholder颜色
  11. android开发之自定义AutoCompleteTextView
  12. 单片机原理及应用c语言版答案,单片机原理及应用(C语言版(周国运)习题答案.doc...
  13. 1 常见的HTTP股票数据接口整理 腾讯 新浪 网易 2019-08-02
  14. Chrome 网页长截图
  15. IIS 发生未知FastCGI错误:0x80070005
  16. 【bug】修复YYC松鼠短视频系统V2.7版本bug 注册输入验证码提示邀请码,输入邀请码提示错误
  17. [单调栈 扫描线] BZOJ 4826 [Hnoi2017]影魔
  18. android tf卡及u盘_android8.1系统修改第三方app无法读写U盘或者内部SD卡的问题
  19. Qt组件-QLabel
  20. 会议论文扩展摘要写作指南 conference extended abstract

热门文章

  1. boost::mpl::not_equal_to相关的测试程序
  2. Boost.MultiIndex 复合键的例子
  3. boost::fusion::make_unfused用法的测试程序
  4. boost::diagnostic_information_what的用法程序
  5. GDCM:将文件封装在RawData中的测试程序
  6. Boost:实现了k-means聚类算法
  7. boost::callable_traits的return_type_t的测试程序
  8. VTK:小部件之AngleWidget2D
  9. VTK:Rendering之Mace
  10. VTK:相互作用之Game