前面在solver的层面把caffe的整体运行流程梳理了一遍.今天接着来梳理Net部分.

Net的入口

说Net的入口,自然要从solver说起.在solver.cpp找你可以找到如下清晰的流程:
Solver()构造函数  ->  Init(param)  ->  InitTrainNet()  ->  net_.reset(new Net(net_param))

Net::Init()

通过Net入口,就开始构造net了.而Net的构造函数里最重要的就是Init(param).下面详细说一下它干了什么活.

网络参数预处理

重要通过以下两个函数:

FilterNet(in_param, &filtered_param): 过滤*.prototxt文件中不符合规则的层.

InsertSplits(filtered_param, &param): 当下一层有两个网络时,把当前层分裂成两份.

网络构造

这里就是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 框图