解剖caffe mode:Blobs, Layers和Nets
2018-04-08 19:42
627 查看
[b]Implementation Details[/b]一个Blob存储两块内存的数据:data和diff。data是沿着神经网络传递的正常数据,diff则是网络计算的梯度。
另外,实际数值可能存储在CPU或GPU。有两种方式访问数据,对GPU、CPU和diff同样适用:
1、常值访问(const):不改变数值
2、可变访问(mutable): 改变数值
例如,
之所以这样设计,是由于Blob使用SyncedMem类来同步CPU和GPU的数值,来隐藏同步化细节和减少数据传输。一种简单并粗略的方法是若不想改变数值,总是使用常值访问,不把指针存储到所拥有的object。每次影响一个Blob,调用函数来得到指针,因为SyncedMem类需要指针来明白什么时候需要复制数据。
实践中,当存在GPUs,在CPU代码中,从磁盘中加载数据到一个Blob,调用一个设备核来做GPU计算,并且把Blob渡运到下一层,忽略了底层细节并同时保有高层的性能。只要所有层有GPU实现,所有的中间数据和梯度都将保留在GPU里面。当一个Blob将复制数据时,如果想要签出检验,此处是一个例子:
层是模型的本质和计算的基本单元。卷基层、池化层采用内积,并使用非线性等按元素的转换,诸如rectified-linear和sigmoid,归一化,数据加载,类似softmax和hinge来计算损失。最先进的深度学习任务所需的层类别可参考http://caffe.berkeleyvision.org/tutorial/layers.html
一个layer使用bottom连接作为输入,并通过top连接输出。
每一层的type定义三种关键的计算:setup, forward, backward
setup: 在模型初始化时,初始化该层和相关连接一次
forward:使用来自bottom的输入来计算输出,并发送给top
backward: 若给出关于top输出的梯度,计算关于输入的梯度并发送到bottom。具有参数的一层计算关于参数的梯度,并内部存储。
更具体的说,要实现两个Forward和backward函数,分别在CPU和GPU。若不实现GPU版本,layer转而求助于CPU函数作为后备选项。若你想要做快速实验,这将会派上用场,但是会带来额外的数据传输成本(输入将会从CPU复制到GPU,输出将会从CPU复制回GPU)。
对网络运行来说,layer有两个关键的责任:
forward pass:使用输入计算输出
backward pass:使用关于输出的梯度(误差敏感度),来计算关于参数和关于输入的梯度,并一次反向传播到更早的层。
这些传递是每一层前向和反向的组成部分。
通过使用网络的组合性和代码的模块化,开发自定义层轻而易举的完成。对一层定义setup, forward, backward,就是做好了准备放入网络。
Net definition and operation网络net共同的定义一个函数和他的梯度通过组合和自动差分。对于给定的任务,每一层输出的组合计算函数,并且每一层反向的组合从损失计算梯度来学习任务。Caffe模型是端到端机器学习引擎。
Net是在计算图中连接的层集合-准确来说,是有向非循环图DAG。对于层的DAG,caffe做所有的统计来确保前向和反向传递的正确性。一个典型的net在数据层开始(从磁盘中加载数据),在损失层结束(计算诸如分类或重建等任务的目标函数)。net定义为层集合并且连接定义为普通文本的模型化语言。一个简单的logistic regression 分类器为:
Net::Init()操作模型初始化,初始化主要做两件事情:
搭建整个DAG的支架:创建blobs和layer(对于C++怪才们,网络将会保留blobs和layers的终生所有权)
调用层的setup()函数:
也会做其他统计事情,来保证整个网络架构的正确性
在网络初始化期间,网络通过记录INFO来解释初始化,正如以下这样:
Model format
模型使用纯文本协议缓冲区格式(prototext)定义,同时学习的模型序列化为二进制协议缓冲区文件.caffemodel(binaryproto).
模型格式被caffe.proto的协议格式定义模型格式。源文件大多有说明,建议看看。
caffes使用Google协议缓冲具备下述优点,对于caffe模型的灵活性和可扩展性都有贡献:
序列化所拥有的最小尺寸的二进制字符串
高效的串行化(序列化)
与二进制版本兼容的可读文本格式
多种语言的高效接口实现,最突出的C++/Python
另外,实际数值可能存储在CPU或GPU。有两种方式访问数据,对GPU、CPU和diff同样适用:
1、常值访问(const):不改变数值
2、可变访问(mutable): 改变数值
例如,
const Dtype* cpu_data() const; Dtype* mutable_cpu_data();
之所以这样设计,是由于Blob使用SyncedMem类来同步CPU和GPU的数值,来隐藏同步化细节和减少数据传输。一种简单并粗略的方法是若不想改变数值,总是使用常值访问,不把指针存储到所拥有的object。每次影响一个Blob,调用函数来得到指针,因为SyncedMem类需要指针来明白什么时候需要复制数据。
实践中,当存在GPUs,在CPU代码中,从磁盘中加载数据到一个Blob,调用一个设备核来做GPU计算,并且把Blob渡运到下一层,忽略了底层细节并同时保有高层的性能。只要所有层有GPU实现,所有的中间数据和梯度都将保留在GPU里面。当一个Blob将复制数据时,如果想要签出检验,此处是一个例子:
// Assuming that data are on the CPU initially, and we have a blob. const Dtype* foo; Dtype* bar; foo = blob.gpu_data(); // data copied cpu->gpu. foo = blob.cpu_data(); // no data copied since both have up-to-date contents. bar = blob.mutable_gpu_data(); // no data copied. // ... some operations ... bar = blob.mutable_gpu_data(); // no data copied when we are still on GPU. foo = blob.cpu_data(); // data copied gpu->cpu, since the gpu side has modified the data foo = blob.gpu_data(); // no data copied since both have up-to-date contents bar = blob.mutable_cpu_data(); // still no data copied. bar = blob.mutable_gpu_data(); // data copied cpu->gpu. bar = blob.mutable_cpu_data(); // data copied gpu->cpu.Layer computation and connections
层是模型的本质和计算的基本单元。卷基层、池化层采用内积,并使用非线性等按元素的转换,诸如rectified-linear和sigmoid,归一化,数据加载,类似softmax和hinge来计算损失。最先进的深度学习任务所需的层类别可参考http://caffe.berkeleyvision.org/tutorial/layers.html
一个layer使用bottom连接作为输入,并通过top连接输出。
每一层的type定义三种关键的计算:setup, forward, backward
setup: 在模型初始化时,初始化该层和相关连接一次
forward:使用来自bottom的输入来计算输出,并发送给top
backward: 若给出关于top输出的梯度,计算关于输入的梯度并发送到bottom。具有参数的一层计算关于参数的梯度,并内部存储。
更具体的说,要实现两个Forward和backward函数,分别在CPU和GPU。若不实现GPU版本,layer转而求助于CPU函数作为后备选项。若你想要做快速实验,这将会派上用场,但是会带来额外的数据传输成本(输入将会从CPU复制到GPU,输出将会从CPU复制回GPU)。
对网络运行来说,layer有两个关键的责任:
forward pass:使用输入计算输出
backward pass:使用关于输出的梯度(误差敏感度),来计算关于参数和关于输入的梯度,并一次反向传播到更早的层。
这些传递是每一层前向和反向的组成部分。
通过使用网络的组合性和代码的模块化,开发自定义层轻而易举的完成。对一层定义setup, forward, backward,就是做好了准备放入网络。
Net definition and operation网络net共同的定义一个函数和他的梯度通过组合和自动差分。对于给定的任务,每一层输出的组合计算函数,并且每一层反向的组合从损失计算梯度来学习任务。Caffe模型是端到端机器学习引擎。
Net是在计算图中连接的层集合-准确来说,是有向非循环图DAG。对于层的DAG,caffe做所有的统计来确保前向和反向传递的正确性。一个典型的net在数据层开始(从磁盘中加载数据),在损失层结束(计算诸如分类或重建等任务的目标函数)。net定义为层集合并且连接定义为普通文本的模型化语言。一个简单的logistic regression 分类器为:
name: "LogReg" layer { name: "mnist" type: "Data" top: "data" top: "label" data_param { source: "input_leveldb" batch_size: 64 } } layer { name: "ip" type: "InnerProduct" bottom: "data" top: "ip" inner_product_param { num_output: 2 } } layer { name: "loss" type: "SoftmaxWithLoss" bottom: "ip" bottom: "label" top: "loss" }
Net::Init()操作模型初始化,初始化主要做两件事情:
搭建整个DAG的支架:创建blobs和layer(对于C++怪才们,网络将会保留blobs和layers的终生所有权)
调用层的setup()函数:
也会做其他统计事情,来保证整个网络架构的正确性
在网络初始化期间,网络通过记录INFO来解释初始化,正如以下这样:
I0902 22:52:17.931977 2079114000 net.cpp:39] Initializing net from parameters: name: "LogReg" [...model prototxt printout...] # construct the network layer-by-layer I0902 22:52:17.932152 2079114000 net.cpp:67] Creating Layer mnist I0902 22:52:17.932165 2079114000 net.cpp:356] mnist -> data I0902 22:52:17.932188 2079114000 net.cpp:356] mnist -> label I0902 22:52:17.932200 2079114000 net.cpp:96] Setting up mnist I0902 22:52:17.935807 2079114000 data_layer.cpp:135] Opening leveldb input_leveldb I0902 22:52:17.937155 2079114000 data_layer.cpp:195] output data size: 64,1,28,28 I0902 22:52:17.938570 2079114000 net.cpp:103] Top shape: 64 1 28 28 (50176) I0902 22:52:17.938593 2079114000 net.cpp:103] Top shape: 64 (64) I0902 22:52:17.938611 2079114000 net.cpp:67] Creating Layer ip I0902 22:52:17.938617 2079114000 net.cpp:394] ip <- data I0902 22:52:17.939177 2079114000 net.cpp:356] ip -> ip I0902 22:52:17.939196 2079114000 net.cpp:96] Setting up ip I0902 22:52:17.940289 2079114000 net.cpp:103] Top shape: 64 2 (128) I0902 22:52:17.941270 2079114000 net.cpp:67] Creating Layer loss I0902 22:52:17.941305 2079114000 net.cpp:394] loss <- ip I0902 22:52:17.941314 2079114000 net.cpp:394] loss <- label I0902 22:52:17.941323 2079114000 net.cpp:356] loss -> loss # set up the loss and configure the backward pass I0902 22:52:17.941328 2079114000 net.cpp:96] Setting up loss I0902 22:52:17.941328 2079114000 net.cpp:103] Top shape: (1) I0902 22:52:17.941329 2079114000 net.cpp:109] with loss weight 1 I0902 22:52:17.941779 2079114000 net.cpp:170] loss needs backward computation. I0902 22:52:17.941787 2079114000 net.cpp:170] ip needs backward computation. I0902 22:52:17.941794 2079114000 net.cpp:172] mnist does not need backward computation. # determine outputs I0902 22:52:17.941800 2079114000 net.cpp:208] This network produces output loss # finish initialization and report memory usage I0902 22:52:17.941810 2079114000 net.cpp:467] Collecting Learning Rate and Weight Decay. I0902 22:52:17.941818 2079114000 net.cpp:219] Network initialization done. I0902 22:52:17.941824 2079114000 net.cpp:220] Memory required for data: 201476注意:网络的构建和设备无关,回想早期对blobs和layers的解释,他们从模型定义上隐藏了实现细节。网络构建后是运行在CPU还是GPU上,通过在Caffe::mode()中定义的单极开关来设置,可通过Caffe::set_mode()设置。对应于CPU和GPU例程的层产生相同的结果(最多数值错误,并有测试来保护)。CPU/GPU转换是无缝的,并且独立于模型定义。对于研究和部署,最好划分模型和实现。
Model format
模型使用纯文本协议缓冲区格式(prototext)定义,同时学习的模型序列化为二进制协议缓冲区文件.caffemodel(binaryproto).
模型格式被caffe.proto的协议格式定义模型格式。源文件大多有说明,建议看看。
caffes使用Google协议缓冲具备下述优点,对于caffe模型的灵活性和可扩展性都有贡献:
序列化所拥有的最小尺寸的二进制字符串
高效的串行化(序列化)
与二进制版本兼容的可读文本格式
多种语言的高效接口实现,最突出的C++/Python
相关文章推荐
- Caffe学习笔记——Caffe的三级结构(Blobs,Layers,Nets)
- Caffe学习2--Blobs,Layers与Nets
- Caffe学习笔记2-Caffe的三级结构(Blobs,Layers,Nets)
- Caffe学习笔记——Caffe的三级结构(Blobs,Layers,Nets)
- Caffe官网 Tutorial: Nets, Layers, and Blobs caffe模型分解分析
- Caffe学习:Blobs, Layers, and Nets
- Caffe学习笔记3--caffe的三级结构:Blobs, Layers,Nets
- Caffe 初学拾遗(三) Blobs, Layers, and Nets
- 浅读Caffe: Blobs, Layers, and Nets
- Caffe学习笔记2-Caffe的三级结构(Blobs,Layers,Nets)
- Caffe中的Blobs,Layers和Nets
- Caffe学习:Blobs, Layers, and Nets
- caffe 相关--Blobs, Layers, and Nets: anatomy of a Caffe model
- caffe 相关--Blobs, Layers, and Nets: anatomy of a Caffe model
- caffe 相关--Blobs, Layers, and Nets: anatomy of a Caffe model
- caffe 相关--Blobs, Layers, and Nets: anatomy of a Caffe model
- caffe 相关--Blobs, Layers, and Nets: anatomy of a Caffe model
- caffe 相关--Blobs, Layers, and Nets: anatomy of a Caffe model
- caffe 相关--Blobs, Layers, and Nets: anatomy of a Caffe model
- caffe 相关--Blobs, Layers, and Nets: anatomy of a Caffe model