caffe源码阅读(2)-Layer
神经网络是由层组成的,深度神经网络就是层数多了。layer对应神经网络的层。数据以Blob的形式,在不同的layer之间流动。caffe定义的神经网络已protobuf形式定义。例如:
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
......
}
就是定义了一个卷积层,bottom是其前一层,而top是其后一层。前向传播计算过程就是获取bottom的输出(Blob),当做输入,通过计算(Forward),输出Blob给下一层top;每一层还有一个反向传播Backforward。不同的层实现的前向传播和反向传播不相同,但是它们都有同一个基类class Layer
。
成员变量
先看一下Layer的成员变量,这些成员变量都是层的基本变量,不同的层都需要这些变量,这些成员变量访问权限为protected
LayerParameter 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层,这是两个纯虚函数。
caffe源码阅读(2)-Layer的更多相关文章
- Caffe源码阅读(1) 全连接层
Caffe源码阅读(1) 全连接层 发表于 2014-09-15 | 今天看全连接层的实现.主要看的是https://github.com/BVLC/caffe/blob/master/src ...
- caffe源码阅读
参考网址:https://www.cnblogs.com/louyihang-loves-baiyan/p/5149628.html 1.caffe代码层次熟悉blob,layer,net,solve ...
- caffe源码阅读(1)-数据流Blob
Blob是Caffe中层之间数据流通的单位,各个layer之间的数据通过Blob传递.在看Blob源码之前,先看一下CPU和GPU内存之间的数据同步类SyncedMemory:使用GPU运算时,数据要 ...
- caffe源码阅读(3)-Datalayer
DataLayer是把数据从文件导入到网络的层,从网络定义prototxt文件可以看一下数据层定义 layer { name: "data" type: "Data&qu ...
- caffe源码阅读(1)_整体框架和简介(摘录)
原文链接:https://www.zhihu.com/question/27982282 1.Caffe代码层次.回答里面有人说熟悉Blob,Layer,Net,Solver这样的几大类,我比较赞同. ...
- caffe 源码阅读
bvlc:Berkeley Vision and Learning Center. 1. 目录结构 models(四个文件夹均有四个文件构成,deploy.prototxt, readme.md, s ...
- caffe源码阅读(一)convert_imageset.cpp注释
PS:本系列为本人初步学习caffe所记,由于理解尚浅,其中多有不足之处和错误之处,有待改正. 一.实现方法 首先,将文件名与它对应的标签用 std::pair 存储起来,其中first存储文件名,s ...
- caffe中batch norm源码阅读
1. batch norm 输入batch norm层的数据为[N, C, H, W], 该层计算得到均值为C个,方差为C个,输出数据为[N, C, H, W]. <1> 形象点说,均值的 ...
- 源码阅读经验谈-slim,darknet,labelimg,caffe(1)
本文首先谈自己的源码阅读体验,然后给几个案例解读,选的例子都是比较简单.重在说明我琢磨的点线面源码阅读方法.我不是专业架构师,是从一个深度学习算法工程师的角度来谈的,不专业的地方请大家轻拍. 经常看别 ...
随机推荐
- 快速、冒泡排序算法(PHP版)
1.冒泡排序算法改进: 方法一: function bubbleSort($arr){//$arr(1...n)是待排序的文件,采用自下向上扫描,对$arr做冒泡排序 $bFlag = true; / ...
- HW3.28
import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner i ...
- 小波变换和motion信号处理(三)(转)
这篇文章算太监了,去作者blog提问去吧:http://www.kunli.info/2012/04/08/fourier-wavelet-motion-signal-3/ 从前两篇发布到现在,过去一 ...
- poj 2367 Genealogical tree (拓扑排序)
火星人的血缘关系很奇怪,一个人可以有很多父亲,当然一个人也可以有很多孩子.有些时候分不清辈分会产生一些尴尬.所以写个程序来让n个人排序,长辈排在晚辈前面. 输入:N 代表n个人 1~n 接下来n行 第 ...
- 问题-[Delphi]在对GRID设置单击为编辑时,其他GRID可以,但有一个GRID不行?
问题现象:在对GRID设置单击为编辑时,其他GRID可以,但有一个GRID不行?问题原因:在这个GRID中的单击事件可能不存在,可以测试一下有没有单击事件.解决方法:需要在GRID的上一个类中,放开单 ...
- maven 通过nexus创建工厂的配置
访问中央工厂的地址:http://localhost:8081/nexus/index.html#welcome admin.admin123 查找到自己配置的maven仓库的位置,编辑setti ...
- Eclipse导入Maven项目时class not found
用maven开发javaweb项目可以自动导包,可以在配置文件pom.xml中发现依赖包,今天在eclipse中导入maven项目,开启tomcat服务器时报错 class not found, 看到 ...
- CAS认证(3):验证用户信息
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...
- linux 查看并终止进程
1,查看port被那个进程占用 比如: netstat -anp | grep 1160 ps:查看port1169被那个进程占用. 2.查找进程 比如 :ps -ef | grep 'tomcat' ...
- MediaProvider 数据库Audio相关表格相应关系
Android的MediaProvider提供了一系列的Audio,Video,image等表格,用于APP检索相关的音视频图片信息. 首先来看看Audio相关的表格: ×图中颜色同样的部分表示来自于 ...