Caffe中的Blobs,Layers和Nets

最近在学习Caffe,来总结一下Caffe中基本知识吧。Caffe中最基本的概念包括blobs,layers和nets。Caffe中的模型是基于定义好的网络,它从下到上定义了整个模型(即从输入的数据层到最后的loss层)。而模型中数据存储在叫做blob的数据结构中,该结构是一个标准的数组,并且是整个框架的统一内存接口。

在计算机视觉领域,大多数的数据都是一个四维(4D)数组(但对于非图像应用也是可以使用blobs的),常见的blobs对于图像集数据的维度是( N×K×H×W ),第一个N表示图像集的图像个数(patch size),比如对于ImageNet,训练batch为256张图像(即一次训练256张图像),那么 N=256 ,第二个K表示特征的维度,比如对于一张RGB的图像来说 K=3 ,而第三、四个参数分别表示图像的高和宽(注意是宽在最后一维),比如,在一个4D的blob中, (n,k,h,w) 的物理位置为 ((nK+k)H+h)W+w ,可以看出宽度的变化是最快的。

一个blob同时存储data和diff。data是传递过去的正常的数据,而diff是由网络计算出来的梯度值(差分值)。其可能存储在CPU或GPU上,而且获得它们的方式也有两种(const和非const的),const类型的可以改变数据,另一种不能。代码如下(这是data的cpu实现,gpu类似,而diff也是类似的):

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.

这里写图片描述

数据的流向就是这样的,其中数据一共被改变了3次(除了初始的CPU版本)。

接下来讲层,每一层都有三个基本的模块:setup(初始设置),forward(前向计算),backward(后向传播,即计算梯度值)。
Setup:在模型初始化的时候初始化层和连接;
Forward:给定底层的输入计算输出,并传递给顶层;
Backward:给定顶层输出的梯度值,计算关于输入的梯度值,并传递给底层。拥有参数的层计算关于参数的梯度值并且在内部存储起来。

而对于net,它是由很多层连接起来的计算图——有向无环图(DAG)。一个典型的网络(net)起始于从磁盘加载出来数据的数据层,并且以一个loss层结束。网络可以完成分类、重建等任务。

下面是一个简单的逻辑回归分类器。网络的图示和定义如下:

这里写图片描述

name: "LogReg"
layer {
  name: "mnist"
  type: "Data"
  top: "data"
  top: "label"
  data_param {
    source: "input_leveldb"
    batch_size: 64
  }
}
layer {
  name: "ip"
  type: "InnerProduct"
  bottom: "data"
  top: "ip"
  inner_product_param {
    num_output: 2
  }
}
layer {
  name: "loss"
  type: "SoftmaxWithLoss"
  bottom: "ip"
  bottom: "label"
  top: "loss"
}

猜你喜欢

转载自blog.csdn.net/qxconverse/article/details/77646421
今日推荐