caffe学习笔记3.1 -- caffe的三级结构

Caffe总体架构 前面已经将Caffe搭建好,现在来介绍一下Caffe的具体知识。本人也在学习中,如有不精,请指点。 阅读详情

在caffe教程中,介绍了caffe的三级结构:Blobs, Layers,Nets.如下图所示:

深度网络是一个复杂的模型,caffe定义了一个层与层之间连接的网络模型。这个网络定义了从输入层到损失的所有模型。caffe使用blobs结构存储,交换和处理网络中正向和反向迭代时的数据和导数信息,blob是Caffe的标准数组结构,它提供了一个统一的内存接口。Layer是Caffe模型和计算的基本单元。Net是一系列的Layer和其连接的集合,Blob详细描述了信息是如何在Layer和net中存储和交换的。

solving:是求解方法,分别配置解耦模型和优化方法


1. Blob存储与交换

Blob是caffe中负责数据传递和处理的包,并且提供了在CPU与GPU之间同步处理的功能。从数学角度看,Blob是C语言风格的一个连续存数的N维数组。

Caffe利用Blobs存储和交换数据,Blobs提供了统一的内存接口存储某种类型的数据,如批处理的图像数据,模型参数和用与优化算法的导数。

Blobs可以根据CPU主机和GPU设备的需要,屏蔽CPU/GPU计算和混合操作中的开销,主机和设备的内存按需求分配(lazily),以提高内存利用率。

对于批处理的图片来说,Blobs常规的维度为:图像数据的个数N * 通道数K * 图像高度H * 图像宽度W。Blob按行存储, 这使得它最后/最右面的维度更新的最快。比如,在一个4维的blob中,位置为(n,k,h,w)的值的物理位置为((n * K + k) * H + h) * W + w.

  • Number/N是每批处理数据的规模,批量处理数据有利于提高设备处理和交换数据的吞吐率。在Imagenet上训练数据每批有256张图像,则N=256.
  • Channel/K是特征维度,对于RGB图像K=3.

虽然在Caffe在用于图像数据过程中,Blob都是4维的,但是它完全可以用于非图像数据。例如,如果你仅需要类似于传统多层感知机那样的全连接网络,使用2维的blobs(形式为(N,D)) , 然后调用InnerProdectLayer(全连接层)即可。

Blob的维度参数根据层的类型和配置而变化,对于由96个规模为11*11,输入为3通道的滤波器构成的卷积层,blob的维度为96*3×11*11,对于一个输入是1024维,输出是1000维的内几层和全连接层,blob的维度是1000*1024.

对于一些特定的数据,自己设计输入工具或数据层是有必要的,但是,一旦数据准备完毕,各种层模块会帮你完成剩下的工作。


实现细节:

对于blob中的数据,我们通常会关心它的值和梯度,因此,blob存储了两块数据内容:data和diff。前者是通过网络的普通数据,后者是网络反向计算得到的梯度。

而且,因为数据既可以存储在CPU上,又可以存储在GPU上,因而有两种不同的访问方式:静态方式,不改变数值,动态方式,改变数值。

const Dtype* cpu_data() const;
Dtype* mutable_cpu_data();
(gpu和diff类似)

这么设计是为了用SyncedMem类来同步CPU与GPU上的数值,以隐藏同步细节,最小化传送数据。一个准则是,如果你不想改变数值,就一直用常数调用,不要在你的项目中存储指针,每层操作blob时,调用相应的函数获取它的指针,因为SyncedMem需要用这种方式确定何时需要复制数据。

实际上,使用GPU时,Caffe中的CPU 代码先从磁盘加载到blob,调用一个(GPU)设备核使GPU进行计算, 再将算好的blob数据送入下一层,忽略了底层的细节,同时又能维持高效的运算。一旦所有的层都有GPU实现,那么所有中间数据和梯度都会保存在GPU上。


下面的例子解释blub何时复制数据:

// Assuming that data are on the CPU initially, and we have a blob.假定数据在CPU上进行初始化,我们有一个blob
const Dtype* foo;
Dtype* bar;
foo = blob.gpu_data(); // data copied cpu->gpu.数据从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. 没有数据拷贝,依旧在gpu
foo = blob.cpu_data(); // data copied gpu->cpu, since the gpu side has modified the data 数据从gpu复制到cpu,因为gpu端已经修改了数据
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.数据从cpu到gpu
bar = blob.mutable_cpu_data(); // data copied gpu->cpu.数据从gpu到cpu


2. Layer : 计算和连接

这一层是非常重要的模型,是执行计算的基本单元, Layers可以进行的计算有:convolve filters(卷积滤波), pool(池化),inner products(内积), 及一些非线性运算如rectified-linear(限制线性运算),sigmoid及元素级的数据转换,normalize(归一化),数据加载,计算损失,如softmax和hinge。


这一层通过bottom(底部)连接层接收数据,通过top(顶部)连接层输出数据

每个类型的层都定义了三种重要运算:setup, forward, 和backward.

  1. Setup: 在模型初始化时,初始化层和它的连接
  2. Forward: 从bottom给定的输入计算输出,传到top层中
  3. Backward: 给定输出层的梯度,计算相对于输入层的梯度,并传到bottom层,一个有参的layer需要计算相对于各个参数的梯度并存储。

特别的,Forward和Backward函数有CPU和GPU两种执行方式。如果你没有执行GPU版本,layer会转为作为备选的CPU方式,这会增加额外的数据传送成本,但是对于一些快速实验还是很方便的(尽管输入数据要由gpu到cpu,之后输出数据从gpu回到cpu)。

Layers承担了整个网络的两个核心操作: 前向传播,接收输入计算输出;反向传播,接收关于输出的梯度,计算参数的梯度并反向传播给前面的层,由此组成了每个layer的前向和反向通道。

由于caffe网络的组合性和其代码的模块化,定义layer是很容易的,只要定义好setup,forward,backward,就可以将layer接入到网络中。



Net的定义和操作:

net通过组合和自动微分,定义了一个函数和其对应的梯度。通过各个层的输出计算这个函数,执行给定的任务。并通过组合各个层的反向传播过程计算学习任务中损失函数的梯度,caffe模型是一种端到端的机器学习引擎。

net是由一系列层组成的有向无环图,Caffe保留了图中所有层的中间值以确保前向和反向迭代的正确性。一个典型的net开始于数据(data)层,从磁盘中加载数据,结束于损失(loss)层,计算目标任务,如分类和重构。

net模型定义在一个纯文本模型语言中,有一系列的层和它们的连接构成。一个简单的逻辑回归定义如下:


其网络结构定义为:

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()初始化,初始化主要做两件事情:通过创建blobs和layers搭建整个网络的DAG图; 调用layers的Setup()函数。初始化时会有一系列的记录,例如整个网络的结构是否正确构建。同时,Net在初始化阶段会将其日志答应在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

注意:caffe中网络的构件与设备无关,回想之前解释过的blobs和layers是为了从模型定义中隐藏实现细节的,网络构建完成之后,通过设置Caffe::mode()和Caffe::set_mode(),网络将在CPU或GPU中运行。CPU和GPU的实现结果相同,CPU和GPU可以无缝切换并且独立于模型定义


Model格式

Caffe的模型定义在纯文本的协议上(prototxt),学习好的模型被序列化到二进制protocol buffer(binaryproto).caffemodel文件中。

模型格式用protobuf语言定义在caffe.proto文件中。这部分也会在笔记中解释。



参考资料:

Caffe官网: http://caffe.berkeleyvision.org/tutorial/net_layer_blob.html



Caffe学习笔记(一):Caffe架构及其模型解析 Caffe学习(一):Caffe架构及其模型解析         写在前面:关于caffe平台如何快速搭建以及如何在caffe上进行训练与预测,请参见前面的文章《caffe平台快速搭建:caffe+window7+vs2013》、《Windows平台上Caffe的训练与学习方法(以数据库CIFAR-10为例)》。         本文主要介绍Caffe的总体框架,并对caffe 阅读详情

相关推荐

caffe学习笔记(二)——caffe结构分析

一、caffe目录结构: data —— 用于存放下载的训练数据 docs —— 帮助文档 examples —— 代码样例 matlab —— MATLAB接口文件 python —— PYTHON接口文件 models —— 一些配置好的模型参数 scripts —— 一些文档和数据会用到的脚本 核心代码: tools —— 保存的源码是用于生成二进制处理程序的,caffe在训练时实际是直接调

孤旅人。。。的博客 3256

参看caffe中三通道彩色图像的卷积过程

E:\caffe-windows-lib\matlab\hdf5creation\predict_label_testdata_for_analysis.m代码:clearvars;close all;if ~exist('ttest_data','var')||~exist('means','var') test_data = load('ttest_data.mat'); % load

机器学习的小学生 4744

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

Caffe学习笔记(三):Caffe之caffe数据是如何输入和输出的?        Caffe中的数据流以Blobs进行传输,在《Caffe学习笔记(一):Caffe架构及其模型解析》中已经对Blobs进行了简单的介绍。下面对caffe数据是如何输入和输出做更加详细的分析。1、输入/输出之Blobs        caffe使用blobs结构来存储、交换并处理网络中正向和反向迭代时的数据和导数

成长Bar的博客专栏 4965

Caffe学习笔记2-Caffe的三级结构(Blobs,Layers,Nets)

Caffe学习笔记2-Caffe的三级结构(Blobs,Layers,Nets) By YuFeiGan 2014-12-09 更新日期:2014-12-10 根据Caffe官方文档介绍,caffe大致可以分为三层结构blob,layer,net。数据的保存,交换以及操作都是以blob的形式进行的,layer是模型和计算的基础,net整和并连接layer。 Blobs B

965

深度学习_21天实战Caffe.pdf

深度学习_21天实战Caffe.pdf 原 深度学习21天实战caffe学习笔记《1:深度学习的过往》 1. 深度学习DL: 1.1、有监督学习、无监督学习、过拟合、训练样本、泛化、训练集、验证集、测试集这些和深度学习有关的知识需要实现明白,这里有一个深度学习的资料你们可以去下载; http://download.csdn.net/detail/julialove102123...

chenxuanhanhao的专栏 3319

【Caffe-Windows】Caffe1.1.0+VS2017+CUDA9.2+cuDNN9.2+OpenCV3.4.3+OpenBLAS+Windows配置教程

Caffe-Windows Configuration Tutorial In VS2017_x64 先前配置了VS2017环境下的OpenPose,其中有第三方库Caffe,不过似乎Caffe官方并不支持为VS2017编译,其实有支持VS2017的Caffe2,不过现阶段功能不如Caffe完善。在这里提供Caffe1.1.0于VS2017环境下利用CMake配置的教程。 环境 操作系统:Win...

SkalDak BloOoG 5713

配置opencv3.1+caffe

caffe reid https://github.com/zlmzju/caffe/tree/reidcaffe install http://caffe.berkeleyvision.org/install_apt.htmlUbuntu16.04 14.04安装配置Caffe(GPU版):https://www.cnblogs.com/go-better/p/7161006.htmlUbunt...

凹酱的DEEP LEARNING 2970

Caffe 数据结构——Blob(上)

最近一直在看Caffe C++ 这块的东西,特此整理此份Caffe 学习专栏,所有代码均基于C++实现。本篇博文我们将介绍Blob,并从源码去分析Blob在Caffe中是干什么的,怎么使用它,废话不多说。下面开始介绍Blob。 Blob作为Caffe中用于存储和交换数据的基础数据结构。Blob是一个4维的数组,BIob提供了统一的存储器接口。 Blob在内存中中表示为4维数组,维度从低到高为(...

CVer 1861

Caffe-Windows + Anaconda3编译Caffe的python接口

一:目的 Caffe-Windows编译python接口; 网上找了很多资料,基本上都是用Anaconda2进行编译的,但是个人电脑中装的是Anaconda3,故这里采用Anaconda3进行编译并做下记录。 二:编译过程 1. 思路 个人电脑里装了python27,python36和Anaconda3,而Caffe-Windows编译python接口基本上都是基于pytho

nichengwuxiao的博客 6029

caffe网络模型各层详解(中文版)

caffe网络模型各层详解(中文版) 参考网址:https://blog.csdn.net/qq_34220460/article/details/79872830 一.数据层及参数 要运行caffe,需要先创建一个模型(model),如比较常用的Lenet,Alex等, 而一个模型由多个屋(layer)构成,每一屋又由许多参数组成。所有的参数都定义在caffe.proto这个文件中。要熟练...

a1809032425的博客 3578

NRF52832调试方法1——HardFault_Handler问题定位

一、遇到问题 keil debug模式下,直接点击全速运行(Run)发现程序卡死,点击stop按钮后,停到了HardFault_Handler位置,如下图所示。 此时使用navigate backwards(蓝色左箭头)是无效的,找不到程序卡在哪里。 二、解决办法 此时首先观察register窗口 若Stack为MSP,则复制R13(SP)的值到memory观察窗的地址搜索栏。每一行显示连续的28个地址上的存储信息,每个地址上存有一个字节。 从第21个位置起的连续四个字节是LR的值,

小梁的博客 3650

caffe安装(2)python3.5+opencv3.1+caffe

1. OpenCV3opencv3 与cuda8不兼容,不启动支持cuda 真的是历经千辛啊 安装依赖库 sudo apt-get install cmake git pkg-config libgtk2.0-dev libavcodec-dev libavformat-dev libswscale-dev sudo apt-get install python-dev python-openC

Chunying27的博客 4173

C8T6和ZET6选型更换过程中出现.\Obj\Project.sct(7): error: L6235E: More than one section matches selector - cann

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言一、问题原因二、解决方法三、现象总结 前言 又一件离谱的事情发生了,我之前转换过程中没有发生的错误,今天拿出来程序重新编译了一下,结果他奶奶滴一个新的错误出现了,而且我还完全不知道是什么原因导致的,先上图: 一、问题原因 之前我已经尝试过更换芯片选型,但是没有出现此类问题,今天更改的时候发现了,我还以为是个偶然错误,结果换来换去,还是有这个问题,那我之前说c8t6的程序更改成zet6上跑只需改芯片选型和宏定义岂不是啪啪打.

wx18045623090的博客 1489

Yolov3转化Caffe框架详解

https://blog.csdn.net/watermelon1123/article/details/82083522 下面这部分将着重讲一下如何实现从darknet向yolov3的转换,首先这一过程要感谢chenyingpeng提供的代码,博客在这里。 1.加入upsample层并编译Caffe upsample层的代码在这里,密码bwrd。 其中的upsample_layer.hp...

qwj的博客 1171

【开源训练数据集2】10个最适合机器学习的股票市场数据集

​随着加密货币在世界各地的兴起,人们现在有比以往更多的投资方式。然而,这并不像低买高卖那么简单。如果你能准确预测股市,你就会成为地球上最富有的人之一。因此,之前已经有关于如何利用情绪分析来预测股市的研究。对于那些希望构建类似预测模型的人,本文将介绍 10 个用于机器学习的股票市场和加密货币数据集。

u010542847的博客 2139

SpringBoot4.0+JDK25+GraalVM实战:云原生新纪元,微服务性能翻倍的落地指南

三者的组合不是偶然,而是“框架优化+JDK升级+虚拟机革新”的必然结果——SpringBoot4.0完善了对GraalVM原生镜像的支持,JDK25强化了云原生与AOT编译能力,GraalVM则提供了极致的启动速度和资源利用率,三者协同,刚好命中云原生微服务的核心痛点。SpringBoot4.0+JDK25+GraalVM的组合,不是简单的版本升级,而是云原生微服务的一次性能革命。

2601_94871597的博客 1141

CAFFE 学习-1:基本的CAFFE结构

CAFFE 学习-1:基本的CAFFE结构主要参考: Blob,Layer,Net,Solver

KW的学习博客 324

Python学习第32天:Web前端入门

本文介绍了Web前端开发三大核心技术:HTML、CSS和JavaScript。首先概述了HTML的发展历程和HTML5新特性,详细讲解了常用HTML标签如文本、列表、链接、图像、表格、表单等。其次介绍了CSS的基础语法、选择器、颜色字体设置、盒子模型和布局定位方法。最后简要提及JavaScript为网页添加交互功能的作用。文章为Python开发者提供了前端技术的基础知识,帮助理解网页的结构、样式和行为实现原理。

tigerhhzz的博客 1911

pytorch版本yolov3模型转caffe

目前我有一个pytorch版本的yolov3模型,该模型有 X.cfg和X.pt两个文件 该格式可以与两个主流pytorch工程一致: https://github.com/ultralytics/yolov3 https://github.com/eriklindernoren/PyTorch-YOLOv3 由于caffe没有yolov3所需的upsample层与yolo层,所以需要自己来实现...

一呆飞仙的博客 4279

pycharm报错cannot start the IED:Error occurred during initialization of VMagent library failed...如何解决?

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。

**My Coding Family** 1925

lvgl 9虚拟键盘控件 (lv_keyboard) 使用指南

是 LittlevGL 提供的一个虚拟键盘控件,适用于在图形界面中输入文本。与按钮矩阵类似,虚拟键盘预定义了多个键位布局,支持多种模式和自定义键位映射,能够满足各种文本输入需求。通过与文本区域 (Text Area) 的结合,键盘能够自动将输入的字符传送到指定区域。控件是 LittlevGL 提供的强大虚拟键盘解决方案,适用于任何需要文本输入的界面。通过预定义的键盘模式、自定义键位映射和文本区域自动填充功能,可以大大提升用户输入体验。无论是在嵌入式系统的用户界面中,还是在其他需要虚拟键盘的应用中,

m0_62599305的博客 2185

为 Caffe 添加 Python3 支持

python2已近生命终点,然而 Caffe 却受硬件厂商的拥护。于是我们尝试在 Python3 环境下编译 Caffe。 Caffe Python 3.7 安装 对于 Python 3.3+而言,需要搭配 Protobuf 3。因此不再需要 apt 安装libprotobuf-dev和protobuf-compiler,这二者是Protobuf 2 的。 首先修改 CMakeLists.txt ...

yiran103的专栏 6460

安装Codex时出现无法下载此应用和Microsoft Store初始化失败的解决方案

本文主要介绍了安装Codex时出现无法下载此应用和Microsoft Store初始化失败的解决方案,希望能对使用codex的同学们有所帮助。 文章目录 1. 问题描述 2. Windows 解决方案 3. Mac解决方案

weixin_43178406的博客 7万+

YOLOv3转换为caffe模型

yolov3里面有些层,比如:shortcut, route, upsample, yolo等这些层是caffe不支持的,但在caffe中可以用eltwise替换shortcut,用concat替换route,但是yolo层只能自己实现写了, upsample可以自己在caffe里添加该层的实现。 1 caffe中添加upsample层的实现 感谢chen大神提供的代码。 添加upsample...

nodototao的博客 9660

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

上一篇: caffe学习笔记14(外篇)--使用CodeBlocks调试caffe代码
下一篇: 七月算法机器学习笔记1--机器学习中的数学之数理统计和参数估计
thystar
博客等级 码龄17年 407粉丝 151原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值