caffe框架翻译-理解(转载)

本文转自:  http://dirlt.com/caffe.html

http://blog.csdn.net/songyu0120/article/details/46817085

1 caffe

  • http://caffe.berkeleyvision.org/

1.1 setup

安装需要下面这些组件。这些组件都可以通过apt-get获得。

  • libgoogle-glog-dev # glog
  • libgflags-dev # gflags
  • libhdf5-dev # hdf5
  • liblmdb-dev # lmdb
  • libleveldb-dev # leveldb
  • libsnappy-dev # snappy
  • libopencv-dev # opencv
  • liblapack-dev libblas-dev libatlas-dev libatlas-base-dev libopenblas-dev # blas

1.2 arch

caffe是非常模块化的,可能这和神经网络本身就比较模块化相关。主页上有这个系统的设计哲学:

  • Expression: models and optimizations are defined as plaintext schemas instead of code. # 使用google protocol-buffers来描述网络结构和参数。protobuf居然还可以使用TextFormat载入文件,之前没有不知道还有这个功能。这个功能非常适合描述大规模,结构化,human-readable的数据。
  • Speed: for research and industry alike speed is crucial for state-of-the-art models and massive data. # tensor(在caffe里面叫做blob)既有gpu也有cpu实现。
  • Modularity: new tasks and settings require flexibility and extension. # 下面会说到caffe的几个模块: Solver, Net, Layer, Blob.
  • Openness: scientific and applied progress call for common code, reference models, and reproducibility. # 可以将训练模型参数保存下来进行分发, 存储格式则是protocol-buffers的binary.
  • Community: academic research, startup prototypes, and industrial applications all share strength by joint discussion and development in a BSD-2 project.

这里先大概说一下几个模块:

  • Blob: 是caffe的数据表示,可以表示输入输出数据,也可以表示参数数据。
  • Layer: 不仅可以表示神经网络层,也可以表示数据输入输出层。Blob在Layer上流动(forward & backward)。
  • Net: 神经网络结构,将这些Layers层叠和关联起来。
  • Solver: 协调神经网络的训练和测试,比如使用什么梯度下降以及具体参数,还支保存和恢复训练状态以及存储网络参数。

#note: prototxt描述文件大部分字段都非常好理解。对于不好理解的字段,或者是不知道有哪些参数的话,可以参考src/caffe/proto/caffe.proto. 这个文件里面每个字段都有比较详细说明。

1.2.1 Blob

Blob是一个四维连续数组(4-D contiguous array, type = float32), 使用(n, k, h, w)表示的话,那么每一维的意思分别是:

  • n: number. 输入数据量,比如进行sgd时候的mini-batch大小。
  • c: channel. 如果是图像数据的话可以认为是通道数量。
  • h,w: height, width. 如果是图像数据的话可以认为是图片的高度和宽度。

当然Blob不一定就是用来表示图像输入数据。理解这些维度最重要的一点是,下标w是变化最快的。主页里面举了几个例子:

  • the shape of blob holding 1000 vectors of 16 feature dimensions is 1000 x 16 x 1 x 1.
  • For a convolution layer with 96 filters of 11 x 11 spatial dimension and 3 inputs the blob is 96 x 3 x 11 x 11.
  • For an inner product / fully-connected layer with 1000 output channels and 1024 input channels the parameter blob is 1 x 1 x 1000 x 1024.

Blob内部其实有两个字段data, diff. data表示流动数据(输出数据),而diff则存储BP的梯度。data/diff可以存储于cpu, 也可以存储于gpu. 如果某个layer不支持gpu的话,那么就需要将gpu数据copy到cpu上,造成性能开销。对于python/numpy用户来说,可以用reshape函数来转换为blob: data = data.reshape((-1, c, h, w))

1.2.2 Layer

caffe提供了许多内置layer,比如convolution layer, pool layer, dropout layer, nonlinearity layer等。这些层说明以及具体参数都可以在 这里 查到(文档比代码有一些滞后,文档里面没有说支持了dropout但是实际已经提供)。每个layer有输入一些'bottom' blobs, 输出一些'top' blobs. 输入层是"data"和"label" blobs.

./images/caffe-layer.jpg

Each layer type defines three critical computations: setup, forward, and backward.

  • Setup: initialize the layer and its connections once at model initialization. # 初始化工作
  • Forward: given input from bottom compute the output and send to the top. # 前向转播
  • Backward: given the gradient w.r.t. the top output compute the gradient w.r.t. to the input and send to the bottom. A layer with parameters computes the gradient w.r.t. to its parameters and stores it internally. # 反向转播/计算梯度

caffe支持的layer完整在 http://caffe.berkeleyvision.org/tutorial/layers.html, 部分data layer还支持 预处理 操作

#note: 有可能文档上名字和实际代码对不上,如果是这样的话可以阅读src/caffe/layers/*_layer.cpp找到REGISTER_LAYER_CLASS(name). 其中name就是注册的字符串

1.2.3 Net

net是layers组成的DAG, 并且可以使用文本格式来描述(protocol-buffers TextFormat). 比如下面文本生成的是logistic regression.

name: "LogReg"
layers {name: "mnist"type: DATAtop: "data"top: "label"data_param {source: "input_leveldb"batch_size: 64}
}
layers {name: "ip"type: INNER_PRODUCTbottom: "data"top: "ip"inner_product_param {num_output: 2}
}
layers {name: "loss"type: SOFTMAX_LOSSbottom: "ip"bottom: "label"top: "loss"
}

./images/caffe-net-logreg.jpg

Net有个初始化函数Init(). 它的作用有两个:1. 创建blosb和layers; 2. 调用layers的SetUp函数来初始化layers. 在这个过程中会打印日志来说明。注意在这个阶段并没有指明说是用GPU还是CPU来训练,指定使用什么训练是在solver层面的事情,这样可以将模型和实现分离。Net还有Forward和Backward两个函数,分别调用各个Layers的forward/backward. 最周如果我们进行预测的话,我们先填充好input blobs, 然后调用forward函数,最后获取output blobs作为预测结果。

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 1 1 1 (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 1 1 (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 1 1 1 (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/models会发现,这些例子下面有train.prototxt,还有一个deploy.prototxt. 差别仅仅在于deploy.txt没有data-layer,而是在指定输入的shape.

input: "data"
input_dim: 10
input_dim: 1
input_dim: 28
input_dim: 28

从字面上来看train.prototxt是用来训练出model的,而deploy.prototxt则是用来进行预测的。下面是使用python进行预测的代码:

#note: 我没有使用caffe自身提供的classifier.py, 因为我发现Classifier会对input做一些处理。在进行实验的时候我发现使用Classifier得到的结果比直接使用Net::forward_all接口要差很多。

caffe.set_mode_cpu()
net = caffe.Net('caffe-conf/test.prototxt','uv_iter_10000.caffemodel',caffe.TEST)
data = data.reshape((-1, 1, 28, 28))
out = net.forward_all(**{'data': data})
rs = out['prob'] # 得到的是softmax.
print_timer(<span class="org-string">"predict"</span>)

1.2.4 Solver

solver做了下面这些事情:

  • scaffolds the optimization bookkeeping and creates the training network for learning and test network(s) for evaluation.
  • iteratively optimizes by calling forward / backward and updating parameters # Solver::ComputeUpdateValue()
  • (periodically) evaluates the test networks
  • snapshots the model and solver state throughout the optimization
    • Solver::Snapshot() / Solver::Restore() # 保存和恢复网络参数, 后缀.caffemodel
    • Solver::SnapshotSolverState() / Solver::RestoreSolverState() # 保存和恢复运行状态,后缀.solverstate
    • 文件名称是<prefix>_iter_<N>,其中prefix是指定前缀,N表示迭代轮数。

solver每轮迭代做了下面这些事情:

  • calls network forward to compute the output and loss
  • calls network backward to compute the gradients
    • Stochastic Gradient Descent (SGD),
    • Adaptive Gradient (ADAGRAD),
    • and Nesterov’s Accelerated Gradient (NESTEROV).
    • 如何选择和设置参数可以看 这里
  • incorporates the gradients into parameter updates according to the solver method
  • updates the solver state according to learning rate, history, and method

下面是solver.prototxt的一个示例(从examples/mnist/修改过来的)

# The train/test net protocol buffer definition
net: "caffe-conf/train.prototxt"# 如果test数据量是10000,而bacth_size = 100的话,那么test_iter就应该设置100
# 这样每次进行test就可以把所有的cases都使用上了
test_iter: 90
# Carry out testing every 500 training iterations.
# 每进行500轮迭代进行一次测试
test_interval: 500# 下面这些是训练使用参数
# The base learning rate, momentum and the weight decay of the network.
base_lr: 0.01
momentum: 0.9
weight_decay: 0.0005
# The learning rate policy
lr_policy: "inv"
gamma: 0.0001
power: 0.75# Display every 100 iterations
display: 500
# The maximum number of iterations
max_iter: 10000
# snapshot intermediate results
# 每进行500轮做一次snapshot.
# 每一轮使用的数据量大小为batch_size.
snapshot: 500
snapshot_prefix: "uv"
snapshot_after_train: true
# solver mode: CPU or GPU
# 使用CPU训练
solver_mode: CPU

"net"表示train和test使用同一个net. 在net.prototxt中可以使用include语法来声明说,某个layer是否需要包含在train/test阶段.

如果你在训练时候不想进行test的话,那么可以指定上面的"net"为"train_net". 当然你也可以使用"test_nets"来指定多个test_net.

1.3 python

http://caffe.berkeleyvision.org/tutorial/interfaces.html

caffe interfaces有三种: 1. command line 2. python binding 3. matlab binding. 这里就只写python binding. caffe/examples下面有一些ipynb可以使用ipython-notebook查看。

caffe的python binding功能还是非常完备的

  • caffe.Net is the central interface for loading, configuring, and running models. caffe.Classsifier and caffe.Detector provide convenience interfaces for common tasks.
  • caffe.SGDSolver exposes the solving interface.
  • caffe.io handles input / output with preprocessing and protocol buffers.
  • caffe.draw visualizes network architectures.
  • Caffe blobs are exposed as numpy ndarrays for ease-of-use and efficiency.

我写了个 示例 来解决Kaggle上 手写数字识别 问题,prototxt是在examples/mnist基础上稍作修改的(增加了一个dropout)。

#note: LB上的0.99586不是真实成绩,这个是用mnist自带的数据跑出的模型,而不是kaggle给出的数据。使用kaggle给出的数据最高跑到0.99071. 如果要改进的话,估计可以在caffe-prepare.py上多做一些数据变化来增加数据样例大小(现在只是做了rotate).

训练完成之后,使用某个case作为输入,可以画出conv1, pool1, conv2, pool2输出图像。

./images/caffe-conv1.png ./images/caffe-pool1.png

./images/caffe-conv2.png ./images/caffe-pool2.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/247152.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java生鲜电商平台-SpringCloud微服务架构中分布式事务解决方案

Java生鲜电商平台-SpringCloud微服务架构中分布式事务解决方案 说明&#xff1a;Java生鲜电商平台中由于采用了微服务架构进行业务的处理&#xff0c;买家&#xff0c;卖家&#xff0c;配送&#xff0c;销售&#xff0c;供应商等进行服务化&#xff0c;但是不可避免存在分布式事…

【Yoshua Bengio 亲自解答】机器学习 81 个问题及答案(最全收录)

本文转自&#xff1a;http://mp.weixin.qq.com/s?__bizMzI3MTA0MTk1MA&mid401958262&idx1&sn707f228cf5779a31f0933af903516ba6&scene1&srcid0121zzdeFPtgoRoEviZ3LZDG#rd 译者&#xff1a;张巨岩 王婉婷 李宏菲 戴秋池 这是 Quora 的最新节目&#xf…

基础js逆向练习-登录密码破解(js逆向)

练习平台&#xff1a;逆向账号密码 https://login1.scrape.center/ 直接打开平台&#xff0c;输入密码账号&#xff0c;抓包找到加密的参数携带的位置&#xff0c;这边我们找到的是一个叫token的加密参数&#xff0c;这个参数的携带是一个密文 我们首先考虑一下搜索这个加密的…

python之socket

socket套接字 什么叫socket socket是处于应用层与传输层之间的抽象层,他是一组操作起来非常简单的接口(接受数据)此接口接受数据之后,交由操作系统.socket在python中就是一个模块. socket两个分类 基于文件类型的套接字家族 套接字家族的名字&#xff1a;AF_UNIX unix一切皆文件…

socket补充:通信循环、链接循环、远程操作及黏包现象

socket补充&#xff1a;通信循环、链接循环、远程操作及黏包现象 socket通信循环 server端&#xff1a; import socketphone socket.socket(socket.AF_INET,socket.SOCK_STREAM)phone.bind((127.0.0.1,8080))phone.listen(5)conn, client_addr phone.accept() print(conn, cl…

Java生鲜电商平台-SpringCloud微服务架构中核心要点和实现原理

Java生鲜电商平台-SpringCloud微服务架构中核心要点和实现原理 说明&#xff1a;Java生鲜电商平台中&#xff0c;我们将进一步理解微服务架构的核心要点和实现原理&#xff0c;为读者的实践提供微服务的设计模式&#xff0c;以期让微服务在读者正在工作的项目中起到积极的作用。…

ASP.NET Core Web 应用程序开发期间部署到IIS自定义主机域名并附加到进程调试

想必大家之前在进行ASP.NET Web 应用程序开发期间都有用到过将我们的网站部署到IIS自定义主机域名并附加到进程进行调试。 那我们的ASP.NET Core Web 应用程序又是如何部署到我们的IIS上面进行调试的呢&#xff0c;接下来我们来简单介绍下&#xff1a; 一、安装IIS所需的Host扩…

ASP.NET Core Web 应用程序系列(一)- 使用ASP.NET Core内置的IoC容器DI进行批量依赖注入(MVC当中应用)...

在正式进入主题之前我们来看下几个概念&#xff1a; 一、依赖倒置 依赖倒置是编程五大原则之一&#xff0c;即&#xff1a; 1、上层模块不应该依赖于下层模块&#xff0c;它们共同依赖于一个抽象。 2、抽象不能依赖于具体&#xff0c;具体依赖于抽象。 其中上层就是指使用者&am…

苹果电脑基本设置+Linux 命令+Android 实战集锦

本文微信公众号「AndroidTraveler」首发。 背景 大多数应届毕业生在大学期间使用的比较多的是 windows 电脑&#xff0c;因此初入职场如果拿到一台苹果电脑&#xff0c;可能一时间不能够很快的上手。基于此&#xff0c;这边出了系列视频&#xff0c;通过实际的演示让没使用过苹…

Mac中AndroidStudio没有找到Plugins的问题

我们在windows中都可以正常找到plugins 但是在Mac上AndroidStudio里 setting打开却没有plugins 正准备在Mac上搞一下flutter呢 我感觉智商受到了侮辱&#xff01; 这里其实是mac版本给我开了个玩笑 你可以按快捷键&#xff0c;你就可以找到 快捷键 command ‘,’ 没错就是comm…

进程和操作系统概述

进程和操作系统概述 进程的基础 程序和进程&#xff1a; 程序是一对静态的代码文件 进程是一个正在运行着的程序&#xff0c;抽象概念 进程由操作系统操控调用交于CPU运行 操作系统 1.管理控制协调计算机硬件和软件的关系 2.操作系统的作用&#xff1f; ​ 第一个作用&#xff…

对前端Jenkins自动化部署的研究

1. 安装 安装 Nginx 1.1去官网下直接下载&#xff0c;解压缩 start nginx就可以使了&#xff0c;常用命令&#xff1a; start nginx # 启动 nginx -s reload # 修改配置后重新加载生效 nginx -s reopen # 重新打开日志文件 nginx -t # 配置文件检测是否正确 1.2 安装Jenkins…

ASP.NET Core Web 应用程序系列(二)- 在ASP.NET Core中使用Autofac替换自带DI进行批量依赖注入(MVC当中应用)...

在上一章中主要和大家分享在MVC当中如何使用ASP.NET Core内置的DI进行批量依赖注入&#xff0c;本章将继续和大家分享在ASP.NET Core中如何使用Autofac替换自带DI进行批量依赖注入。 PS&#xff1a;本章将主要采用构造函数注入的方式&#xff0c;下一章将继续分享如何使之能够同…

Java过滤器与SpringMVC拦截器之间的关系与区别

今天学习和认识了一下&#xff0c;过滤器和SpringMVC的拦截器的区别&#xff0c;学到了不少的东西&#xff0c;以前一直以为拦截器就是过滤器实现的&#xff0c;现在想想还真是一种错误啊&#xff0c;而且看的比较粗浅&#xff0c;没有一个全局而又细致的认识&#xff0c;由于已…

二次幂权限设计

设置含有的权限如增删改查减为1,2,4,8,16 如果A包含增删改这5个权限&#xff0c;那A的值为1247 如果B包含增改查这5个权限&#xff0c;那A的值为14813 如果C包含增删改查减这5个权限&#xff0c;那A的值为12481631 7二进制为111,13的二进制为1101,31二进制为11111 1二进制为1&a…

使用putty在linux主机和windows主机之间拷贝文件(已测试可执行)

转载于&#xff0c;请点击 首先下载putty&#xff0c;putty下载地址zip&#xff0c; 解压zip发现里面有plink.exe pscp.exe psftp.exe putty.exe puttygen.exe puttytel.exe等可执行文件&#xff0c;如果只是想要链接主机做一些操作那么使用putty.exe&#xff0c;要想要上传 …

ASP.NET Core Web 应用程序系列(三)- 在ASP.NET Core中使用Autofac替换自带DI进行构造函数和属性的批量依赖注入(MVC当中应用)...

在上一章中主要和大家分享了在ASP.NET Core中如何使用Autofac替换自带DI进行构造函数的批量依赖注入&#xff0c;本章将和大家继续分享如何使之能够同时支持属性的批量依赖注入。 约定&#xff1a; 1、仓储层接口都以“I”开头&#xff0c;以“Repository”结尾。仓储层实现都以…

可视化caffe模型结构及在线可视化

在线可视化caffe模型结构 http://ethereon.github.io/netscope/#/editor 假设Caffe的目录是$(CAFFE_ROOT) 1.编译caffe的python接口 $ make pycaffe 2.装各种依赖 $ pip install pydot $ sudo apt-get install graphviz 3.可视化模型 draw_net.py执行的时候带三个参数 …

iOS核心动画之CALayer(1)

本文目录 一、什么是CALayer二、CALayer的简单使用 回到顶部一、什么是CALayer * 在iOS系统中&#xff0c;你能看得见摸得着的东西基本上都是UIView&#xff0c;比如一个按钮、一个文本标签、一个文本输入框、一个图标等等&#xff0c;这些都是UIView。 * 其实UIView之所以能显…

ASP.NET Core Web 应用程序系列(四)- ASP.NET Core 异步编程之async await

PS&#xff1a;异步编程的本质就是新开任务线程来处理。 约定&#xff1a;异步的方法名均以Async结尾。 实际上呢&#xff0c;异步编程就是通过Task.Run()来实现的。 了解线程的人都知道&#xff0c;新开一个线程来处理事务这个很常见&#xff0c;但是在以往是没办法接收线程里…