Caffe源码分析之Net
前面在solver的层面把caffe的整体运行流程梳理了一遍.今天接着来梳理Net部分.
Net的入口
说Net的入口,自然要从solver说起.在solver.cpp找你可以找到如下清晰的流程:
Solver()构造函数 -> Init(param) -> InitTrainNet() -> net_.reset(new Net
Net::Init()
通过Net入口,就开始构造net了.而Net的构造函数里最重要的就是Init(param).下面详细说一下它干了什么活.
网络参数预处理
重要通过以下两个函数:
FilterNet(in_param, &filtered_param): 过滤*.prototxt文件中不符合规则的层.
InsertSplits(filtered_param, ¶m): 当下一层有两个网络时,把当前层分裂成两份.
网络构造
这里就是Init函数的主体代码.
for
CreateLayer(layer_param). 构成一层.
AppendBottom()构造每层输入blob
AppendTop(()构造每层输出blob
SetUp()为上面的blob分配内存
AppendParam()初始化网络权重(weights)
粗略设置backward flag
以上for循环创建了各层网络,并分配数据以及连接起来,构成整个网络
层与层的连接是怎么实现的:每一层的Bottom blob其实就是一个指针,指向上一层的Top blob(它才是真正分配了内存),因此连接起来了.
网络参数后处理
修正backward设置,例如有些对loss没影响的输入无需反向求导.
构建map,以供solver选择.
共享权重处理
Net的其他函数
主要是net.cpp中的一些函数,由于caffe更新频繁,不保证一下函数不同版本都有.
Forward和Backward相关函数
这里以Forward为例,主要有如下函数:
ForwardFromTo(): 从某层到另一层进行前向运算
ForwardFrom(): 从某层到网络结束进行前向运算
ForwardTo(): 从网络最开始到某层进行前向运算
Forward(): 从网络开始到网络结束进行前向运算
注意:这些函数只是调用layer的forward运算
剩余函数
大多是layer,blob整体的操作,也都不涉及具体实现,已经数据转换操作.例如:各种CopyTrainedLayers函数,ToProto,ToHDF5,has_blob等等
强力推荐以下博文:
caffe::net::init()函数代码详细注解
caffe net.cpp梳理
caffe Net 框图