caffe框架结构介绍

这几天开始开始忙着找工作的事情,由于简历中写道熟悉深度学习框架caffe,为避免在面试的时候问及caffe框架相关的问题,就对caffe的框架进行重温一遍。

第三方依赖库

caffe安装需要的依赖包比较多,下面介绍这些依赖包的用途:

  • protobuffer:用户建立统一的参数描述文件(proto),然后利用protoc编译就能让协议(prototxt)等部分关键代码自动生成,节省大量开发,调试代码时间。
  • boost:caffe中使用了boost中的智能指针,其自带引用计数功能,可避免共享指针时造成的内存泄漏问题;
  • gflags:命令行参数解析;
  • glog:用于记录应用程序日志;
  • openBLAS:负责caffe中CPU端的数值计算(如矩阵、向量的乘法运算),由于调用量相当大,该库的性能直接影响caffe的运行性能;
  • hfd5:存储不同类型的图像和数码数据;
  • OpenCV:计算机视觉库,包含大量图像处理函数,caffe使用这个完成图像存取和预处理功能;
  • lmdb和leveldb:将各种原始数据(jpeg图片,二进制数据等)转化为key-value存储,便于caffe快速获取这些数据;
  • snappy:压缩和解压缩;

结构

Caffe是一个深度学习框架,该框架主要包括四个组件组成:blobs,layers,nets、solver。因此可以从这四个层次进行理解:

Blob

Blob是一个四维连续数组(type = float32), 使用(n, c, h,w)表示的话,那么每一维的意思分别是:

  • n: number. 输入数据量,比如进行sgd时候的mini-batch大小。
  • c: channel. 如果是图像数据的话可以认为是通道数量。
  • h,w: height, width. 如果是图像数据的话可以认为是图片(或feature map)的高度和宽度。

Blob内部其实有两个字段data,diff.data表示流动数据(输出数据),而diff则存储BP的梯度。data/diff可以存储于cpu, 也可以存储于gpu。如果某个layer不支持gpu的话,那么就需要将gpu数据copy到cpu上,造成性能开销。对于python/numpy用户来说,可以用reshape函数来转换为blob:

Layer

caffe提供了许多内置layer,比如convolution layer, pool layer, dropout layer, nonlinearity layer等。这些层说明以及具体参数都可以在这里查看。每个layer有输入一些’bottom’ blobs, 输出一些’top’ blobs. 输入层是”data”和”label” blobs。每个层的定义有四个关键的函数:

  • LayerSetUp:初始化工作;
  • Reshape:数据输入大小类型转化;
  • Forward_cpu/Forward_gpu:前向传播;
  • Backward_cpu/Backward_gpu:反向传播/计算梯度;

另外,部分data layer还支持预处理操作。

Net

Net是layers组成的DAG, 并且可以使用文本格式来描述(比如lenet_train_test.prototxt)。Net有个初始化函数Init(),它的作用有两个:1)创建blosb和layers; 2) 调用layers的SetUp函数来初始化layers。

Solver

负责深度网络的训练,主要目的就是协调模型的优化,solver优化一个模型的方法是:首先通过调用前向传播来获得输出和损失,然后通过调用反向传播产生模型的梯度,将梯度和权值更新后相结合来最小化损失。此外通过solver.prototxt(例如lenet_solver.prototxt)文件指定优化方法,以及一些超参数,以及保存模型。

上面只是简单地从理论层面上对caffe架构以及模型进行重温和介绍,更深入地理解必须结合caffe源码做进一步地分析,如果要深入理解的话,还是建议阅读以下源码。

参考
https://dirtysalt.github.io/html/caffe.html