新建VS工程,根据自己实际的目录进行下面的配置(即类似于Caffe工程中matlab子工程的配置拷贝)。
E:\caffe-windows\src
E:\caffe-windows\scripts\build\libraries\include\boost-1_61
E:\caffe-windows\scripts\build\libraries\include
E:\caffe-windows\scripts\build\include
E:\caffe-windows\scripts\build\libraries\include\opencv
D:\python\python2.7.12\include
D:\python\python2.7.12\lib\site-packages\numpy\core\include
E:\caffe-windows\include
E:\caffe-windows\scripts\build
E:\caffe-windows\scripts\build\libraries\Include
..\build\lib\Release\caffe.lib
..\build\lib\Release\proto.lib
..\build\libraries\lib\boost_system-vc140-mt-1_61.lib
..\build\libraries\lib\boost_thread-vc140-mt-1_61.lib
..\build\libraries\lib\boost_filesystem-vc140-mt-1_61.lib
..\build\libraries\lib\boost_chrono-vc140-mt-1_61.lib
..\build\libraries\lib\boost_date_time-vc140-mt-1_61.lib
..\build\libraries\lib\boost_atomic-vc140-mt-1_61.lib
..\build\libraries\lib\boost_python-vc140-mt-1_61.lib
..\build\libraries\lib\glog.lib
..\build\libraries\lib\gflags.lib
shlwapi.lib
..\build\libraries\lib\libprotobuf.lib
..\build\libraries\lib\caffehdf5_hl.lib
..\build\libraries\lib\caffehdf5.lib
..\build\libraries\lib\lmdb.lib
ntdll.lib
..\build\libraries\lib\leveldb.lib
..\build\libraries\lib\snappy_static.lib
..\build\libraries\lib\caffezlib.lib
..\build\libraries\x64\vc14\lib\opencv_highgui310.lib
..\build\libraries\x64\vc14\lib\opencv_imgcodecs310.lib
..\build\libraries\x64\vc14\lib\opencv_imgproc310.lib
..\build\libraries\x64\vc14\lib\opencv_core310.lib
..\build\libraries\lib\libopenblas.dll.a
D:\python\python2.7.12\libs\python27.lib
..\build\libraries\lib\libboost_filesystem-vc140-mt-1_61.lib
..\build\libraries\lib\libboost_system-vc140-mt-1_61.lib
..\build\libraries\lib\libboost_date_time-vc140-mt-1_61.lib
..\build\lib\Debug\caffe-d.lib
..\build\lib\Debug\proto-d.lib
..\build\libraries\lib\libboost_system-vc140-mt-gd-1_61.lib
..\build\libraries\lib\boost_thread-vc140-mt-gd-1_61.lib
..\build\libraries\lib\libboost_filesystem-vc140-mt-gd-1_61.lib
..\build\libraries\lib\boost_chrono-vc140-mt-gd-1_61.lib
..\build\libraries\lib\libboost_date_time-vc140-mt-gd-1_61.lib
..\build\libraries\lib\boost_atomic-vc140-mt-gd-1_61.lib
..\build\libraries\lib\boost_python-vc140-mt-gd-1_61.lib
..\build\libraries\lib\glogd.lib
..\build\libraries\lib\gflagsd.lib
..\build\libraries\lib\libprotobufd.lib
..\build\libraries\lib\caffehdf5_hl_D.lib
..\build\libraries\lib\caffehdf5_D.lib
..\build\libraries\lib\lmdbd.lib
..\build\libraries\lib\leveldbd.lib
..\build\libraries\lib\snappy_staticd.lib
..\build\libraries\lib\caffezlibd.lib
..\build\libraries\x64\vc14\lib\opencv_core310d.lib
..\build\libraries\x64\vc14\lib\opencv_imgproc310d.lib
..\build\libraries\x64\vc14\lib\opencv_imgcodecs310d.lib
..\build\libraries\x64\vc14\lib\opencv_highgui310d.lib
..\build\libraries\lib\libopenblas.dll.a
D:\python\python2.7.12\libs\python27.lib
shlwapi.lib
ntdll.lib
设置Debug模式,我们就可以调试Caffe代码,跟踪到源程序,来深入的学习Caffe.
E:\caffe-windows\scripts\build\tools\Release
E:\caffe-windows\scripts\build\libraries\bin
E:\caffe-windows\scripts\build\libraries\lib
E:\caffe-windows\scripts\build\libraries\x64\vc14\bin
// VS2015
#include "stdafx.h"
#define CPU_ONLY
/* caffe.ph.h 和caffe.pb.cc用于解析Caffe参数配置文件,将模型权值序列化和反序列化到磁盘的协议接口*/
/* add : _CRT_SECURE_NO_WARNINGS 到预处理命令 */
#include
#include
#include
#include
#include
#include
using namespace std;
using google::protobuf::io::FileInputStream;
using google::protobuf::io::FileOutputStream;
using google::protobuf::io::ZeroCopyInputStream;
using google::protobuf::io::CodedInputStream;
using google::protobuf::io::ZeroCopyOutputStream;
using google::protobuf::io::CodedOutputStream;
using google::protobuf::Message;
#include
#include //for windows
int main(void)
{
const char* filename = "solver.prototxt";
caffe::SolverParameter solver_param;
FILE * fp = fopen(filename, "r");
int fd = _open(filename, O_RDONLY);
if(fp == NULL)
{
cout << "File not found :" << filename << endl;
}
FileInputStream * input = new FileInputStream(fd);
bool success = google::protobuf::TextFormat::Parse(input, &solver_param);
delete input;
_close(fd);
cout << "Solver Mode = " << solver_param.solver_mode() << endl;
cout << "Device id = " << solver_param.device_id() << endl;
cout << "Solver Type = " << solver_param.solver_type() << endl;
cout << "Rondom Seed = " << solver_param.random_seed() << endl;
//cout << "Train net param = " << solver_param.train_net_param() << endl;
cout << "Max iter = " << solver_param.max_iter() << endl;
cout << "Test interval = " << solver_param.test_interval() << endl;
cout << "Momentum = " << solver_param.momentum()<< endl;
cout << "gamam = " << solver_param.gamma() << endl;
cout << "End " << endl;
}
#include "stdafx.h"
#define CPU_ONLY //没有安装cuda
#include
#include
#include
/* Tip: libboost_filesystem-vc140-mt-1_61.lib,将其添加*/
#include //write blob to proto
using namespace caffe;
using namespace std;
int main(void)
{
Blob<float> a;
cout << "Size : " << a.shape_string() << endl;
a.Reshape(1, 2, 3, 4);
cout << "Size: " << a.shape_string() << endl;
//change value of a
float *p = a.mutable_cpu_data();
for (int i = 0; i < a.count(); i++)
{
p[i] = i;
}
cout << "a.count = " << a.count() << endl;
//print a
for (int u = 0; u < a.num(); u++) // image number
{
for (int v = 0; v < a.channels(); v++) //image channels
{
for (int y = 0; y < a.height(); y++) // image height
{
for (int x = 0; x < a.width(); x++) // image width
{
cout << "a[" << u << "][" << v << "][" << y << "][" << x << "] = " << a.data_at(u, v, y, x) << endl;
}
}
}
}
// L1 norm and L2 norm
cout << "ASUM = " << a.asum_data() << endl; //abs sum
cout << "SUMSQ = " << a.sumsq_data() << endl; // sum sqrt
/* change blob's diff*/
float *q = a.mutable_cpu_diff();
for (int i = 0; i < a.count(); i++)
{
q[i] = a.count() - 1 - i;
}
a.Update(); // a = a - diff
//print a
for (int u = 0; u < a.num(); u++) // image number
{
for (int v = 0; v < a.channels(); v++) //image channels
{
for (int y = 0; y < a.height(); y++) // image height
{
for (int x = 0; x < a.width(); x++) // image width
{
cout << "a[" << u << "][" << v << "][" << y << "][" << x << "] = " << a.data_at(u, v, y, x) << endl;
}
}
}
}
/*将Blob内部的值保存到磁盘或者从磁盘载入内存,可以分别通过ToProto(),FromProto()实现*/
BlobProto bp;
a.ToProto(&bp, true);// 将a序列化,连同diff(默认不带)
WriteProtoToBinaryFile(bp, "a.blob");
BlobProto bp2;
ReadProtoFromBinaryFileOrDie("a.blob", &bp2);
Blob<float> b;
b.FromProto(bp2, true);
// print b
for (int u = 0; u < a.num(); u++) // image number
{
for (int v = 0; v < a.channels(); v++) //image channels
{
for (int y = 0; y < a.height(); y++) // image height
{
for (int x = 0; x < a.width(); x++) // image width
{
cout << "b[" << u << "][" << v << "][" << y << "][" << x << "] = " << b.data_at(u, v, y, x) << endl;
}
}
}
}
return 0;
}
#pragma once
#ifndef CAFFE_REG_H
#define CAFFE_REG_H
#include "caffe/common.hpp"
#include "caffe/layers/input_layer.hpp"
#include "caffe/layers/inner_product_layer.hpp"
#include "caffe/layers/dropout_layer.hpp"
#include "caffe/layers/conv_layer.hpp"
#include "caffe/layers/relu_layer.hpp"
#include "caffe/layers/pooling_layer.hpp"
#include "caffe/layers/lrn_layer.hpp"
#include "caffe/layers/softmax_layer.hpp"
//#include "caffe/layers/normalize_layer.hpp"
//#include "caffe/layers/permute_layer.hpp"
#include "caffe/layers/flatten_layer.hpp"
//#include "caffe/layers/prior_box_layer.hpp"
#include "caffe/layers/concat_layer.hpp"
#include "caffe/layers/reshape_layer.hpp"
#include "caffe/layers/softmax_layer.hpp"
//#include "caffe/layers/detection_output_layer.hpp"
namespace caffe
{
extern INSTANTIATE_CLASS(InputLayer);
//REGISTER_LAYER_CLASS(Input);
//extern INSTANTIATE_CLASS(ConvolutionLayer);
//REGISTER_LAYER_CLASS(Convolution);
extern INSTANTIATE_CLASS(InnerProductLayer);
extern INSTANTIATE_CLASS(DropoutLayer);
//extern INSTANTIATE_CLASS(ReLULayer);
//REGISTER_LAYER_CLASS(ReLU);
//extern INSTANTIATE_CLASS(PoolingLayer);
//REGISTER_LAYER_CLASS(Pooling);
//extern INSTANTIATE_CLASS(LRNLayer);
//REGISTER_LAYER_CLASS(LRN);
//extern INSTANTIATE_CLASS(SoftmaxLayer);
//REGISTER_LAYER_CLASS(Softmax);
//extern INSTANTIATE_CLASS(NormalizeLayer);
//REGISTER_LAYER_CLASS(Normalize);
//extern INSTANTIATE_CLASS(PermuteLayer);
//REGISTER_LAYER_CLASS(Permute);
//extern INSTANTIATE_CLASS(FlattenLayer);
//extern INSTANTIATE_CLASS(PriorBoxLayer);
//extern INSTANTIATE_CLASS(ConcatLayer);
//extern INSTANTIATE_CLASS(ReshapeLayer);
//extern INSTANTIATE_CLASS(SoftmaxLayer);
//REGISTER_LAYER_CLASS(Softmax);
//extern INSTANTIATE_CLASS(DetectionOutputLayer);
}
#endif
//http://blog.csdn.net/birdwcp/article/details/53580068
#include"stdafx.h"
#define CPU_ONLY
#include"caffe_reg.h"
#include
#include
#include
using namespace caffe;
using namespace std;
int main(void)
{
string proto("deploy.prototxt");
Net<float> nn(proto, caffe::TEST);
vector<string> bn = nn.blob_names(); //获得Net中所有Blob对象
vector<string> ln = nn.layer_names();
for (int i = 0; i < bn.size(); i++)
{
cout << "Blob # " << i << ":" << bn[i] << endl;
}
for (int i = 0; i < ln.size(); i++)
{
cout << "Layer # " << i << ":" << ln[i] << endl;
}
return 0;
}
从上面的例子我们可以看出,Net中即包括了Layer对象,又包括了Blob对象。其中Blob对象用于存放每个Layer输入/输出的中间结果,Layer则根据Net描述对指定的输入Blob进行某种计算处理(卷积,下采样,全连接,非线性变换,计算代价函数等),输出的结果放在指定的Blob中,由于输入Blob和输出Blob可能为同一个,所以上面给出的Layer24个,而Blob只有15个。
补充:
caffe.lib 静态库的编译: 仅需要头文件和源文件。
C++/常规/附加包含目录。
F:\vs\caffe-windows\src;
F:\vs\caffe-windows\scripts\build\libraries\include\boost-1_61;
F:\vs\caffe-windows\scripts\build\libraries\include;
F:\vs\caffe-windows\scripts\build\include;
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\include;
F:\vs\caffe-windows\scripts\build\libraries\include\opencv;
D:\Python27\include;
D:\Python27\lib\site-packages\numpy\core\include;
F:\vs\caffe-windows\include;
F:\vs\caffe-windows\scripts\build;
F:\vs\caffe-windows\scripts\build\libraries\Include;
%(AdditionalIncludeDirectories)
编译动态库时.pyd,如:会把连接的静态库编译进去,因此需要 【连接器-输入-附加依赖项】。
参考文献
1.深度学习21天实战Caffe.pdf