main() 

  首先入口函数caffe.cpp

 int main(int argc, char** argv) {
......
if (argc == ) {
#ifdef WITH_PYTHON_LAYER
try {
#endif
return GetBrewFunction(caffe::string(argv[]))(); //根据输入参数确定是train还是test,采用string到函数指针的映射实现,非常巧妙
#ifdef WITH_PYTHON_LAYER
} catch (bp::error_already_set) {
PyErr_Print();
return ;
}
#endif
} else {
gflags::ShowUsageWithFlagsRestrict(argv[], "tools/caffe");
}
}

  在main函数中GetBrewFunction函数调用了通过工厂模式生成的由string到函数指针的map

 typedef int (*BrewFunction)();
typedef std::map<caffe::string, BrewFunction> BrewMap;
BrewMap g_brew_map;

  在train、test、device_query、time函数后面都可以看到对这些函数的register,相当于这些函数指针已经在map中存在了

 RegisterBrewFunction(train);
RegisterBrewFunction(test);
RegisterBrewFunction(device_query);
RegisterBrewFunction(time);

train()

  接着是train过程

 // Train / Finetune a model.
int train() {
......
caffe::SolverParameter solver_param;
caffe::ReadSolverParamsFromTextFileOrDie(FLAGS_solver, &solver_param);//从-solver参数读取solver_param
......
shared_ptr<caffe::Solver<float> >
solver(caffe::SolverRegistry<float>::CreateSolver(solver_param));//从参数创建solver,同样采用string到函数指针的映射实现,用到了工厂模式 if (FLAGS_snapshot.size()) {//迭代snapshot次后保存模型一次
LOG(INFO) << "Resuming from " << FLAGS_snapshot;
solver->Restore(FLAGS_snapshot.c_str());
} else if (FLAGS_weights.size()) {//若采用finetuning,则拷贝weight到指定模型
CopyLayers(solver.get(), FLAGS_weights);
} if (gpus.size() > ) {
caffe::P2PSync<float> sync(solver, NULL, solver->param());
sync.Run(gpus);
} else {
LOG(INFO) << "Starting Optimization";
solver->Solve();//开始训练网络
}
LOG(INFO) << "Optimization Done.";
return ;
}

Solver()

  看CreateSolver函数是如何构建solver和net的,CreateSolver定义在solver_factory.hpp中,首先需要知道的是solver是一个基类,继承自它的类有SGD等,下面的实现就可以根据param的type构造一个指向特定solver的指针,比如SGD。

 static Solver<Dtype>* CreateSolver(const SolverParameter& param) {
const string& type = param.type();
CreatorRegistry& registry = Registry();
CHECK_EQ(registry.count(type), ) << "Unknown solver type: " << type
<< " (known types: " << SolverTypeListString() << ")";
return registry[type](param);
}

  关键之处在于上面代码最后一行语句,它的作用是根据配置文件创建对应的Solver对象(默认为SGDSolver子类对象)。此处工厂模式和一个关键的宏REGISTER_SOLVER_CLASS(SGD)发挥了重要作用。

 #define REGISTER_SOLVER_CLASS(type)
template <typename Dtype>
Solver<Dtype>* Creator_##type##Solver(
const SolverParameter& param)
{
return new type##Solver<Dtype>(param);
}
REGISTER_SOLVER_CREATOR(type, Creator_##type##Solver)
}

  这样一个SGDSolver对象就调用其构造函数被构造出来了。

 explicit SGDSolver(const SolverParameter& param)
: Solver<Dtype>(param) { PreSolve(); }

  同时,Solver这个基类也被构造出来了,在solver.hpp里

 explicit Solver(const SolverParameter& param,
const Solver* root_solver = NULL);

  Solver构造函数又会调用Init进行训练网络和测试网络的初始化,Init函数没有被声明为虚函数,不能被覆写,也就是说所有的solver都调用这个函数进行初始化。

 template <typename Dtype>
void Solver<Dtype>::Init(const SolverParameter& param) {
......
// Scaffolding code
InitTrainNet();//初始化训练网络
if (Caffe::root_solver()) {
InitTestNets();//初始化测试网络
LOG(INFO) << "Solver scaffolding done.";
}
iter_ = ;//迭代次数设为0
current_step_ = ;
}

InitTrainNet()

  接下来看训练网络初始化函数InitTrainNet,具体的内容见Net的网络层的构建(源码分析)

  caffe是如何来solve的:在成员函数Solve()内部,

 template <typename Dtype>
void Solver<Dtype>::Solve(const char* resume_file) {
......
// For a network that is trained by the solver, no bottom or top vecs
// should be given, and we will just provide dummy vecs.
int start_iter = iter_;
//开始迭代
Step(param_.max_iter() - iter_);
......
}

Step()

  下面我们看一下Solver::Step()函数内部实现情况,具体的一次迭代过程。见Caffe参数交换源码分析

  这就是整个网络的训练过程。

Caffe:深入分析(怎么训练)的更多相关文章

  1. 基于英特尔® 至强 E5 系列处理器的单节点 Caffe 评分和训练

    原文链接 在互联网搜索引擎和医疗成像等诸多领域,深度神经网络 (DNN) 应用的重要性正在不断提升. Pradeep Dubey 在其博文中概述了英特尔® 架构机器学习愿景. 英特尔正在实现 Prad ...

  2. 【caffe】执行训练

    @tags caffe 训练 是在windows平台上. 主要是使用/caffe.exe,配合动作参数train,以及指定solver文件.e.g.: cd %caffe_root% %caffe_b ...

  3. win10 caffe python Faster-RCNN训练自己数据集(转)

    一.制作数据集 1. 关于训练的图片 不论你是网上找的图片或者你用别人的数据集,记住一点你的图片不能太小,width和height最好不要小于150.需要是jpeg的图片. 2.制作xml文件 1)L ...

  4. caffe 利用VGG训练自己的数据

    写这个是因为有童鞋在跑VGG的时候遇到各种问题,供参考一下. 网络结构 以VGG16为例,自己跑的细胞数据 solver.prototxt: net: "/media/dl/source/E ...

  5. 【caffe】用训练好的imagenet模型分类图像

    因为毕设需要,我首先是用ffmpeg抽取某个宠物视频的关键帧,然后用caffe对这个关键帧中的物体进行分类. 1.抽取关键帧的命令: E:\graduation design\FFMPEG\bin&g ...

  6. 【神经网络与深度学习】深度学习实战——caffe windows 下训练自己的网络模型

    1.相关准备 1.1 手写数字数据集 这篇博客上有.jpg格式的图片下载,附带标签信息,有需要的自行下载,博客附带百度云盘下载地址(手写数字.jpg 格式):http://blog.csdn.net/ ...

  7. Caffe深入分析(源码)

    Caffe的整体流程图: 程序入口:main() int main(int argc, char** argv) { ..... ]))(); .... } g_brew_map实现过程,首先通过 t ...

  8. caffe + ssd网络训练过程

    參考博客:https://blog.csdn.net/xiao_lxl/article/details/79106837 1获取源代码:git clone https://github.com/wei ...

  9. 【caffe】mnist训练日志

    @tags caffe 前面根据train_lenet.sh改写了train_lenet.py后,在根目录下执行它,得到一系列输出,内容如下: I1013 10:05:16.721294 1684 c ...

随机推荐

  1. Window Operations详解

    window(windowLength, slideInterval):返回窗口长度为windowLength,每隔slideInterval滑动一次的window DStream countByWi ...

  2. sublime text 3基本参数设置及插件使用

    sublime text 3常用基本设置,包括插件,字体等一些配置.写个随笔,备忘. soda主题:特别喜欢: 插件:Color Highlighter输入颜色时,可以看到颜色. 在Color Hig ...

  3. win10系统中photoshop cs6中界面字体太小的解决方法

    win10系统中photoshop cs6中界面字体太小的解决方法 ps页面系统字体特别小,解决方法如下: 右键ps图标—属性—兼容性—勾选替代高dpi缩放行为,缩放执行选为默认,如果不行三个都试试

  4. CCPC-Wannafly Winter Camp Day1 爬爬爬山 (最短路)

    题目描述 爬山是wlswls最喜欢的活动之一. 在一个神奇的世界里,一共有nn座山,mm条路. wlswls初始有kk点体力,在爬山的过程中,他所处的海拔每上升1m1m,体力会减11点,海拔每下降1m ...

  5. 用递归将嵌套的JSON对象遍历出来,转为二维数组 或一维数组

    var map = new Array();//二维数组 var map2 = new Array();//一维数组 for (var i = 0; i < e.Data.length; i++ ...

  6. PHP使用HighChart生成股票K线图详解

    本人qq群也有许多的技术文档,希望可以为你提供一些帮助(非技术的勿加). QQ群:   281442983 (点击链接加入群:http://jq.qq.com/?_wv=1027&k=29Lo ...

  7. node项目实战-用node-koa2-mysql-bootstrap搭建一个前端论坛

    前言 在学习了koa2和express并写了一些demo后,打算自己写一个项目练练手,由于是在校生,没什么好的项目做,即以开发一个前端论坛为目标,功能需求参照一下一些社区拟定,主要有: 登录注册 个人 ...

  8. element和iView初步研究(-)

    element 1.可以通过npm 和使用cdn 2,支持多种语言组件 3.基本组件还是可以的 iView iView 是一套基于 Vue.js 的开源 UI 组件库,主要服务于 PC 界面的中后台产 ...

  9. LeetCode--617--合并二叉树(python)

    给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠. 你需要将他们合并为一个新的二叉树.合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 ...

  10. LeetCode--075--颜色分类(python)

    给定一个包含红色.白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色.白色.蓝色顺序排列. 此题中,我们使用整数 0. 1 和 2 分别表示红色.白色和蓝色. ...