caffe总结

作者:Fiberleif
链接:http://www.zhihu.com/question/27982282/answer/94031317
来源:知乎
著作权归作者所有,转载请联系作者获得授权。

Caffe's Abstract Framework:
就像楼上一些回答里说到的,要读懂caffe,首先要熟悉Blob,Layer,Net,Solver这几个大类。这四个大类自下而上,环环相扣,贯穿了整个caffe的结构,下面先分别简单地介绍一下这四个类的主要作用。
  • Blob:作为数据传输的媒介,无论是网络权重参数,还是输入数据,都是转化为Blob数据结构来存储
  • Layer:作为网络的基础单元,神经网络中层与层间的数据节点、前后传递都在该数据结构中被实现,层类种类丰富,比如常用的卷积层、全连接层、pooling层等等,大大地增加了网络的多样性
  • Net:作为网络的整体骨架,决定了网络中的层次数目以及各个层的类别等信息
  • Solver:作为网络的求解策略,涉及到求解优化问题的策略选择以及参数确定方面,修改这个模块的话一般都会是研究DL的优化求解的方向。
================================================================
Caffe's Concrete Framework:
1. Blob:
1.1. Blob的类型描述
Caffe内部采用的数据类型主要是对protocol buffer所定义的数据结构的继承,因此可以在尽可能小的内存占用下获得很高的效率,虽然追求性能的同时Caffe也会牺牲了一些代码可读性。
直观来说,可以把Blob看成一个有4维的结构体(包含数据和梯度),而实际上,它们只是一维的指针而已,其4维结构通过shape属性得以计算出来。
1.2. Blob的重要成员函数和变量
shared_ptr data_ //数据
shared_ptr diff_ //梯度
void Blob::Reshape(const int num, const int channels, const int height,
const int width)
重新修改Blob的形状(4维),并根据形状来申请动态内存存储数据和梯度。
inline int count(int start_axis, int end_axis) const
计算Blob所需要的基本数据单元的数量。 2. Layer:
2.1. Layer的类型描述

Layer是网络模型和计算的核心,在数据存储上,主要分成bottom_vecs、top_vecs、weights&bias三个部分;在数据传递上,也主要分为LayerSetUp、Reshape、Forward、Backward四个过程,符合直观上对层与层之间连接的理解,贴切自然。
2.2. Layer的重要成员函数和变量
vector loss_ //每一层都会有一个loss值,但只有LossLayer才会产生非0的loss
vector > > blobs_ //Layer所学习的参数,包括权值和偏差
virtual void LayerSetUp(const vector*>& bottom,
      const vector*>& top) 
通过bottom Blob对象的形状以及LayerParameter(从prototxt读入)来确定Layer的学习参数(以Blob类型存储)的形状。
 virtual void Reshape(const vector*>& bottom,
      const vector*>& top) 
通过bottom Blob对象的形状以及Layer的学习参数的形状来确定top Blob对象的形状。
virtual void Forward(const vector*> &bottom,                     
                     vector*> *top) = 0
Layer内部数据正向传播,从bottom到top方向。
virtual void Backward(const vector*> &top,
                      const vector &propagate_down, 
                      vector*> *bottom) = 0
Layer内部梯度反向传播,从top到bottom方向。
3. Net:
3.1. Net的类型描述
Net用容器的形式将多个Layer有序地放在一起,其自身实现的功能主要是对逐层Layer进行初始化,以及提供Update( )的接口(更新网络参数),本身不能对参数进行有效地学习过程。
3.2. Net的重要成员函数和变量
vector > > layers_ //构成该net的layers
vector*> > bottom_vecs_ //每一层layer中的bottom Blobs
vector*> > top_vecs_ //每一层layer中的top Blobs
vector > > params_ //整个net中的learnable parameter
void Init(const NetParameter& param)
根据NetParameter进行net初始化,简单的来说就是先把网络中所有层的bottom Blobs&top Blobs(无重复)实例化,并从输入层开始,逐层地进行Setup的工作,从而完成了整个网络的搭建,为后面的数据前后传输打下基础。
vector*>& Forward(const vector* > & bottom,
                              Dtype* loss = NULL)
void Net::Backward()
是对整个网络的前向和方向传导,各调用一次就可以计算出网络的loss了。
4. Solver
4.1. Solver的类型描述
Solver类中包含一个Net的指针,主要是实现了训练模型参数所采用的优化算法,根据优化算法的不同会派生不同的类,而基于这些子类就可以对网络进行正常的训练过程。
4.2. Solver的重要成员函数和变量
shared_ptr > net_ //net对象
void Step(int iters)
对已初始化后的网络进行固定次数的训练迭代过程。
ComputeUpdateValue();
net_->Update();

不同的模型训练方法通过重载函数ComputeUpdateValue( )实现计算update参数的核心功能。
===============================================================
说到这儿,大家可能已经对Caffe的自底向上的主要结构有了一个大致的了解~
除了这些之外呢,Caffe里面还涉及到了许多特色模块,比如google的轻量级高效数据传输工具protobuf、负责stream输出模块的glog和负责命令行便捷输入的gflags、factory宏定义等等...
最后想在这里向caffe的contributors以及caffe blog的博主们表示深深的感激~ 由于本人的C++经验不多,所以是花了较长的时间才大致理解caffe的实现(呜呜TT),但现在回头想来确实收获很大,不管是在代码架构方面,还是在实现细节方面,caffe都有很多值得借鉴的地方,相信大家在阅读完caffe之后也一定会受益匪浅~~~

你可能感兴趣的:(AI学习)