Caffe源码阅读——Net组装
- 了解作为一个成熟的CNN模型框架需要考虑的一些问题;
- 如果想对网络结构做扩展,如写一个新的Layer,其中的一些数据是如何在Layer和Net之间流动的
- layer_factory.hpp:77] Creating layer conv1
- net.cpp:92] Creating Layer conv1
- net.cpp:428] conv1 <- data
- net.cpp:402] conv1 -> conv1
- net.cpp:144] Setting up conv1
- net.cpp:151] Top shape: 64 20 24 24 (737280)
- net.cpp:159] Memory required for data: 3752192
这其中第一行是创建这个Layer实例的代码,具体的创建过程在layer_factory里面。为了方便创建Layer,Caffe采用了工厂方法的设计模式,只要提供Layer的名字(在配置文件中参数叫type),就可以根据名字和对应参数实例化一个Layer。这部分的细节只要认真看一下就会明白。
第3,4行显示了创建当前层的bottom和top数据的过程。这里涉及到net.cpp中的AppendBottom和AppendTop两个方法,因为每一个bottom blob和top blob都有名字,这里就将他们之间的关系输出在了这里。
第5行看上去没什么干货,但是它代表了Layer的Setup函数已经调用完成(或者Layer被share)。Layer的Setup函数是Layer初始化的关键函数,这里面涉及到以下几个具体的操作:
- CheckBlobCounts(bottom, top);
- LayerSetUp(bottom, top);
- Reshape(bottom, top);
- SetLossWeights(top);
总结地说,这四句完成了:
- 对bottom blob, top blob数量的检查,父类实现。
- 对Layer内部相关变量的初始化,由具体的子类实现
- 传入时bottom blob的维度已经确定,Layer需要根据自己要做的计算确定top blob的纬度。比方说这一层是卷积层,维度是20*5*5,输入图像是1*28*28,也就是bottom blob的维度,那么输出的维度就是20*24*24,这也是上面log里面算出的结果,只不过还加了一个batch size。这个函数由具体的子类实现。
- 对Layer是否输出loss以及输出loss要做的操作进行初始化。父类实现。必须说一句,Caffe中关于Loss Layer中Loss_weight,loss_,top.cpu_diff的数据设定还是有点绕且有点trick的。
好了回到上面的log。接下来的那一句告诉了我们top层应该输出的维度。这里输出了维度就是为了让不放心的朋友算一下,看看和你想的是否一样。当然,输出这句log的循环不是只做了这件事,它的主要工作就是设置top blob的loss_weight。
最后一句计算了该层top blob所占用的内存。可以看出截至到这一层,内存消耗大约是3M多,还不算大。
好,这就是一个最典型的Layer的初始化,下面这个ReLU层就稍微有些不同了:
- layer_factory.hpp:77] Creating layer relu1
- net.cpp:92] Creating Layer relu1
- net.cpp:428] relu1 <- ip1
- net.cpp:389] relu1 -> ip1 (in-place)
- net.cpp:144] Setting up relu1
- net.cpp:151] Top shape: 64 500 (32000)
- net.cpp:159] Memory required for data: 5769472
这里面最不同的就是第4行结尾的(in-place),这说明relu的bottom blob和top blob是同一个数据,这和我们在网络中的定义是一样的。in-place的好处就是减少内存的操作,但是这里在统计内存消耗时并没有考虑in-place带来的节省。
接下来就是共享网络的conv1_p了:
- layer_factory.hpp:77] Creating layer conv1_p
- net.cpp:92] Creating Layer conv1_p
- net.cpp:428] conv1_p <- data_p
- net.cpp:402] conv1_p -> conv1_p
- net.cpp:144] Setting up conv1_p
- net.cpp:151] Top shape: 64 20 24 24 (737280)
- net.cpp:159] Memory required for data: 8721664
- net.cpp:488] Sharing parameters 'conv1_w' owned by layer 'conv1', param index 0
- net.cpp:488] Sharing parameters 'conv1_b' owned by layer 'conv1', param index 1
这一段最有特点的是最后两句“Sharing”,因为siamese model中拥有参数完全相同的两个网络,所以在构建时候,第二个网络检测到参数名字已经存在,说明该层的参数和其他层共享,于是在这里打印出来告诉用户这一点。当然,这一句之前没有打印出来的内容告诉了我们,实际上Net类中还负责了参数相关的初始化。这部分的内容实际上还挺多,除了参数共享,还有对参数learning rate,weight decay的设定。

时间:2018-08-05 01:23 来源: 转发量:次
声明:本站部分作品是由网友自主投稿和发布、编辑整理上传,对此类作品本站仅提供交流平台,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,不为其版权负责。如果您发现网站上有侵犯您的知识产权的作品,请与我们取得联系,我们会及时修改或删除。
相关文章:
相关推荐:
网友评论: