Caffe学习笔记(一):Caffe架构及其模型解析

写在前面:关于caffe平台如何快速搭建以及如何在caffe上进行训练与预测,请参见前面的文章《caffe平台快速搭建:caffe+window7+vs2013》、《Windows平台上Caffe的训练与学习方法(以数据库CIFAR-10为例)》。

本文主要介绍Caffe的总体框架,并对caffe模型进行解析,主要是本人的学习笔记,参考了各种资料,例如:《Caffe官方教程中译本》,网址:http://caffe.berkeleyvision.org/等等。

1、Caffe架构

Caffe是一个深度学习框架,该框架主要包括五大组件:blobs/layers/nets、solver/proto。

其中,blobs/layers/nets使得Caffe构成基于自己的模型架构,即一种模块化的模型,简单来说就是caffe通过逐层(layer-by-layer)的方式定义了一个网络nets,网络从数据输入层到损失层自下而上定义整个模型,而Blobs只是caffe中处理和传递实际数据的数据封装包;

而solver/proto中的Solver负责深度网络的训练,主要目的就是协调模型的优化,每个Solver中包含一个训练网络对象和一个测试网络对象。Solver优化一个模型的方法是:首先通过调用前传来获得输出和损失,然后通过调用反传产生模型的梯度,将梯度和权值更新后相结合来最小化损失。

而proto则基于Google的Protobuf开源项目,是一种类似XML的数据交换格式,用户只需要按格式定义对象的数据成员,可以在多种语言中实现对象的序列化与反序列化,在Caffe中用于网络模型的结构定义、存储和读取。

blobs/layers/nets与solver/proto的区别与联系可以总结为:caffe通过layers的方式定义nets,而贯穿所有nets的结构就是caffe框架或者模型,对于layers而言,输入的就是blobs这种数据封装包格式的实际数据,当采用该框架进行训练时,也就是solver调优模型,则需要proto这种用于网络模型的结构定义、存储和读取,换句话说,模型格式用protobuf语言定义在caffe.proto文件中。

2、Caffe模型解析:Blobs、Layers, and Nets

blobs、layers与nets之间的关系可以总结为:caffe使用blobs结构来存储、交换和处理网络中正向和反向迭代时的数据(值)和导数信息(梯度),blobs是caffe的标准数组结构,他提供了一个统一的内存接口,layer是caffe模型和计算的基本单元,net则是一系列layers和其连接的集合,blobs详细描述了信息是如何在layer和net中存储和交换的。

下面对blob/layer/net分别介绍。

2.1、blobs

Blob是Caffe中处理和传递实际数据的数据封装包,并且在 CPU与GPU之间具有同步处理能力。从数学意义上说,blob是按C风格连续存储的N维数组。为了便于优化,blobs提供统一的内存接口来存储某种类型的数据,例如批量图像数据、模型参数以及用来进行优化的导数。

对于批量图像数据来说,blob常规的维数为图像数量N *通道数K *图像高度H *图像宽度W。Blob按行为主(row-major)进行存储,所以一个4维blob中,坐标为(n, k, h, w)的值的物理位置为((n * K + k) * H + h) * W + w,这也使得最后面/最右边的维度更新最快。

对于blob中的数据,我们关心的是values(值)和gradients(梯度),所以一个blob单元存储了两块数据——data和diff。前者是我们在网络中传送的普通数据,后者是通过网络计算得到的梯度。 而且,由于数据既可存储在CPU上,也可存储在GPU上,因而有两种数据访问方式:静态方式,不改变数值;动态方式,改变数值。之所以这么设计是因为blob使用了一个SyncedMem类来同步CPU和GPU上的数值,以隐藏同步的细节和最小化传送数据。一个经验准则是,如果不想改变数值,就一直使用常量调用,而且绝不要在自定义类中存储指针。每次操作blob时,调用相应的函数来获取它的指针,因为SyncedMem需要用这种方式来确定何时需要复制数据。

实际上,使用GPU时,Caffe中CPU代码先从磁盘中加载数据到blob,同时请求分配一个GPU设备核(device kernel)以使用GPU进行计算,再将计算好的blob数据送入下一层,这样既实现了高效运算,又忽略了底层细节。只要所有layers均有GPU实现,这种情况下所有的中间数据和梯度都会保留在GPU上。

2.2、layers

Layer是Caffe模型的本质内容和执行计算的基本单元。Layer可以进行很多运算,如:convolve(卷积)、pool(池化)、inner product(内积),rectified-linear和sigmoid等非线性运算,元素级的数据变换,normalize(归一化)、load data(数据加载)、softmax和hinge等losses(损失计算)。可在Caffe的layer catalogue(层目录)中查看所有操作,其囊括了绝大部分目前最前沿的深度学习任务所需要的层类型。

一个layer通过bottom(底部)连接层接收数据,通过top(顶部)连接层输出数据。 每一个layer都定义了3种重要的运算:setup(初始化设置),forward(前向传播),backward(反向传播)。

总的来说,Layer承担了网络的两个核心操作:forward pass(前向传播)——接收输入并计算输出;backward pass(反向传播)——接收关于输出的梯度,计算相对于参数和输入的梯度并反向传播给在它前面的层。由此组成了每个layer的前向和反向通道。

由于Caffe网络的组合性和其代码的模块化,自定义layer是很容易的。只要定义好layer的setup(初始化设置)、forward(前向通道)和backward(反向通道),就可将layer纳入到网络中。

2.3、nets

Caffe模型是端到端的机器学习引擎。

准确的说,Net是由一系列层组成的有向无环(DAG)计算图,Caffe保留了计算图中所有的中间值以确保前向和反向迭代的准确性。一个典型的Net开始于data layer——从磁盘中加载数据,终止于loss layer——计算如分类和重构这些任务的目标函数。

Net由一系列层和它们之间的相互连接构成,用的是一种文本建模语言。

Net::Init()进行模型的初始化。初始化主要实现两个操作:创建blobs和layers以搭建整个网络DAG图,以及调用layers的SetUp()函数。初始化时也会做另一些记录,例如确认整个网络结构的正确与否等。另外,初始化期间,Net会打印其初始化日志到INFO信息中。网络构建完之后,通过设置Caffe::mode()函数中的Caffe::set_mode(),即可实现在CPU或GPU上的运行,实验已经证明采用CPU或GPU计算得到的结果相同。

模型是利用文本protocol buffer(prototxt)语言定义的,学习好的模型会被序列化地存储在二进制protocol buffer (binaryproto) .caffemodel文件中。 模型格式用protobuf语言定义在caffe.proto文件中。

3、总结

上面只是简单地从理论模型层面上对caffe架构以及模型进行介绍,更深入地理解必须结合caffe源码做进一步地分析,个人建议:在阅读caffe源码的同时回过头来理解这些稍微理论性的知识,不仅有助于源码的理解,更加有助于caffe整体设计思想的深入了解。

Caffe学习笔记(一):Caffe架构及其模型解析的更多相关文章

  1. Caffe学习笔记(三):Caffe数据是如何输入和输出的?

    Caffe学习笔记(三):Caffe数据是如何输入和输出的? Caffe中的数据流以Blobs进行传输,在<Caffe学习笔记(一):Caffe架构及其模型解析>中已经对Blobs进行了简 ...

  2. Caffe学习笔记(二):Caffe前传与反传、损失函数、调优

    Caffe学习笔记(二):Caffe前传与反传.损失函数.调优 在caffe框架中,前传/反传(forward and backward)是一个网络中最重要的计算过程:损失函数(loss)是学习的驱动 ...

  3. Caffe学习笔记4图像特征进行可视化

    Caffe学习笔记4图像特征进行可视化 本文为原创作品,未经本人同意,禁止转载,禁止用于商业用途!本人对博客使用拥有最终解释权 欢迎关注我的博客:http://blog.csdn.net/hit201 ...

  4. Caffe学习笔记3

    Caffe学习笔记3 本文为原创作品,未经本人同意,禁止转载,禁止用于商业用途!本人对博客使用拥有最终解释权 欢迎关注我的博客:http://blog.csdn.net/hit2015spring和h ...

  5. Caffe 学习笔记1

    Caffe 学习笔记1 本文为原创作品,未经本人同意,禁止转载,禁止用于商业用途!本人对博客使用拥有最终解释权 欢迎关注我的博客:http://blog.csdn.net/hit2015spring和 ...

  6. Caffe学习笔记2

    Caffe学习笔记2-用一个预训练模型提取特征 本文为原创作品,未经本人同意,禁止转载,禁止用于商业用途!本人对博客使用拥有最终解释权 欢迎关注我的博客:http://blog.csdn.net/hi ...

  7. Caffe学习笔记2--Ubuntu 14.04 64bit 安装Caffe(GPU版本)

    0.检查配置 1. VMWare上运行的Ubuntu,并不能支持真实的GPU(除了特定版本的VMWare和特定的GPU,要求条件严格,所以我在VMWare上搭建好了Caffe环境后,又重新在Windo ...

  8. CAFFE学习笔记(五)用caffe跑自己的jpg数据

    1 收集自己的数据 1-1 我的训练集与测试集的来源:表情包 由于网上一幅一幅图片下载非常麻烦,所以我干脆下载了两个eif表情包.同一个表情包里的图像都有很强的相似性,因此可以当成一类图像来使用.下载 ...

  9. CAFFE学习笔记(四)将自己的jpg数据转成lmdb格式

    1 引言 1-1 以example_mnist为例,如何加载属于自己的测试集? 首先抛出一个问题:在example_mnist这个例子中,测试集是人家给好了的.那么如果我们想自己试着手写几个数字然后验 ...

随机推荐

  1. Spoken English Practice(1、This is between you and me, Don't let it out. 2、Don't let your dreams be dreams, no matter how hard it gets, say to yourself, I'm going to make it.)

    绿色:连读:                  红色:略读:               蓝色:浊化:               橙色:弱读     下划线_为浊化 口语蜕变(2017/7/12) ...

  2. HDU3658—How many words

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3658 题目意思: 题目的意思是在52个英文字母里面选择m个字母组成一个字符串,满足以下两个条件.第一是 ...

  3. 重装系统后Myeclipse遇到的项目配置问题--一个菜鸟的经历!

    电脑不知道为什么流量突然变大了. 一查svchost.exe后台下载老多系统.某某安全卫士根本么用,运维说用某企鹅管家. 结果一个鸟样.. 之前是系统是32位的win7  4G内存用不完.又打算升级内 ...

  4. git学习——<五>git分支

    git学习——<一>git安装 git学习——<二>git配置文件 git学习——<三>git操作 git学习——<四>git版本管理 一.提出问题 今 ...

  5. python中lambda使用

    一.lambda函数 1.lambda函数基础: lambda函数也叫匿名函数,即,函数没有具体的名称,而用def创建的方法是有名称的.如下: """命名的foo函数&q ...

  6. Linux IPC之管道通信

    2017-04-07 管道通信在linux中使用较为频繁的进程通信机制.基于unix一切皆文件的传统,管道也是一种文件.所以可以使用一般的VFS接口对管道进行读写操作,如read.write.具体管道 ...

  7. 使用maven为web工程引入jstl包时报错了

    原pom文件: <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</a ...

  8. Matlab GUI memo

    有一段时间没写博客,一周4篇文章都坚持不下来,不知道写哪个方面的内容,写研究相关就怕论文查重查到,其他方面也没太多时间去学.还是花时间多学点其他方面.废话到此,很早就做过matlab gui相关,现在 ...

  9. PSR-2 代码风格规范

    https://blog.csdn.net/qq_28602957/article/details/52248239 这篇规范是PSR-1(基本代码规范)的扩展和继承. 本规通过制定一系列规范化PHP ...

  10. bat命令运行java程序

    注意空格 本文主要介绍在window下bat批处理文件调用java的方法. @echo off echo 正在加密,请稍后....echo path:%~dp0 set base=%~dp0 set ...