caffe-工具箱

caffe使用工具

caffe 编译后生成动态链接库 libcaffe.so。使用caffe时,在main.cpp中调用相应API,编译时包含对应的头文件,链接时加入 libcaffe.so。如此才是一个完整的caffe应用。

在tools/中就是一些调用libcaffe.so的工具源码。

前面提到过,caffe.bin工具由4个功能:

1
2
3
4
./caffe.bin train           #train or finetune a model
./caffe.bin test #score a model
./caffe.bin device_query #show GPU diagnostic information
./caffe.bin time #benchmark model execution time

tools/caffe.cpp中看看是如何实现传递不同的参数,执行不同的功能。

首先定义一个caffe命令注册表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
typedef int (*BrewFunction)();
typedef std::map<caffe::string, BrewFunction> BrewMap;
BrewMap g_brew_map;

#define RegisterBrewFunction(func) \
namespace { \
class __Registerer_##func { \
public: /* NOLINT */ \
__Registerer_##func() { \
g_brew_map[#func] = &func; \
} \
}; \
__Registerer_##func g_registerer_##func; \
}

device_query命令:

1
2
3
4
5
6
7
8
9
10
11
int device_query() {
LOG(INFO) << "Querying GPUs " << FLAGS_gpu;
vector<int> gpus;
get_gpus(&gpus); // TODO
for (int i = 0; i < gpus.size(); ++i) {
caffe::Caffe::SetDevice(gpus[i]);
caffe::Caffe::DeviceQuery();
}
return 0;
}
RegisterBrewFunction(device_query);

train命令

1
2
int train() {...}
RegisterBrewFunction(train);

test命令

1
2
int test() {...}
RegisterBrewFunction(test);

time命令

1
2
int time() {...}
RegisterBrewFunction(time);

上述将4条命令加入注册表。

从注册表中取对应的命令:

1
2
3
4
5
static BrewFunction GetBrewFunction(const caffe::string& name) {
if (g_brew_map.count(name)) {
return g_brew_map[name];
} else {...}
}

从main函数中调用:

1
2
3
4
5
6
7
8
9
10
11
12
int main(int argc, char** argv) {
...
gflags::SetUsageMessage("command line brew\n"
"usage: caffe <command> <args>\n\n"
"commands:\n"
" train train or finetune a model\n"
" test score a model\n"
" device_query show GPU diagnostic information\n"
" time benchmark model execution time");
...
return GetBrewFunction(caffe::string(argv[1]))();
}

如上实现了在caffe.bin工具中执行不同的命令。

还有其他工具:特征提取,图像格式转换,计算图像均值,等等。

编写自己的工具

编写自己的工具帮助理解 caffe 框架和操作。

caffe中的GPU实现

其实caffe不需要手动编写CUDA程序,而是直接使用cuBLAS实现数学计算,相当于CPU端的OpenBLASMKL计算库。

上述是从数学计算角度,而对于DL中常见算子,如卷积,下采样等,在cuDNN中都已实现。