Caffe

【框架caffe】2:blob.hpp/blob.cpp——ca

2018-09-11  本文已影响17人  yuanCruise

0. Blob简介

Blob:是基础的数据结构,是用来保存学习到的参数以及网络传输过程中产生数据的类。是Caffe作为数据传输的媒介,无论是网络权重参数,还是输入数据,都是转化为Blob数据结构来存储,网络,求解器等都是直接与此结构打交道的。

其直观的可以把它看成一个有4维度的结构体(包含数据和梯度),而实际上,它们只是一维的指针而已,其4维结构通过shape属性得以计算出来(根据C语言的数据顺序),因为Blob是row-major(行优先)保存的,比如对于输入(n, c, h, w)位置的数据位置为((n * channels_+c) * height_+h) * width_+w。
Blob是用以存储数据的四维数组,分别由下面组成:

对于BlobProto,可以看到定义了四个optional的int32类型的名字(name)num、channels、height和width,optional意味着Blob可以有一个或者没有这个参数,而后面的repeated意味着float类型的data和diff可以重复任意次,而加上[packed = true]是为了更高效的编码。

message BlobProto {
   optional int32 num = 1 [default = 0];
   optional int32 channels = 2 [default = 0];
   optional int32 height = 3 [default = 0];
   optional int32 width = 4 [default = 0];
   repeated float data = 5 [packed = true];
   repeated float diff = 6 [packed = true];
}

到这里基本上Blob就很清楚了,主要数据有两个data和diff(data表示流动数据(输出数据),而diff则存储BP的梯度。),用num、channels、height和width这四个维度来确定数据的具体位置,做一些数据查询和Blobreshape的操作。

在更高一级的Layer中Blob用下面的形式表示学习到的参数:

vector<shared_ptr<Blob<Dtype> > > blobs_;

1.Blob代码解析

<0> 包含的头文件

#include "caffe/common.hpp"      //单例化caffe类,并且封装了boost和cuda随机数生成的函数,提供了统一接口。
#include "caffe/proto/caffe.pb.h" //[查看caffe.proto介绍](https://www.jianshu.com/p/907be4c91d7c)
#include "caffe/syncedmem.hpp"  //主要是分配内存和释放内存的。而classSyncedMemory定义了内存分配管理和CPU与GPU之间同步的函数,也没啥特别的。
                               // Blob会使用SyncedMem自动决定什么时候去copy data以提高运行效率,通常情况是仅当gnu或cpu修改后有copy操作。

#include "caffe/util/math_functions.hpp" //封装了很多cblas矩阵运算,基本是矩阵和向量的处理函数。

<1> 成员变量

protected:
  shared_ptr<SyncedMemory> data_;// 存放数据
  shared_ptr<SyncedMemory> diff_;//存放梯度
  vector<int> shape_; //存放形状
  int count_; //数据个数
  int capacity_; //数据容量

<2>成员函数
blob.cpp

 const Dtype* cpu_data() const; //cpu使用的数据
  void set_cpu_data(Dtype* data);//用数据块的值来blob里面的data。
  const Dtype* gpu_data() const;//返回不可更改的指针,下同
  const Dtype* cpu_diff() const;
  const Dtype* gpu_diff() const;
  Dtype* mutable_cpu_data();//返回可更改的指针,下同
  Dtype* mutable_gpu_data();
  Dtype* mutable_cpu_diff();
  Dtype* mutable_gpu_diff();
Reshape()         //可以改变一个blob的大小;
ReshapeLike()  //为data和diff重新分配一块空间,大小和另一个blob的一样;
Num_axes()     //返回的是blob的大小;
Count()           //计算得到count=num*channels*height*width。
Offset()           //可得到输入blob数据(n,c,h,w)的偏移量位置;
CopyFrom()   //从source拷贝数据,copy_diff来作为标志区分是拷贝data还是diff。
FromProto()  //从proto读数据进来,其实就是反序列化。
ToProto()       //把blob数据保存到proto中。
ShareDate()/ShareDiff()  //从other的blob复制data和diff的值;

2.Blob举例

Blob1
Blob2

上一篇 下一篇

猜你喜欢

热点阅读