Caffe学习(六)——Blob代码文件介绍

src/caffe/proto/caffe.proto

该文件主要描述Blob数据结构,主要包括:

// 描述Blob的shape信息
message BlobShape {
  repeated int64 dim = 1 [packed = true];  //int64类型数值,表示Blob每个维度大小。packed = true表示这些值在内存中紧密排布,没有空洞
}

//描述Blob在磁盘存储的信息
message BlobProto {
  optional BlobShape shape = 7; //可选,表示一个BlobShape对象
  repeated float data = 5 [packed = true];  //float数据类型,用于存储数据,数目由shape(N,C,H,W)决定
  repeated float diff = 6 [packed = true];  //float数据类型,用于存储增量信息,维度与data一致
  repeated double double_data = 8 [packed = true];  //double数据类型,与data并列
  repeated double double_diff = 9 [packed = true];  //double数据类型,与diff并列

// 4D dimensions -- deprecated.  Use "shape" instead.
  optional int32 num = 1 [default = 0]; // 数据的图片数量
  optional int32 channels = 2 [default = 0];    // 图片的通道数
  optional int32 height = 3 [default = 0];  //图片的高度
  optional int32 width = 4 [default = 0];   //图片的宽度
}

include/caffe/blob.hpp

该文件是Blob实现的头文件,声明了Blob实现的接口,最终都是调用blob.cpp的实现,可以走读下。
比如

//对Reshape操作的声明:
void Reshape(const int num, const int channels, const int height,
      const int width);
void Reshape(const vector<int>& shape);
void Reshape(const BlobShape& shape);
void ReshapeLike(const Blob& other);
//获取blob的维度数目
inline int num_axes() const { return shape_.size(); }
//获取数据总数
 inline int count() const { return count_; }

src/caffe/blob.cpp

此文件是Blob接口的具体实现,实现Blob数据的初始化、reshape变维、数据读取和写入、获得diff、更新网络中Blob数据等等操作,建议深入阅读。
以Blob 输入nchw维度进行初始化为例:

//Blob初始化,输入数据nchw
template <typename Dtype>
Blob::Blob(const int num, const int channels, const int height,
    const int width)
  // capacity_ must be initialized before calling Reshape
  : capacity_(0) {  //设置容量capacity = 0,未分配内存
  Reshape(num, channels, height, width);    //最终调用Reshape()初始化
}
//针对Reshape入参,选择这个模板
template <typename Dtype>
void Blob::Reshape(const int num, const int channels, const int height,
    const int width) {
  vector<int> shape(4);
  shape[0] = num;
  shape[1] = channels;
  shape[2] = height;
  shape[3] = width;
  Reshape(shape);  //初始化数组,存储nchw到shape,然后调用Reshape()
}
//根据输入,选择这个模板,真正的Reshape操作
template <typename Dtype>
void Blob::Reshape(const vector<int>& shape) {
  CHECK_LE(shape.size(), kMaxBlobAxes); //检查数据size <=  kMaxBlobAxes
  count_ = 1;
  shape_.resize(shape.size()); // 重置成员变量维度
  if (!shape_data_ || shape_data_->size() < shape.size() * sizeof(int)) {
    shape_data_.reset(new SyncedMemory(shape.size() * sizeof(int)));
  }
  int* shape_data = static_cast<int*>(shape_data_->mutable_cpu_data());
  for (int i = 0; i < shape.size(); ++i) {
    CHECK_GE(shape[i], 0);  //保证每个维度的数组>=0
    if (count_ != 0) {
      CHECK_LE(shape[i], INT_MAX / count_) << "blob size exceeds INT_MAX";
    }   //保证count_不会溢出
    count_ *= shape[i]; // count_ 是nchw的累乘
    shape_[i] = shape[i];   //更新成员变量,这里
    shape_data[i] = shape[i];
  }
if (count_ > capacity_) {   //如果新的count_大于capacity
    capacity_ = count_; //初始化最开始capacity_ = 0,这里赋值真正的容量,即nchw累乘结果。
    data_.reset(new SyncedMemory(capacity_ * sizeof(Dtype))); //扩容,重新分配data空间
    diff_.reset(new SyncedMemory(capacity_ * sizeof(Dtype))); ////扩容,重新分配diff空间
  }
}

从上面可以看到,Blob实现多个模板,根据用户输入选择模板,最终调用到最终实现完成功能。同时使用模板的好处是,Reshape操作,支持多种用户输入方式。

其他Blob内部实现接口类似。
Caffe学习(六)——Blob代码文件介绍_第1张图片

你可能感兴趣的:(caffe)