Caffe学习(三)Caffe模型的结构

一总体结构

在caffe中,解决一个问题首先应该定义一个slover,反应到mnist例程中也就是lenet_solver.prototxt。该slover主要包括两部分,(1)为网络模型model,(2)为该模型参数的具体optimization方法及参数。model主要由各种layer组成,主要包括数据相关的DataLayer,图像滤波变换相关的VisionLayer,非线性激活函数ActivationLayer,各种损失函数LossLayer,以及其他常用Layer等。每一个layer保存的数据和layer之间互相传递的数据在caffe里都是以封装为blob格式。

二.blob数据单元

blob的内容

Caffe学习(三)Caffe模型的结构_第1张图片

其中blob里的数据有两种,一个为权值data,另一个为更新权值会用到的梯度diff,这两种数据都是要么存放在在CPU RAM里,要么存放在GPU RAM里

数据在blob里以类型的指针形式存放,该类型隐藏了cpu和gpu内存之间数据复制和传递同步的细节,一般情况下上层应用不用考虑。

类里,提供了两种取数据的方法,一种是容许使用的时候对数据发生更改,一种不容许。

const Dtype* cpu_data() const;
Dtype* mutable_cpu_data();

为了提高运算效率,blob的数据会选择性的在cpu和gpu之间复制,下面为实例

// Assuming that data are on the CPU initially, and we have a blob.
const Dtype* foo;
Dtype* bar;
foo = blob.gpu_data(); // data copied cpu->gpu.
foo = blob.cpu_data(); // no data copied since both have up-to-date contents.
bar = blob.mutable_gpu_data(); // no data copied.
// ... some operations ...
bar = blob.mutable_gpu_data(); // no data copied when we are still on GPU.
foo = blob.cpu_data(); // data copied gpu->cpu, since the gpu side has modified the data
foo = blob.gpu_data(); // no data copied since both have up-to-date contents
bar = blob.mutable_cpu_data(); // still no data copied.
bar = blob.mutable_gpu_data(); // data copied cpu->gpu.
bar = blob.mutable_cpu_data(); // data copied gpu->cpu.
由例子可知,只有当用户数据的Processor变化(由cpu到gpu或者gpu到cpu),且上一次使用数据的形式为mutable时才会发生copy。

三.Layer

在定义每一层时都定义了三种运算:setup,forward,backward

setup:初始化层和各连接权值

forward:该层的前向传递计算

backward:该层的后向传播

其中每一层的计算都可以以两种方式实现,cpu模式和gpu模式。一般是由cpu读入数据,然后传入gpu,运算完毕以后在由cpu写入到磁盘

当我们根据自己的应用要新添层时,主要就是在caffe.proto文件里添加新定义,并在cpp里写出该层的前向和后向计算函数,以及权值初始化函数


前向后向传播,以下图所示的网络为例,

前向传播即计算:,其中,即由X计算输出

梯度的后向传递:,先计算后面一层的梯度,再由链式法则计算前一层的权值梯度


Caffe学习(三)Caffe模型的结构_第2张图片


四.网络Net

网络都是由层和层的链接关系组成。有点需要注意

网络的结构不一定需要是线性的,可以是任意的DAG(有向无环图)


Caffe学习(三)Caffe模型的结构_第3张图片

五.Optimizing Solver优化算子

caffe提供的优化算法有以下几种:SGD,AdaDelta,AdaptiveGradient,Adam,Nesterov,RMSProp等

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