Caffe数据结构

一、基本概念




深度学习21天实战caffe学习笔记《7 :Caffe数据结构》_数据结构



二、Blob:Caffe的基本存储单元


blob


  • 四维数组,维度从低到高(width_,height_,channels_,num_);
  • 用于存储和交换数据;存储数据或者权值(data)和权值增量(diff);
  • 提供统一的存储器接口,持有一批图像或其他数据、权值、权值更新值;
  • 进行网络计算时,每层的输入、输出都需要通过Blob对象缓冲。

(1)基本用法


可自动同步CPU/GPU上的数据;


#include <vector>
#include <iostream>
//将Blob内部值保存到磁盘,或者从磁盘载入内存,可以分别通过ToProto()、FromProto()实现
#include <caffe/util/io.hpp> //存需要包含这个文件
#include <caffe/blob.hpp>  #包含头文件                                                                                              
using namespace caffe; #命名空间
using namespace std;

int main(void)
{
  Blob<float>  a;  #创建Blob对象a
  cout<<"Size :"<<a.shape_string()<<endl;   #打印维度信息 Size :(0)
  a.Reshape(1,2,3,4);
  cout<<"Size :"<<a.shape_string()<<endl; #打印维度信息 Size:1 2 3 4 (24)
                                                                                                                                     float *p = a.mutable_cpu_data();  #修改内部数值 mutable_cpu[gpu]_data[diff]
  float *q = a.mutable_cpu_diff();  #修改内部数值 mutable_cpu[gpu]_data[diff]
  for(int i = 0; i < a.count(); i ++)
 {
        p[i] = i; #将data初始化为1,2,3...
 q[i] =a.count()-1-i ; #将diff初始化为23,22,21...
 }
 a.update(); #执行Update操作,将diff与data融合(这也是CNN权值更新步骤的追踪实施者)                                   # Update()实现 data=data-diff

BlobProto bp;    #构造一个BlobProto对象
a.ToProto(&bp,true);  #将a序列化,连通diff(默认不带)
WriteProtoToBinaryFile(bp,"a.blob");  #写入磁盘文件a.blob"
ReadProtoFromBinaryFileOrDie("a.blob",&bp2)
Blob<float> b;   #新建一个Blob对象b
b.FromProto(bp2,true);  #从序列化对象bp2总克隆b(连通形状)

 for(int u = 0; u < a.num(); u ++)
 {
  for(int v = 0; v < a.channels(); v ++) 
   {
     for(int w = 0; w < a.height(); w ++)
     {
	for(int x = 0; x < a.width(); x ++)
        {
	  cout<<"a["<<u<<"]["<< v << "][" << w << "][" << x << "] =" << a.data_at(u,v,w,x)<< endl;
   #下标访问 a[][][][]=-23、-21......21、23
        }
     }
   }
 }
cout<<"ASUM = " << a.asum_data()<< endl;    #所有元素绝对值之和(L1-范数) ASUM = 288                         cout<<"SUMSQ = " << a.sumsq_data()<< endl;  # 平方和 (L2-范数)SUMSQ = 4600
 return 0; 
}


Blobproto对象实现了磁盘、内存之间的数据通信,这对于保存、载入训练好的模型非常实用。


(2)数据结构描述


不用BlobShape和BlobProto二实用ProtoBuffer的原因:



1>、结构体的序列化/反序列化操作需要额外的编程思想,难以做到接口标准化;



2>、结构体中包含变长数据时,需要更加细致的工作保证数据完整性。ProtoBuffer将变成最容易出现问题的地方加以隐藏,让机器自动处理,提高了出的健壮性。




 

该结构描述了Blob的形状信息

message BlobShape


只包括若干int64类型值,分别表示Blob

每个维度的大小,packed表示这些值在内存

中紧密排布,没有空洞

repeated int64 dim = 1 [packed = true];

 

}

 

 

该结构描述Blob在磁盘中序列化后的形态

message BlobProto

可选,包括一个BlobShape对象

optional BlobShape shape = 7;

包括若干护垫元素,

用于存储增量信息,元素数目由shape或

(num,channels,height,width)确定

,这些元素在内存总紧密排布

repeated float data = 5 [packed = true];


包括若干护垫元素,

用于存储增量信息,维度与data粗细一致

repeated float diff = 6 [packed = true];

与data并列,知识类型为double

repeated double double_data = 8 [packed = true];

与diff并列,只是内心为double

repeated double double_diff = 9 [packed = true];

 

 

可选的维度信息,新版本caffe

推荐使用shape,而不再后面的值

// 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];

 

}


(3)Blob炼成法


 Blob是一个模板类,声明在include/caffe/blob.hpp中,封装类SyncedMemory类,作为基本计算单元服务Layer、Net、Solver等。



注意:caffe类中成员变量名都带有后缀“_”,这样再返俗世相中容易区分临时变量和类变量。


三、Layer:Caffe的基本计算单元


Layer至少有一个输入Blob(Bottom Blob)和一个输出Blob(Top Blob),部分Layer带有权值和偏置项;


两个运算方法:



前向传播:对输入Blob进行某种处理(有权值和骗至西安的Layer会利用这些对输入进行处理),得到输出Blob



反向传播:对输出Blob的diff进行某种处理,得到输入Blob的diff(有权值和偏置项的Layer可能也会计算Blob、偏置项Blob的 diff)



(1)数据结构描述



(2)Layer炼成法


  • Layer头文件位于include/caffe/layer.hpp中;
  • Layer源文件位于src/caffe/layer.cpp中(大部分函数并没有实现 ,只有虚函数);
  • Layer的相关函数的实现在派生类,具体代码在src/caffe/layers/*.cpp ;Layer类是一个虚基类,不能直接创建对象。



四、Net:Caffe中网站的CNN模型,包含若干Layer实例


(1)基本用法


  • 描述文件   *.prototxt    (models/bvlc_reference_caffenet/deploy.prototxt );
  • Net中既包括Layer对象,又包括Blob对象。Blob对象用于存放每个Layer输入/输出中间结果,Layer根据Net描述对指定的输入Blob进行某些处理(卷积、下采样、全连接、非线性变换、计算代价函数等),输出结果放到指定的输出Blob中。输入Blob与输出Blob可能为同一个。
  • 所有的Layer和Blob对象都用名字区分,同名的Blob表示同一个Blob对象。同名的Layer表示同一个Layer对象,Blob和Layer同名不代表他们有任何直接关系。


(2)数据结构描述

(3)Net绘成法


下面有两类Blob:


1>、以param开头的权值Blob:随着Blob会随着学习过程而更新,归属于“模型”;


2>、以blob开头的Layer输入/输出Blob:只会随网络输入变化,归属于“数据”;


深度学习的目的就是不断从“数据”中获取知识,存储到“模型”中,应用于后来的“数据”。


深度学习21天实战caffe学习笔记《7 :Caffe数据结构》_数据_02




五、机制和策略:能干什么?怎么干?


  • Blob提供数据容器的机制;
  • Layer通过不同的策略使用该数据容器,实现多元化的计算处理过程,同时又提供了深度学习各种基本算法(卷积、下采样、损失函数计算等)的机制;
  • Net则利用Layer这些机制,组合为更完整的深度学习模型,提供了更加丰富的学习策略。