Caffe使用教程
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Caffe使用教程相关的知识,希望对你有一定的参考价值。
Caffe官网:http://caffe.berkeleyvision.org/
初始化网络
1 #include "caffe/caffe.hpp" 2 #include <string> 3 #include <vector> 4 using namespace caffe; 5 6 char *proto = "H:\\Models\\Caffe\\deploy.prototxt"; /* 加载CaffeNet的配置 */ 7 Phase phase = TEST; /* or TRAIN */ 8 Caffe::set_mode(Caffe::CPU); 9 // Caffe::set_mode(Caffe::GPU); 10 // Caffe::SetDevice(0); 11 12 //! Note: 后文所有提到的net,都是这个net 13 boost::shared_ptr< Net<float> > net(new caffe::Net<float>(proto, phase));
加载已训练好的模型
1 char *model = "H:\\Models\\Caffe\\bvlc_reference_caffenet.caffemodel"; 2 net->CopyTrainedLayersFrom(model);
读取图像均值
1 char *mean_file = "H:\\Models\\Caffe\\imagenet_mean.binaryproto"; 2 Blob<float> image_mean; 3 BlobProto blob_proto; 4 const float *mean_ptr; 5 unsigned int num_pixel; 6 7 bool succeed = ReadProtoFromBinaryFile(mean_file, &blob_proto); 8 if (succeed) 9 { 10 image_mean.FromProto(blob_proto); 11 num_pixel = image_mean.count(); /* NCHW=1x3x256x256=196608 */ 12 mean_ptr = (const float *) image_mean.cpu_data(); 13 }
根据指定数据,前向传播网络
1 //! Note: data_ptr指向已经处理好(去均值的,符合网络输入图像的长宽和Batch Size)的数据 2 void caffe_forward(boost::shared_ptr< Net<float> > & net, float *data_ptr) 3 { 4 Blob<float>* input_blobs = net->input_blobs()[0]; 5 switch (Caffe::mode()) 6 { 7 case Caffe::CPU: 8 memcpy(input_blobs->mutable_cpu_data(), data_ptr, 9 sizeof(float) * input_blobs->count()); 10 break; 11 case Caffe::GPU: 12 cudaMemcpy(input_blobs->mutable_gpu_data(), data_ptr, 13 sizeof(float) * input_blobs->count(), cudaMemcpyHostToDevice); 14 break; 15 default: 16 LOG(FATAL) << "Unknown Caffe mode."; 17 } 18 net->ForwardPrefilled(); 19 }
根据Feature层的名字获取其在网络中的Index
1 //! Note: Net的Blob是指,每个层的输出数据,即Feature Maps 2 // char *query_blob_name = "conv1"; 3 unsigned int get_blob_index(boost::shared_ptr< Net<float> > & net, char *query_blob_name) 4 { 5 std::string str_query(query_blob_name); 6 vector< string > const & blob_names = net->blob_names(); 7 for( unsigned int i = 0; i != blob_names.size(); ++i ) 8 { 9 if( str_query == blob_names[i] ) 10 { 11 return i; 12 } 13 } 14 LOG(FATAL) << "Unknown blob name: " << str_query; 15 }
读取网络指定Feature层数据
1 //! Note: 根据CaffeNet的deploy.prototxt文件,该Net共有15个Blob,从data一直到prob 2 char *query_blob_name = "conv1"; /* data, conv1, pool1, norm1, fc6, prob, etc */ 3 unsigned int blob_id = get_blob_index(net, query_blob_name); 4 5 boost::shared_ptr<Blob<float> > blob = net->blobs()[blob_id]; 6 unsigned int num_data = blob->count(); /* NCHW=10x96x55x55 */ 7 const float *blob_ptr = (const float *) blob->cpu_data();
根据Layer的名字获取其在网络中的Index
1 //! Note: Layer包括神经网络所有层,比如,CaffeNet共有23层 2 // char *query_layer_name = "conv1"; 3 unsigned int get_layer_index(boost::shared_ptr< Net<float> > & net, char *query_layer_name) 4 { 5 std::string str_query(query_layer_name); 6 vector< string > const & layer_names = net->layer_names(); 7 for( unsigned int i = 0; i != layer_names.size(); ++i ) 8 { 9 if( str_query == layer_names[i] ) 10 { 11 return i; 12 } 13 } 14 LOG(FATAL) << "Unknown layer name: " << str_query; 15 }
读取指定Layer的权重数据
1 //! Note: 不同于Net的Blob是Feature Maps,Layer的Blob是指Conv和FC等层的Weight和Bias 2 char *query_layer_name = "conv1"; 3 const float *weight_ptr, *bias_ptr; 4 unsigned int layer_id = get_layer_index(net, query_layer_name); 5 boost::shared_ptr<Layer<float> > layer = net->layers()[layer_id]; 6 std::vector<boost::shared_ptr<Blob<float> >> blobs = layer->blobs(); 7 if (blobs.size() > 0) 8 { 9 weight_ptr = (const float *) blobs[0]->cpu_data(); 10 bias_ptr = (const float *) blobs[1]->cpu_data(); 11 } 12 13 //! Note: 训练模式下,读取指定Layer的梯度数据,与此相似,唯一的区别是将cpu_data改为cpu_diff
修改某层的Weight数据
1 const float* data_ptr; /* 指向待写入数据的指针, 源数据指针*/ 2 float* weight_ptr = NULL; /* 指向网络中某层权重的指针,目标数据指针*/ 3 unsigned int data_size; /* 待写入的数据量 */ 4 char *layer_name = "conv1"; /* 需要修改的Layer名字 */ 5 6 unsigned int layer_id = get_layer_index(net, query_layer_name); 7 boost::shared_ptr<Blob<float> > blob = net->layers()[layer_id]->blobs()[0]; 8 9 CHECK(data_size == blob->count()); 10 switch (Caffe::mode()) 11 { 12 case Caffe::CPU: 13 weight_ptr = blob->mutable_cpu_data(); 14 break; 15 case Caffe::GPU: 16 weight_ptr = blob->mutable_gpu_data(); 17 break; 18 default: 19 LOG(FATAL) << "Unknown Caffe mode"; 20 } 21 caffe_copy(blob->count(), data_ptr, weight_ptr); 22 23 //! Note: 训练模式下,手动修改指定Layer的梯度数据,与此相似 24 // mutable_cpu_data改为mutable_cpu_diff,mutable_gpu_data改为mutable_gpu_diff
保存新的模型
1 char* weights_file = "bvlc_reference_caffenet_new.caffemodel"; 2 NetParameter net_param; 3 net->ToProto(&net_param, false); 4 WriteProtoToBinaryFile(net_param, weights_file);
以上是关于Caffe使用教程的主要内容,如果未能解决你的问题,请参考以下文章