Coder Social home page Coder Social logo

caffe_manual's Introduction

##Caffe使用教程 by Shicai Yang(@星空下的巫师)on 2015/08/06

初始化网络

#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_manual's People

Contributors

shicai avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

caffe_manual's Issues

如何只用cpu跑已经训练好的模型

前辈你好,小白下载了您offer的caffe_manual,并自己新建了工程拷贝进去,但我编译好了的是cpu_only版本的caffe.exe,我现在只想用您的程序测试一下已经训练好的模型,在main函数里面也改成了 Caffe::set_mode(Caffe::CPU);但是仍然报错,全都是说关于cuda的,如:error C1083: 无法打开包括文件: “cublas_v2.h”: No such file or directory ; IntelliSense: 未定义标识符 "cublasHandle_t" d:\caffe-windows-master\include\caffe\common.hpp 等等

而我根本不要用到cuda,怎么解决呢?万分感谢!

提升train mnist的准确率

博主你好哇,最近我刚入门CNN并安装了Caffe学习深度学习。我想请教一下,当初是如何设计CNN然后达到99.58的准确率呢?有没有办法再进一步提升这个准确率?是否通过增加网络的深度/filter的个数可以达到呢,而这个依据又是啥?非常感谢。

萌新请教 windows

vs下要导入哪些库与头文件啊,安装了caffe是否可以不用再安装opencv了。

一些关于运行test_caffe_manual.cpp的问题

1.请问test_caffe_manual.cpp这个程序是输入图片进行物体分类吗,还是只是进行caffemodel的测试?
2.还有我在windows下vs2013运行您的程序。早前已经配置好caffe的环境,各种第三方库也都基本可以用,一开始是boost的库lib没有加进去提示找不到lib,可是加进去了以后还是会出现【error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: __thiscall google::base::CheckOpMessageBuilder::CheckOpMessageBuilder(char const *)" (_imp??0CheckOpMessageBuilder@base@google@@QAE@PBD@Z),该符号在函数 "class std::basic_string<char,struct std::char_traits,class std::allocator >.........】。
我搜索了许多答案,换了boost1.59.0、1.57.0、1.55.0的库,还是会出现无法解析的外部符号。在下不得已来您这寻求解决方法...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.