caffe源码阅读(2)-Layer
2016-06-22 22:42
621 查看
神经网络是由层组成的,深度神经网络就是层数多了。layer对应神经网络的层。数据以Blob的形式,在不同的layer之间流动。caffe定义的神经网络已protobuf形式定义。例如:
就是定义了一个卷积层,bottom是其前一层,而top是其后一层。前向传播计算过程就是获取bottom的输出(Blob),当做输入,通过计算(Forward),输出Blob给下一层top;每一层还有一个反向传播Backforward。不同的层实现的前向传播和反向传播不相同,但是它们都有同一个基类
layer_param_类型为LayerParameter,具体定义在caffe_root/src/caffe/protocaffe.proto中,描述了层的一些信息,例如是测试还是训练,其bottom和top等。
phase_是枚举变量,指明这一层是训练还是测试。
blobs_是容器,其容器内元素类型为指向Blob的智能指针,存储内容为权重w和偏置b,即这一层需要训练的参数。
param_propagate_down_是保存bool类型的容易,即是否要计算Blob的梯度diff
loss_是容器,标志着top blob是否有非零权重
还有2个private访问权限的变量:
layer可以被网络共享,如果共享,使用layer时,需要给layer加锁。
之后调用
不同类型的Layer,前向和反向传播具体实现不同,在Layer层,这是两个纯虚函数。
layer { name: "conv1" type: "Convolution" bottom: "data" top: "conv1" ...... }
就是定义了一个卷积层,bottom是其前一层,而top是其后一层。前向传播计算过程就是获取bottom的输出(Blob),当做输入,通过计算(Forward),输出Blob给下一层top;每一层还有一个反向传播Backforward。不同的层实现的前向传播和反向传播不相同,但是它们都有同一个基类
class Layer。
成员变量
先看一下Layer的成员变量,这些成员变量都是层的基本变量,不同的层都需要这些变量,这些成员变量访问权限为protectedLayerParameter layer_param_; /** The phase: TRAIN or TEST */ Phase phase_; /** The vector that stores the learnable parameters as a set of blobs. */ vector<shared_ptr<Blob<Dtype> > > blobs_; /** Vector indicating whether to compute the diff of each param blob. */ vector<bool> param_propagate_down_; /** The vector that indicates whether each top blob has a non-zero weight in * the objective function. */ vector<Dtype> loss_;
layer_param_类型为LayerParameter,具体定义在caffe_root/src/caffe/protocaffe.proto中,描述了层的一些信息,例如是测试还是训练,其bottom和top等。
phase_是枚举变量,指明这一层是训练还是测试。
blobs_是容器,其容器内元素类型为指向Blob的智能指针,存储内容为权重w和偏置b,即这一层需要训练的参数。
param_propagate_down_是保存bool类型的容易,即是否要计算Blob的梯度diff
loss_是容器,标志着top blob是否有非零权重
还有2个private访问权限的变量:
bool is_shared_;//标记layer是否被nets共享 /** The mutex for sequential forward if this layer is shared */ shared_ptr<boost::mutex> forward_mutex_;//如果layer被共享,使用前要加锁
layer可以被网络共享,如果共享,使用layer时,需要给layer加锁。
初始化过程
layer构造函数需要LayerParameter类型参数,这个参数往往定义在网络的protobuf中。通过构造函数来初始化,给blobs_分配空间,随后从Layerparameter中填充分配的内存。explicit Layer(const LayerParameter& param) : layer_param_(param), is_shared_(false) { // Set phase and copy blobs (if there are any). phase_ = param.phase(); if (layer_param_.blobs_size() > 0) { blobs_.resize(layer_param_.blobs_size()); for (int i = 0; i < layer_param_.blobs_size(); ++i) { blobs_[i].reset(new Blob<Dtype>()); blobs_[i]->FromProto(layer_param_.blobs(i)); } } }
之后调用
SetUp函数,这个函数会初始化互斥量,检查输入输出合法性。调用LayerSetUp设置详细参数,Reshape调整Blob结构,这两个虚函数,不同的层实现不同。最后来设置top blobs的loss function的权重
inline void SetLossWeights(const vector<Blob<Dtype>*>& top) { const int num_loss_weights = layer_param_.loss_weight_size();//在protobuf中获取权重个数 if (num_loss_weights) { CHECK_EQ(top.size(), num_loss_weights) << "loss_weight must be "//检查权重个数是否匹配 "unspecified or specified once per top blob."; for (int top_id = 0; top_id < top.size(); ++top_id) { const Dtype loss_weight = layer_param_.loss_weight(top_id);//从protobuf中获取对应权重 if (loss_weight == Dtype(0)) { continue; }//权重为零则不赋值 this->set_loss(top_id, loss_weight);//设置权重 const int count = top[top_id]->count(); Dtype* loss_multiplier = top[top_id]->mutable_cpu_diff();//得到diff指针 caffe_set(count, loss_weight, loss_multiplier);//给diff指针赋值 } } }
前向传播和反向传播
Layer最重要的功能就是前向传播和反向传播。前向传播,是数据沿着网络向前流,反向传播是梯度(误差)反方向往回流,用来更新权重和偏置。对应的函数为Forward何Backward,再详细一点,这两个函数还应该有对应的CPU版本和GPU版本。不同类型的Layer,前向和反向传播具体实现不同,在Layer层,这是两个纯虚函数。
相关文章推荐
- 禁止拖拽时选中文本的方法
- 如何把Button按钮样式换成ImageButton?
- 简单重写类型为radio的input元素样式
- 10款Web前端工具
- 10款Web前端工具
- jQuery $(document).ready()和JavaScript onload事件
- javascript Cookie
- VLC web 插件javascript常用接口及属性
- 【NodeJs环境下bower】如何更改bower_components文件夹的位置
- [html]选项卡效果
- js中style,currentStyle和getComputedStyle的区别
- jQuery——jquery.fn.extend与jquery.extend
- JavaScript函数(三)
- [Webpack 2] Hashing with Webpack for long term caching
- Javascript 排序数组或对象
- arcgis api for js共享干货系列之一自写算法实现地图量算工具
- JSP 三个指令七个动作九个对象
- 用CSS设置当鼠标移动到图片内时显示文字
- 使用CSS3滤镜让图片反转颜色
- js学习笔记]PDF.js专题