Caffe学习笔记(一):Caffe架构及其模型解析
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架构及其模型解析的更多相关文章
- Caffe学习笔记(三):Caffe数据是如何输入和输出的?
Caffe学习笔记(三):Caffe数据是如何输入和输出的? Caffe中的数据流以Blobs进行传输,在<Caffe学习笔记(一):Caffe架构及其模型解析>中已经对Blobs进行了简 ...
- Caffe学习笔记(二):Caffe前传与反传、损失函数、调优
Caffe学习笔记(二):Caffe前传与反传.损失函数.调优 在caffe框架中,前传/反传(forward and backward)是一个网络中最重要的计算过程:损失函数(loss)是学习的驱动 ...
- Caffe学习笔记4图像特征进行可视化
Caffe学习笔记4图像特征进行可视化 本文为原创作品,未经本人同意,禁止转载,禁止用于商业用途!本人对博客使用拥有最终解释权 欢迎关注我的博客:http://blog.csdn.net/hit201 ...
- Caffe学习笔记3
Caffe学习笔记3 本文为原创作品,未经本人同意,禁止转载,禁止用于商业用途!本人对博客使用拥有最终解释权 欢迎关注我的博客:http://blog.csdn.net/hit2015spring和h ...
- Caffe 学习笔记1
Caffe 学习笔记1 本文为原创作品,未经本人同意,禁止转载,禁止用于商业用途!本人对博客使用拥有最终解释权 欢迎关注我的博客:http://blog.csdn.net/hit2015spring和 ...
- Caffe学习笔记2
Caffe学习笔记2-用一个预训练模型提取特征 本文为原创作品,未经本人同意,禁止转载,禁止用于商业用途!本人对博客使用拥有最终解释权 欢迎关注我的博客:http://blog.csdn.net/hi ...
- Caffe学习笔记2--Ubuntu 14.04 64bit 安装Caffe(GPU版本)
0.检查配置 1. VMWare上运行的Ubuntu,并不能支持真实的GPU(除了特定版本的VMWare和特定的GPU,要求条件严格,所以我在VMWare上搭建好了Caffe环境后,又重新在Windo ...
- CAFFE学习笔记(五)用caffe跑自己的jpg数据
1 收集自己的数据 1-1 我的训练集与测试集的来源:表情包 由于网上一幅一幅图片下载非常麻烦,所以我干脆下载了两个eif表情包.同一个表情包里的图像都有很强的相似性,因此可以当成一类图像来使用.下载 ...
- CAFFE学习笔记(四)将自己的jpg数据转成lmdb格式
1 引言 1-1 以example_mnist为例,如何加载属于自己的测试集? 首先抛出一个问题:在example_mnist这个例子中,测试集是人家给好了的.那么如果我们想自己试着手写几个数字然后验 ...
随机推荐
- DNS服务简介
一.域名系统 1.域名系统概述 域名系统DNS(Domain Name System)是因特网使用的命名系统,用来把便于人们使用的机器名字转换成为IP地址.域名系统其实就是名字系统.为什么不叫“名字” ...
- Python 常用资源
Python:https://www.python.org/ftp/python/ Django:https://www.djangoproject.com/download/
- 【转载】为什么不常见include .c文件
备:对于#include <filename.h> ,编译器从标准库路径开始搜索 filename.h 对于#include “filename.h” ,编译器从用户的工作 ...
- Storm-源码分析-LocalState (backtype.storm.utils)
LocalState A simple, durable, atomic K/V database. *Very inefficient*, should only be used for occas ...
- linux下安装JDK,及配置环境变量
首先去官网https://www.oracle.com/technetwork/java/javase/downloads/index.html下载最新的JDK版本: 以下操作在root用户下操作 第 ...
- requests设置Authorization
headers = {"Authorization", "Bearer {}".format(token_string)} r = requests.get(& ...
- 【我的Android进阶之旅】Android 混淆文件资源分类整理
之前将所有的混淆都配置在一个 proguard-rules.pro 这个Android Studio新建项目时自动生成的文件里面,而随着项目功能迭代越来越多,代码量越来越多,引用的第二方库.第三方库都 ...
- java获取src下文件
方式一: InputStream in = Test.class .getResourceAsStream("/env.properties"); URL url = Test.c ...
- 【Android】自己定义相机的实现(支持连续拍照、前后摄像头切换、连续对焦)
~转载请注明http://blog.csdn.net/u013015161/article/details/46921257 介绍 这几天.写了一个自己定义照相机的demo.支持连续拍照和摄像头切换. ...
- SpringBoot-URL路由:@Controller和@RequestMapping
SpringBoot定义URL处理方法:@Controller和@RequestMapping @Controller标注的类表示的是一个处理HTTP请求的控制器(即MVC中的C),该类中所有被@Re ...