博客

http://blog.csdn.net/seven_first/article/details/47378697

https://zhuanlan.zhihu.com/p/25127756?refer=xiaoleimlnote

https://github.com/BUPTLdy/Caffe_Code_Analysis/tree/master/

学习计划

Caffe运行主要流程


caffe.cpp

// A simple registry for caffe commands.
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; \
}
  • typedef int (*BrewFunction)()

    函数指针:可用于处理一些参数和返回值一致,但是功能不一样一组函数。

    本示例:定义了一组函数指针,函数参数为(),但是返回值为int这样一组函数指针族。
  • typedef std::map<caffe::string, BrewFunction> BrewMap

    定义BrewMap为一个map,key为string,value为函数指针(参数为(),返回为int)。
  • #define RegisterBrewFunction(func)

    该宏命令完成一次注册的初始化操作; 其中在宏中#和##符号表示的意思如下: #:用来把参数转换成字符串;

    ##:用来连接前后两个参数。

以caffe中RegisterBrewFunction(train)为例,上面代码可转换为:

#define RegisterBrewFunction(train) \
namespace { \
class __Registerer_train { \
public: /* NOLINT */ \
__Registerer_train() { \
g_brew_map["train"] = &train; \
} \
}; \
__Registerer_train g_registerer_train; \
} //完成了全局变量的初始化操作

接来下看caffe.cpp里的main函数代码

int main(int argc, char** argv) {
// Print output to stderr (while still logging).
FLAGS_alsologtostderr = 1;
// Set version
gflags::SetVersionString(AS_STRING(CAFFE_VERSION));
// Usage message.
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");
// Run tool or show usage.
caffe::GlobalInit(&argc, &argv);
if (argc == 2) {
#ifdef WITH_PYTHON_LAYER
try {
#endif
return GetBrewFunction(caffe::string(argv[1]))();
#ifdef WITH_PYTHON_LAYER
} catch (bp::error_already_set) {
PyErr_Print();
return 1;
}
#endif
} else {
gflags::ShowUsageWithFlagsRestrict(argv[0], "tools/caffe");
}
}

caffe控制台训练示例:caffe train --solver==*.prototxt

输入完全正确的情况下,函数首先进入:

  • return GetBrewFunction(caffe::string(argv[1]))();
static BrewFunction GetBrewFunction(const caffe::string& name) {
if (g_brew_map.count(name)) {
return g_brew_map[name];
} else {
LOG(ERROR) << "Available caffe actions:";
for (BrewMap::iterator it = g_brew_map.begin();
it != g_brew_map.end(); ++it) {
LOG(ERROR) << "\t" << it->first;
}
LOG(FATAL) << "Unknown action: " << name;
return NULL; // not reachable, just to suppress old compiler warnings.
}
}

总结:

  • C++函数指针的应用;函数指针可用于解决 函数参数和返回值一致,但功能不一样的一群函数族
  • 进入主函数前,通过全局变量注册函数的方法;

举例:

#include <iostream>
#include <map> typedef int (*mathfunc)(int,int);
typedef std::map<std::string, mathfunc> BrepMap;
BrepMap g_brew_map; #define RegisterMathFunc(func) \
namespace { \
class __Register_##func{ \
public: \
__Register_##func() { g_brew_map[#func] = &func;}};\
__Register_##func g_register_##func;} int add(int a, int b){
return a+b;
}
RegisterMathFunc(add) int sub(int a, int b){
return a-b;
}
RegisterMathFunc(sub) int mul(int a, int b){
return a*b;
}
RegisterMathFunc(mul) int main()
{
std::cout<< "number of register functions: " << g_brew_map.size() << std::endl;
std::string math_method = "add";
std::cout << "23 + 12 = " << g_brew_map[math_method](23,12) << std::endl;
return 1;
} /*
*******result*******
number of register functions: 3
23 + 12 = 35
*/

caffe学习笔记1的更多相关文章

  1. Caffe学习笔记2--Ubuntu 14.04 64bit 安装Caffe(GPU版本)

    0.检查配置 1. VMWare上运行的Ubuntu,并不能支持真实的GPU(除了特定版本的VMWare和特定的GPU,要求条件严格,所以我在VMWare上搭建好了Caffe环境后,又重新在Windo ...

  2. Caffe学习笔记(三):Caffe数据是如何输入和输出的?

    Caffe学习笔记(三):Caffe数据是如何输入和输出的? Caffe中的数据流以Blobs进行传输,在<Caffe学习笔记(一):Caffe架构及其模型解析>中已经对Blobs进行了简 ...

  3. Caffe学习笔记(二):Caffe前传与反传、损失函数、调优

    Caffe学习笔记(二):Caffe前传与反传.损失函数.调优 在caffe框架中,前传/反传(forward and backward)是一个网络中最重要的计算过程:损失函数(loss)是学习的驱动 ...

  4. Caffe学习笔记(一):Caffe架构及其模型解析

    Caffe学习笔记(一):Caffe架构及其模型解析 写在前面:关于caffe平台如何快速搭建以及如何在caffe上进行训练与预测,请参见前面的文章<caffe平台快速搭建:caffe+wind ...

  5. Caffe学习笔记4图像特征进行可视化

    Caffe学习笔记4图像特征进行可视化 本文为原创作品,未经本人同意,禁止转载,禁止用于商业用途!本人对博客使用拥有最终解释权 欢迎关注我的博客:http://blog.csdn.net/hit201 ...

  6. Caffe学习笔记3

    Caffe学习笔记3 本文为原创作品,未经本人同意,禁止转载,禁止用于商业用途!本人对博客使用拥有最终解释权 欢迎关注我的博客:http://blog.csdn.net/hit2015spring和h ...

  7. Caffe 学习笔记1

    Caffe 学习笔记1 本文为原创作品,未经本人同意,禁止转载,禁止用于商业用途!本人对博客使用拥有最终解释权 欢迎关注我的博客:http://blog.csdn.net/hit2015spring和 ...

  8. Caffe学习笔记2

    Caffe学习笔记2-用一个预训练模型提取特征 本文为原创作品,未经本人同意,禁止转载,禁止用于商业用途!本人对博客使用拥有最终解释权 欢迎关注我的博客:http://blog.csdn.net/hi ...

  9. CAFFE学习笔记(五)用caffe跑自己的jpg数据

    1 收集自己的数据 1-1 我的训练集与测试集的来源:表情包 由于网上一幅一幅图片下载非常麻烦,所以我干脆下载了两个eif表情包.同一个表情包里的图像都有很强的相似性,因此可以当成一类图像来使用.下载 ...

  10. CAFFE学习笔记(四)将自己的jpg数据转成lmdb格式

    1 引言 1-1 以example_mnist为例,如何加载属于自己的测试集? 首先抛出一个问题:在example_mnist这个例子中,测试集是人家给好了的.那么如果我们想自己试着手写几个数字然后验 ...

随机推荐

  1. 前端导出csv

    前端导出csv export: function(data, name) { // csv文件的BOM头 \ufeff可以让excel等识别出csv文件的编码 var uri = 'data:text ...

  2. 前端上传图片回显并用base64编码,后端做解码储存,存储图片路径在.properties文件中配置(以上传身份证照片为例)

    前端页面:<form id="kycForm" enctype="multipart/form-data"> <input type=&quo ...

  3. Node - centOS配置环境

    1.安装依赖包:yum install gcc-c++ openssl-devel (gcc版本查询:gcc -v ,为 4.4.7-11:python版本查询:python –version 为2. ...

  4. AOP统一处理Web请求日志

    <!--aop--> <dependency> <groupId>org.springframework.boot</groupId> <arti ...

  5. 中间件和Django缓存

    中间件定义: 中间件是一个.一个的管道,如果相对任何所有的通过Django的请求进行管理都需要自定义中间件 中间件可以对进来的请求和出去的请求进行控制 中间件是一类. 看下面的代码在settings里 ...

  6. python如何输出文件的年月日

    import time print('{}BiasedMF312and4414_rt.txt'.format(time.strftime("%Y-%m-%d"))) 输出: 201 ...

  7. 群晖NAS同步文件,防止Mac OS X自动休眠的办法

    背景: NAS drive同步文件到移动硬盘,需要消耗很长时间.但长时间不动电脑,mac又会自动关闭所有application,进入休眠模式,导致同步任务被终止. 使用系统的节能设置配置也没能成功关闭 ...

  8. 小程序 iphone X 吸底按钮适配

    问题图: 解决方法: // app.js App({   isIphoneX() {     let isIphoneX = false     wx.getSystemInfo({       su ...

  9. USD在CentOS7.0操作系统下的安装方法

    最近Pixar的开源USD软件很火,官方在Introduce中明确讲到这个软件的设计开发目标是增强艺术家协作,减少不确定因素,最大化资产版本迭代效率,追求更大的承载能力. 当今行业中传统的线性的制作方 ...

  10. DNS搭建

    构建主从服务DNS 1.主服务名字:ns1.amber.com #hostname ns1.amber.com bash 刷新一下 #bash 2.Vim /etc/hosts 3.Vim /etc/ ...