2018-7-16
简介
Caffe由加州大学伯克利的PHD贾扬清开发, 全称Convolutional Architecture for Fast Feature Embedding, 是一个清晰而高效的开源深度学习框架,
目前由伯克利视觉学中心(Berkeley Vision and Learning Center, BVLC)进行维护;
(贾扬清曾就职于MSRA, NEC, Google Brain, 他也是TensorFlow的作者之一, 目前任职于Facebook FAIR实验室; )
Caffe基本流程: Caffe遵循了神经网络的一个简单假设——所有的计算都是以layer的形式表示的,
layer做的事情就是获得一些数据, 然后输出一些计算以后的结果;
比如说卷积——就是输入一个图像, 然后和这一层的参数(filter)做卷积, 然后输出卷积的结果;
每一个层级(layer)需要做两个计算: 前向forward是从输入计算输出, 然后反向backward是从上面给的gradient来计算相对于输入的gradient,
只要这两个函数实现了以后, 我们就可以把很多层连接成一个网络, 这个网络做的事情就是输入我们的数据(图像或者语音等),
然后来计算我们需要的输出(比如说识别的标签), 在训练的时候, 我们可以根据已有的标签来计算损失和gradient, 然后用gradient来更新网络的参数;
github页: https://github.com/BVLC/caffe
官页: http://caffe.berkeleyvision.org/tutorial/
看看视频: https://www.youtube.com/watch?v=6eBpjEdgSm0&index=0&list=PL5B692fm6—tI-ijknnVZWbXU2H4JpSYe
纸上谈兵
https://www.cnblogs.com/573177885qq/p/6079280.html
从四个层次来理解: Blob, Layer,Net,Solver;
(不要太在意名词原意, 人类为抽象的一个概念赋予名称)
1.Blob
Caffe 使用 blobs 结构来存储, 交换和处理网络中正向和反向迭代时的数据和导数信息
(简而言之, 是caffe 输入, 输出, 各个模块之间交换, 处理的一种数据结构)
1.Layer
代表神经网络的层, 由各种各样的层来构成整个网络;
一般一个图像或样本会从数据层中读进来, 然后一层一层的往后传;
除了数据层比较特殊之外, 其余大部分层都包含4个函数: LayerSetUp, Reshape, Forward, Backward;
其中LayerSetup用于初始化层, 开辟空间, 填充初始值什么的;
Reshape是对输入数据是如何在层之间传递的呢?
每一层都会有一个(或多个)Bottom和top, 分别存储输入和输出(train_val.prototxt可配置)
3.Net
Net就是把各种层按train_val.prototxt的定义堆叠在一起, 首先进行每个层的初始化, 然后不断进行Update, 每更新一次就进行一次整体的前向传播和反向传播, 然后把每层计算得到的梯度计算进去, 完成一次更新, 这里注意每层在Backward中只是计算dW和db, 而W和b的更新是在Net的Update里最后一起更新的;
而且**在caffe里训练模型的时候一般会有两个Net, 一个train一个test;**刚开始训练网络时前面的一大堆输出, 网络的结构什么的也都是这里输出的;
4.Solver
Solver是按solver.prototxt的参数定义对Net进行训练, 首先会初始化一个TrainNet和一个TestNet然后其中的Step函数会对网络不断进行迭代, 主要就是两个步骤反复迭代:
①不断利用ComputeUpdateValue计算迭代相关参数, 比如计算learning rate, 把weight decay
②调用Net的Update函数对整个网络进行更新; 迭代中的一大堆输出也是在这里输出的, 比如当前的loss
跑一个训练
- 手写数字识别
- for windows
建立数据/标签
- 将手写数字图片,按文件夹分门别类,放到统一目录, 例`└─train`, 该分类用作训练
- 再从每个别类中选一定的比例, 放到测试目录, 例`├─val`, 该分类用测试迭代后验证结果
-
F:\caffework>
└─images
├─train
│ ├─0
│ ├─1
│ ├─2
│ ├─3
│ ├─4
│ ├─5
│ ├─6
│ ├─7
│ ├─8
│ └─9
└─val
├─0
├─1
├─2
├─3
├─4
├─5
├─6
├─7
├─8
└─9 生成label文本文件`train.txt, val.txt`, 内容是文件名加标签的格式, 例:
0\IMG_20180706_173009R_112.jpg 0
0\IMG_20180706_173009R_113.jpg 0
0IMG_20180706_173009R_114.jpg 0
1\IMG_20180706_173009R_125.jpg 1
...
转换图片
图片文件是不能被Caffe识别的, 需要使用Caffe的convert_imageset.exe工具转化为lmdb数据
- 转换train图片数据脚本 :
SET GLOG_logtostderr=1
set a=F:\caffework\images\train\
set b=F:\caffework\images\train\train.txt
set c=F:\caffework\trainlmdb
"D:\Program Files\caffe\bin\convert_imageset.exe" -resize_height=56 -resize_width=128 %a% %b% %c%
pause- 转换val图片数据脚本 :
SET GLOG_logtostderr=1
set a=F:\caffework\images\val\
set b=F:\caffework\images\val\val.txt
set c=F:\caffework\vallmdb
"D:\Program Files\caffe\bin\convert_imageset.exe" -resize_height=56 -resize_width=128 %a% %b% %c%
pause- 它在输出目录生成两个文件
data.mdb,lock.mdb例
F:\caffework>
├─trainlmdb
│ data.mdb
│ lock.mdb
│
└─vallmdb
data.mdb
lock.mdb public static void genTrainTxt(String dir) {
File root= new File(dir);
if( !root.isDirectory() ) {
throw new RuntimeException(root+"is not directory.");
}
File [] rlsts = root.listFiles();
StringBuilder sb = new StringBuilder(200);
for (File rlst: rlsts) {
File[] irr =rlst.listFiles();
for (int i = 0; i < irr.length; i++) {
File [] irs = irr[i].listFiles();
for(File img: irs) {
if(! img.isDirectory()) {
sb.append(img.getPath()+" "+i+"\r\n");
}
}
}
}
writerText(sb.toString(),dir+"/gan.txt",null);
}踩坑: 如果出现类似的错误:
F0722 14:27:40.745323 7148 db_lmdb.cpp:18] Check failed: _mkdir转换输出的目录不能用手动建立.
注意一下相对路径train.txt的路径 分类标签的, 是相对路径路径1\IMG_20180706_173009R_125.jpg 1,后面转换
创建模型并编写配置文件
重点来了
Caffe几个重要文件:
-
solver.prototxt对应Solver -net:= 指定待训练模型结构文件, 即train_val.prototxt
-test_interval:= 测试间隔, 即每隔多少次迭代进行一次测试 -test_iteration:= 指定测试时进行的迭代次数 -base_lr:= 指定基本学习率 -lr_policy:= 学习率变更策略, 这里有介绍, 可供参考 -max_iter:= 模型训练的最大迭代次数 -snapshot:= 快照, 每隔几次保存一次模型参数 -snapshot_prefix:= 保存模型文件的前缀, 可以是路径-
solver_mode := 指定训练模式, 即GPU/CPU
红色,为必须参数, 参考这里
-
-
train_val.prototxt定义layer堆叠方式,组建成Net 是用来存放模型结构的地方, 模型的结构主要以layer为单位来构建;配置有点多.. 参考两个使用的配置文件链接 里面的注释:
-
启动 启动脚本
train_weight.bat貌似用了google某种模型
SET GLOG_logtostderr=1
"D:\Program Files\caffe\bin\caffe.exe" train --solver=F:\caffework\solver.prototxt --weights=F:\caffework\bvlc_googlenet.caffemodel
pause
- 从指定的快照开始跑(不能和—weights一起使用)
--snapshot=F:\caffework\cifar10_full_iter_10000.solverstate
启动参数参考: https://www.cnblogs.com/denny402/p/5076285.html
- 最后目录结构
F:\caffework
│ bvlc_googlenet.caffemodel
│ conver.bat
│ mean.bat
│ solver.prototxt
│ train_val.prototxt
│ train_weight.bat
│
│
├─images
│ │
│ │
│ ├─train
│ │ │ train.txt
│ │ │
│ │ └─0123...//训练分类及文件
│ └─val
│ │ val.txt
│ │
│ └─0123...//验证分类及文件
├─snapshot
├─trainlmdb
│ data.mdb
│ lock.mdb
│
└─vallmdb
data.mdb
lock.mdbcaffe安装目录
D:\Program Files\caffe
- 一些错误
图大小修改, 引发的配置问题:
数据(data)层(layer)的crop_size参数不能大于图片本身
transform_param {
mirror: true
crop_size: 56
mean_value: 93
mean_value: 124
mean_value: 120
}
还有 Check failed: shape[i] >= 0 (-5 vs. 0)错误
https://www.jianshu.com/p/9ffea2ce1456