前一篇的测试程序只能编译通过,并不可用。
因为caffe windows版本默认的libcaffe是静态库,而静态库编译并不会把虚基类layer_factory和一系列子类包含进去。
这就导致在载入文件时会报错,无法识别layer的类型。
所以需要动态编译libcaffe。
1,首先当然把libcaffe工程配置类型从lib改成dll。但此时直接编译并不会产生lib文件,只有一个dll文件是不够用的。
2,做宏定义:这个宏定义需要添加到所有下面提到的hpp文件里
#ifdef BUILD_DLL
#define OS_API __declspec(dllexport)
#else
#define OS_API __declspec(dllimport)
#endif,
然后再预处理器定义BUILD_DLL,这是windows下编写dll的必经步骤。
3,对源码做一些改动,其实就是把一些接口类和方法的定义 里加上OS_API ,如下:
blob.hpp
class OS_API Blob
net.hpp
class OS_API Net
caffe.pb.h
class OS_API BlobShape
class OS_API BlobProto
class OS_API BlobProtoVector
class OS_API SolverParameter
class OS_API LayerParameter
class OS_API NetParameter
class OS_API FillerParameter
因为这个头文件是根据src\caffe\proto\caffe.proto自动生成的,所以编译的时候还把这个文件改了名字,否则就把修改后的caffe.pb.h又覆盖了
common.hpp
OS_API void GlobalInit(int* pargc, char*** pargv);
class OS_API Caffe
class OS_API RNG
io.hpp
OS_API bool ReadProtoFromTextFile(const char* filename, Message* proto);
OS_API bool ReadProtoFromBinaryFile(const char* filename, Message* proto);
OS_API void WriteProtoToBinaryFile
OS_API bool ReadImageToDatum
OS_API bool DecodeDatumNative(Datum* datum);
void OS_API WriteProtoToTextFile
db.hpp
class OS_API DB
OS_API DB* GetDB(DataParameter::DB backend);
OS_API DB* GetDB(const string& backend);
benchmark.hpp
class OS_API Timer
upgrade_proto.hpp
OS_API void ReadSolverParamsFromTextFileOrDie
OS_API bool NetNeedsUpgrade(const NetParameter& net_param);
OS_API bool UpgradeNetAsNeeded(const string& param_file, NetParameter* param);
OS_API bool SolverNeedsTypeUpgrade(const SolverParameter& solver_param);
OS_API boolbool UpgradeSolverAsNeeded(const string& param_file, SolverParameter* param);
signal_handler.h
class OS_API SignalHandler
solver.hpp
class OS_API Solver
parallel.hpp
class OS_API P2PSync
layer.hpp
class OS_API Layer
math_functions.hpp
OS_API unsigned int caffe_rng_rand();
OS_API Dtype caffe_cpu_dot(const int n, const Dtype* x, const Dtype* y);
OS_API void caffe_rng_gaussian
OS_API void caffe_rng_bernoulli(const int n, const Dtype p, int* r);
OS_API void caffe_rng_bernoulli(const int n, const Dtype p, unsigned int* r);
OS_API void caffe_copy(const int N, const Dtype *X, Dtype *Y);
OS_API void caffe_set(const int N, const Dtype alpha, Dtype *X);
OS_API void caffe_rng_uniform(const int n, const Dtype a, const Dtype b, Dtype* r);
syncedmem.hpp
class OS_API SyncedMemory
相比上一篇里提到的dll,这个libcaffe.dll使用还需要加上lmdb.dll。
这次,终于能使用caffe训练好的模型了。
这样改动会导致testall工程编译错误。
因为该工程直接调用了很多layer类型,而在实际使用的时候,我们只需要定义虚基类layer,所以layer目录下的类我并没有都添加到接口里。