Caffe 代码学习 2: Blob

2016-04-14  本文已影响0人  platero

简介

Blob用于存储和交换一个network中所有需要用到的数据, 包括:

  1. 每一层的输入输出数据
  2. 每一层的参数(如果该层含可训练参数的话)

对于实际操作的数据, blob提供了良好的封装, 并且保证了CPU和GPU之间的数据同步. 直观来说, blob是一个行优先的N维数组. 以常用的 4D 数据举例, 每一维为 N number * K channels * H height * W width, 那么(n, k, h, w)的物理地址为 ((n * K + k) * H + h) * W + w.

注意虽然常用的图片数据是4D的, 但是caffe也支持其他维度的blob.

成员变量

Blob类的成员变量如下,

  shared_ptr<SyncedMemory> data_;      \\ 数据本身
  shared_ptr<SyncedMemory> diff_;        \\ 数据的derivative
  shared_ptr<SyncedMemory> shape_data_;  \\ 老版本的shape_数据
  vector<int> shape_;     \\ 当前blob的数据形状, e.g. shape_[0]: num, shape_[1]: channels
  int count_;  \\ 当前blob的数据元素总个数: count_ = shape_[0]*shape_[1]*...*shape_[end]
  int capacity_;   \\ 当前blob的物理元素个数

下面我们来看Blob中的几个主要方法

Reshape

void Blob<Dtype>::Reshape(const vector<int>& shape)

Reshape函数根据输入shape更新count_. 如果需要的元素个数 count_ > 当前实际物理元素个数 capacity_, 那么就需要重新分配内存空间, 并且更新capacity_值. 否则仅仅更新shape_, shape_data_, count_值. 这样做的好处是, 如果实际物理容量足够, 那么就不会频繁重新分配物理空间.

获取data, diff指针

Blob提供了data_, diff_的指针, 其中cpu_data()获取的指针是const, 不能够改变数据内容. 如需要改变数据内容, 需要使用mutable_cpu_data().

注意mutable_cpu_data()获取的是GPU memory中的数据指针, 不同在cpu程序中直接访问读写, 需要通过kernel函数访问.

update

如果Blob保存的是layer 参数, 在backpropagation时, 需要对参数进行更新, update执行下面的操作

    caffe_axpy<Dtype>(count_, Dtype(-1),
        static_cast<const Dtype*>(diff_->cpu_data()),
        static_cast<Dtype*>(data_->mutable_cpu_data()));

这里调用的是 caffe_axpy函数, 这个函数的数学表达为: a*x+y, 即 a multiply by x plus y (因此叫axpy). 这里 a=-1, 因此实际意义就是梯度下降里的参数更新公式:
data = -diff + data

上一篇 下一篇

猜你喜欢

热点阅读