zoukankan      html  css  js  c++  java
  • 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);
  • 相关阅读:
    CB文件读入后输出中文乱码问题
    2019-ICPC-沈阳站打铁感想
    计蒜客习题:画图游戏(Havel-Hakimi定理)
    计蒜客练习题:接龙(带权并查集)
    搜索----Dungeon Master
    最短路 poj1502 MPI Maelstrom
    poj 3259 Wormholes
    Silver Cow Party
    Til the Cows Come Home
    Cow Contest
  • 原文地址:https://www.cnblogs.com/kirai/p/5185071.html
Copyright © 2011-2022 走看看