from:https://www.cnblogs.com/louyihang-loves-baiyan/p/5149628.html

转载请注明出处,楼燚(yì)航的blog,http://www.cnblogs.com/louyihang-loves-baiyan/

首先看到的是Blob这个类,Blob是作为Caffe中数据流通的一个基本类,网络各层之间的数据是通过Blob来传递的。这里整个代码是非常规范的,基本上条件编译,命名空间,模板类,各种不太经常看到的关键字如exlicit,inline等等。
首先提一下explicit关键字的作用是禁止单参数构造函数的隐式转换,具体含义谷歌即可。还有inline的作用,iniline主要是将代码进行复制,扩充,会使代码总量上升,好处就是可以节省调用的开销,能提高执行效率。

1主要变量

shared_ptr<SyncedMemory> data_;
shared_ptr<SyncedMemory> diff_;
shared_ptr<SyncedMemory> shape_data_;
vector<int> shape_;
int count_;
int capacity_;

BLob只是一个基本的数据结构,因此内部的变量相对较少,首先是data_指针,指针类型是shared_ptr,属于boost库的一个智能指针,这一部分主要用来申请内存存储data,data主要是正向传播的时候用的。同理,diff_主要用来存储偏差,update data,shape_datashape_都是存储Blob的形状,一个是老版本一个是新版本。count表示Blob中的元素个数,也就是个数*通道数*高度*宽度,capacity表示当前的元素个数,因为Blob可能会reshape。

2主要函数

template <typename Dtype>
class Blob {public:Blob(): data_(), diff_(), count_(0), capacity_(0) {}/// @brief Deprecated; use <code>Blob(const vector<int>& shape)</code>.explicit Blob(const int num, const int channels, const int height,const int width);explicit Blob(const vector<int>& shape);/// @brief Deprecated; use <code>Reshape(const vector<int>& shape)</code>.void Reshape(const int num, const int channels, const int height,const int width);

其中Blob作为一个最基础的类,其中构造函数开辟一个内存空间来存储数据,Reshape函数在Layer中的reshape或者forward操作中来adjust dimension。同时在改变Blob大小时,内存将会被重新分配如果内存大小不够了,并且额外的内存将不会被释放。对input的blob进行reshape,如果立马调用Net::Backward是会出错的,因为reshape之后,要么Net::forward或者Net::Reshape就会被调用来将新的input shape 传播到高层

Blob类里面有重载很多个count()函数,主要还是为了统计Blob的容量(volume),或者是某一片(slice),从某个axis到具体某个axis的shape乘积。

inline int count(int start_axis, int end_axis)

并且Blob的Index是可以从负坐标开始读的,这一点跟Python好像

inline int CanonicalAxisIndex(int axis_index) 

对于Blob中的4个基本变量num,channel,height,width可以直接通过shape(0),shape(1),shape(2),shape(3)来访问。

计算offset

inline int offset(const int n, const int c = 0, const int h = 0, const int w = 0)
inline int offset(const vector<int>& indices)

offset计算的方式也支持两种方式,一种直接指定n,c,h,w或者放到一个vector中进行计算,偏差是根据对应的n,c,h,w,返回的offset是((n * channels() + c) * height() + h) * width() + w

其实里面稍加留意可以看到有很多的

CHECK_GE
CHECK_LE
CHECK_EQ
....

等等看意思就知道了,肯定是在做比较Geater or Eqal这样的意思。这其实是GLOG,谷歌的一个日志库,Caffe里面用用了大量这样的宏,看起来也比较直观

void CopyFrom(const Blob<Dtype>& source, bool copy_diff = false,bool reshape = false);

从一个blob中copy数据 ,通过开关控制是否copy_diff,如果是False则copy data。reshape控制是否需要reshape。好我们接着往下看

inline Dtype data_at(const int n, const int c, const int h, const int w)
inline Dtype diff_at(const int n, const int c, const int h, const int w)
inline Dtype data_at(const vector<int>& index)
inline Dtype diff_at(const vector<int>& index)
inline const shared_ptr<SyncedMemory>& data()
inline const shared_ptr<SyncedMemory>& diff()

这一部分函数主要通过给定的位置访问数据,根据位置计算与数据起始的偏差offset,在通过cpu_data*指针获得地址。下面几个函数都是获得

const Dtype* cpu_data() const;
void set_cpu_data(Dtype* data);
const int* gpu_shape() const;
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();

可以看到这里有data和diff两类数据,而这个diff就是我们所熟知的偏差,前者主要存储前向传递的数据,而后者存储的是反向传播中的梯度

void Update();

看到update里面面调用了

caffe_axpy<float>(const int N, const float alpha, const float* X,float* Y)
{ cblas_saxpy(N, alpha, X, 1, Y, 1); }

这个函数在caffe的util下面的match-functions.cpp里面,主要是负责了线性代数库的调用,实现的功能是

Y=alpha∗X+beta∗YY=alpha∗X+beta∗Y

也就是blob里面的data部分减去diff部分

void FromProto(const BlobProto& proto, bool reshape = true);
void ToProto(BlobProto* proto, bool write_diff = false) const;

这两个函数主要是将数据序列化,存储到BlobProto,这里说到Proto是谷歌的一个数据序列化的存储格式,可以实现语言、平台无关、可扩展的序列化结构数据格式。Caffe里面数据的存储都采用这一结构,这里就不深入展开,具体可以参照这篇文章,对于proto的序列化和反序列都讲解的非常详细http://***/Article/34963

Dtype asum_data() const;//计算data的L1范数
Dtype asum_diff() const;//计算diff的L1范数
Dtype sumsq_data() const;//计算data的L2范数
Dtype sumsq_diff() const;//计算diff的L2范数
void scale_data(Dtype scale_factor);//将data部分乘以一个因子
void scale_diff(Dtype scale_factor);//将diff部分乘一个因子

这几个函数是一些零散的功能,一看就懂。

void ShareData(const Blob& other);
void ShareData(const Blob& other);

这两个函数看名字就知道了一个是共享data,一个是共享diff,具体就是将别的blob的data和响应的diff指针给这个Blob,实现数据的共享。同时需要注意的是这个操作会引起这个Blob里面的SyncedMemory被释放,因为shared_ptr指针被用=重置的时候回调用响应的析构器。

bool ShapeEquals(const BlobProto& other);

这函数就不用说了,比较两个Blob形状是否相同
好了,基本上Blob的主要参数功能基本就涵盖在里面了,以上只是我的拙见,如有纰漏,还望指出,万分感谢。

Caffe源码解析1:Blob相关推荐

  1. 深度学习框架Caffe源码解析

    作者:薛云峰(https://github.com/HolidayXue),主要从事视频图像算法的研究, 本文来源微信公众号:深度学习大讲堂.  原文:深度学习框架Caffe源码解析  欢迎技术投稿. ...

  2. Caffe源码解析5:Conv_Layer

    转载请注明出处,楼燚(yì)航的blog,http://home.cnblogs.com/louyihang-loves-baiyan/ Vision_layer里面主要是包括了一些关于一些视觉上的操 ...

  3. Caffe源码解析4: Data_layer

    转载请注明出处,楼燚(yì)航的blog,http://home.cnblogs.com/louyihang-loves-baiyan/ data_layer应该是网络的最底层,主要是将数据送给blo ...

  4. Caffe源码解析(一) —— caffe.proto

    文章作者:Tyan 博客:noahsnail.com  |  CSDN  |  简书 caffe.proto是caffe数据结构定义的主要文件,本文主要是在caffe.proto代码的基础上加上了部分 ...

  5. caffe源码导读(二)Blob数据结构介绍

    文章目录 前言 一.先看Blob的数据结构描述 二.Blob基本用法 前言 本篇<深度学习21天实战caffe>这本书的阅读笔记. 打开proto/caffe.proto中,刚开始就是介绍 ...

  6. caffe源码解析—image_data_layer层

    caffe data layer相关层的继承结构 image-data-layer层关键代码注释 DataLayerSetUp函数 //将imagelist中的图片以 image+label格式 读入 ...

  7. Caffe源码解析2:SycedMem

    from:https://www.cnblogs.com/louyihang-loves-baiyan/p/5150554.html 转载请注明出处,楼燚(yì)航的blog,http://www.c ...

  8. Caffe源码解析—核函数

    目录 forward_cpu_gemm forward_cpu_bias backward_cpu_bias weight_cpu_gemm backward_cpu_gemm 其余函数参考链接 fo ...

  9. 零基础学caffe源码 ReLU激活函数

    零基础学caffe源码 ReLU激活函数 原创 2016年08月03日 17:30:19 1.如何有效阅读caffe源码 1.caffe源码阅读路线最好是从src/cafffe/proto/caffe ...

最新文章

  1. 国企程序员有多香?这是一个普通程序员在国企的每日工作清单!
  2. 清华大学计算机系71班张晨,“神仙打架”要来了!网友:又到了凡人围观的时刻...
  3. mysql分页limit运算,MySQL的limit分页查询及性能问题
  4. onlyOfice取消上传文件大小的限制
  5. 关于电脑的基础单词笔记
  6. 信息学奥赛C++语言: 直角三角形
  7. filter IE滤镜(Internet Explorer)CSS
  8. eclipse java环境配置
  9. Redis内存分析方法
  10. 原在一个tableView上应用不同类型的DTAttributedTextCell
  11. rapidxml库生成xml小例子及需注意的问题
  12. 传奇脚本称号(封号)设置的详解
  13. Win10与苹果AirDrop(隔空投送)
  14. 块、内联、内联块都有哪些及其特点
  15. Dubbo的介绍以及Dubbox的区别
  16. 前端屏幕尺寸和分辨率_屏幕尺寸、分辨率、倍率到底是什么鬼
  17. batocera 完整包_Batocera Plus 2.0 中文整合版bt下载 8G和150G
  18. 简单五步设置群晖NAS绑定自有域名实现外网访问
  19. 浅析Java中的深克隆和浅克隆
  20. 亚马逊新专利曝光,让机器人学会自己开锁并将包裹送入你的家中

热门文章

  1. JNA—JNI终结者
  2. Java List<Object>去掉重复对象-java8
  3. POJ 1852 Ants 分析
  4. C++ Qt 访问权限总结
  5. ie7浏览器传输中文的问题
  6. 深入浅出 Javascript API(二)--地图显示与基本操作 转
  7. vue-i18n使用及踩坑记录
  8. [JMX一步步来] 9、基于JBoss来写MBean
  9. 如何实现线程间的通讯(转载)
  10. Oracle PL/SQL之LOOP循环控制语句