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

xiaoxiao2021-03-01  11

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<Dtype>::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<Dtype>::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<Dtype>::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内部实现接口类似。

转载请注明原文地址: https://www.6miu.com/read-3850277.html

最新回复(0)