解析./build/tools/caffe train --solver=examples/mnist/lenet_solver.prototxt

本文详细解析了Caffe深度学习框架的网络初始化过程及训练流程。从Solver、Net、Layer到Blob,层层深入,揭示了Caffe如何通过protobuf定义模型和求解策略,以及如何实现高效的模型训练。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

解析./build/tools/caffe train --solver=examples/mnist/lenet_solver.prototxt
第一个参数build/tools/caffe是Caffe框架的主要框架,由tools/caffe.cpp文件编译而来,第二个参数train表示是要训练网络,第三个参数是 solver的protobuf描述文件。
在Caffe中,网络模型的描述及其求解都是通过 protobuf 定义的,模型的参数也是通过 protobuf 实现加载和存储,包括 CPU 与 GPU 之间的无缝切换,不需要通过硬编码的方式实现。在caffe.cpp中main函数之外,通过宏RegisterBrewFunction将train(),test(),device_query(),time()等函数及其对应的函数指针添加到了g_brew_map中, 通过GetBrewFunction可以得到需要调用的函数的函数指针。

1.网络初始化过程

第二个参数train调用caffe.cpp中的int train()函数。在train函数中:

// caffe.cpp
shared_ptr<caffe::Solver<float>> solver(caffe::SolverRegistry<float>::CreateSolver(solver_param);

首先定义了一个指向Solver的shared_ptr,然后其通过调用SolverRegistry类的静态成员函数CreateSolver得到一个指向Solver的指针来构造shared_ptr类型的solver。
由于C++多态性,尽管solver是一个指向基类Solver类型的指针,通过solver这个智能指针来调用各个子类(SGDSolver等)的函数。在caffe.proto文件中默认的优化type为SGD,所以上面的代码会实例化一个SGDSolver的对象,SGDSolver类继承于Solver类,在新建SGDSolver对象时会调用其构造函数如下所示:

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

其中会先调用父类的Solver的构造函数。

//solver.cpp
template <typename Dtype>
Solver<Dtype>::Solver(const SolverParameter& param, const Solver* root_solver)
                : net_(), callbacks_(), root_solver_(root_solver),requested_early_exit_(false)
{
  Init(param);
}

Solver类的构造函数通过Init(param)函数来初始化网络。在Init(param)函数中,又主要是通过InitTrainNet()和InitTestNets()函数分别来搭建训练网络结构和测试网络结构。训练网络只能有一个,在InitTrainNet()函数中首先会设置一些基本参数,包括设置网络的状态为TRAIN,确定训练网络只有一个等,然后会通过net_.reset(new Net<Dtype>(net_param))新建了一个Net对象。新建了Net对象之后会调用Net类的构造函数:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值