caffe学习笔记1
博客
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的更多相关文章
- Caffe学习笔记2--Ubuntu 14.04 64bit 安装Caffe(GPU版本)
0.检查配置 1. VMWare上运行的Ubuntu,并不能支持真实的GPU(除了特定版本的VMWare和特定的GPU,要求条件严格,所以我在VMWare上搭建好了Caffe环境后,又重新在Windo ...
- Caffe学习笔记(三):Caffe数据是如何输入和输出的?
Caffe学习笔记(三):Caffe数据是如何输入和输出的? Caffe中的数据流以Blobs进行传输,在<Caffe学习笔记(一):Caffe架构及其模型解析>中已经对Blobs进行了简 ...
- Caffe学习笔记(二):Caffe前传与反传、损失函数、调优
Caffe学习笔记(二):Caffe前传与反传.损失函数.调优 在caffe框架中,前传/反传(forward and backward)是一个网络中最重要的计算过程:损失函数(loss)是学习的驱动 ...
- Caffe学习笔记(一):Caffe架构及其模型解析
Caffe学习笔记(一):Caffe架构及其模型解析 写在前面:关于caffe平台如何快速搭建以及如何在caffe上进行训练与预测,请参见前面的文章<caffe平台快速搭建:caffe+wind ...
- Caffe学习笔记4图像特征进行可视化
Caffe学习笔记4图像特征进行可视化 本文为原创作品,未经本人同意,禁止转载,禁止用于商业用途!本人对博客使用拥有最终解释权 欢迎关注我的博客:http://blog.csdn.net/hit201 ...
- Caffe学习笔记3
Caffe学习笔记3 本文为原创作品,未经本人同意,禁止转载,禁止用于商业用途!本人对博客使用拥有最终解释权 欢迎关注我的博客:http://blog.csdn.net/hit2015spring和h ...
- Caffe 学习笔记1
Caffe 学习笔记1 本文为原创作品,未经本人同意,禁止转载,禁止用于商业用途!本人对博客使用拥有最终解释权 欢迎关注我的博客:http://blog.csdn.net/hit2015spring和 ...
- Caffe学习笔记2
Caffe学习笔记2-用一个预训练模型提取特征 本文为原创作品,未经本人同意,禁止转载,禁止用于商业用途!本人对博客使用拥有最终解释权 欢迎关注我的博客:http://blog.csdn.net/hi ...
- CAFFE学习笔记(五)用caffe跑自己的jpg数据
1 收集自己的数据 1-1 我的训练集与测试集的来源:表情包 由于网上一幅一幅图片下载非常麻烦,所以我干脆下载了两个eif表情包.同一个表情包里的图像都有很强的相似性,因此可以当成一类图像来使用.下载 ...
- CAFFE学习笔记(四)将自己的jpg数据转成lmdb格式
1 引言 1-1 以example_mnist为例,如何加载属于自己的测试集? 首先抛出一个问题:在example_mnist这个例子中,测试集是人家给好了的.那么如果我们想自己试着手写几个数字然后验 ...
随机推荐
- angular 实现左侧和顶部固定定位布局
1 布局基于angular ng-zorro组件库实现 由于项目中使用了组件库并且要求响应式布局,卡在这个坑上两天,多次调试后终于解决 代码仅供参考,由于没有上传依赖的库和组件包无法直接运行,提供代码 ...
- jQuery基础之二
jQuery基础之二 jQuery的中文文档十分详细,并且权威.W3C的jQuery文档更加简单实用. jQuery 1.9.0 jQuery中文文档W3C的jQuery文档 jQuery操作DO ...
- 《DSP using MATLAB》Problem 7.15
用Kaiser窗方法设计一个台阶状滤波器. 代码: %% +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ...
- C++中关于字符串的一些API
参考资料:http://www.runoob.com/cplusplus/cpp-strings.html 一.前言 不管是在编写何种语言程序,需要从输入设备中获取数据的需求很频繁,在这类频繁的应用场 ...
- [R] [Johns Hopkins] R Programming -- week 4
#Generating normal distribution (Pseudo) random number x<-rnorm(10) x x2<-rnorm(10,2,1) x2 set ...
- dataframe基础
1 df[i] 其中i是0,1,2,3,... 此时选中的是dataframe的第i列 2 dataframe查看每一列是否有缺失值 temp = data.isnull().any() #列中 ...
- Dubbo和Spring Cloud
1.Dubbo和Spring Cloud区别 1).通信方式不同 Dubbo使用RPC通信,Spring Cloud使用Http RestFul方式 2) 组成部分不同 组件 Dubbo Spring ...
- zabbix批量添加被监控windows客户端
由于公司大部分用的是windows服务器,大概有50多台.如果是一台一台添加的话很是麻烦,如果数量更多的话那工作量可想而知.所以网络管理员通常都是非常懒的. 环境:公司虽是域环境,但是除了几台域服务器 ...
- vue 路由配置
1.不带参数的路由配置 及 跳转 //路由配置: { name: "a", path: "/a", component: a } 页面跳转: this.$r ...
- vue 中 相同的路由不会跳转,更改路由的办法
vue 开发的项目,路由跳转的时候,是相同的路由是不会跳转,页面也不会有更新的 有时候 必须要跳转怎么办, 更改一个参数,num,一直在改变.就可以进入了. this.$router.push({ p ...