转载:http://blog.youkuaiyun.com/qq_32659887/article/details/71440278
Caffe目录结构:核心代码在caffe/src/caffe
*net.cpp:定义网络,整个网络中含有很多layers. net.cpp负责计算整个网络在训练中的forward\backward过程,也就是计算各个层
的gradient
一个典型的net开始于datalayer(从磁盘中加载数据),终止于losslayer(计算目标函数)
*layers文件夹:各种层的定义,在protobuffer中调用时包含name,type(data,conv,pool...),connectionstructure(input
blobs and out
blobs),layer-spectific parameters(如conv的kernel大小)。定义一个layer需要定义其
setup\在模型初始化时重置layers及其相互之间的关系
forward\从bottom层接受数据,进行计算后将输出送入top层中
backward\给定相对于top层输出的梯度,计算其相对于输入的梯度并传递到bottom
前向和后向函数分别有GPU和CPU两种实现方式。如果没有实现gpu版本,那么layer讲转向作为备用选项的cpu方式。尽管这样会增加
额外的数据传输成本(输入数据由gpu复制到cpu上,之后输出数据从cpu复制到gpu上),但是对于做一些快速的实验这还是很方便
1.Convolution:必填项:1.num_output:指定卷积核的数量
2.kernel_size:指定卷积核的高度和宽度
强烈推荐:weight_filter:指定参数的初始化方案,默认为常数0
可选项:1.bais_term:指定是否给卷积输出添加偏置项,默认是
2.pad:指定在输入图像周围补0的像素个数
3.stride:指定卷集合在输入图像上的滑动步长
4.group;指定分组卷积操作的组数,默认为1不分组,如果g大于1,可以将卷积核的连接限制为输入数据的一个子集
layer{
name=”conv1”
type=”Convolution”
bottom=”data”
top=”conv1”
param{lr_mult:1decay_mult:1}
param{lr_mult:2decay_mult:0}
convolution_param{
num_output:96
kernel_size:11
stride:4
weight_filter{
type:”gaussian”
std:0.01
}
bias_filter{
type:”constant”
value:0
}
}
}
2.Pooling :必填项:1.kernel_size:指定卷积核的高度和宽度
可选项:1.pool:池化方法默认MAX有三种选择最大值,均值和随机池化
2.pad:指定在输入图像周围补0的像素个数
3.stride:指定卷集合在输入图像上的滑动步长
layer{
name:”pool1”
type;“Pooling”
bottom:”conv1”
top:”pool1”
pooling_param{
pool:MAX
kernel_size:3
stride:2
}
}
3.局部响应值归一化LRN
可选项:1.local_size:默认5,对于跨通道的归一化,该参数指未参与求和的通道数,对于通道内的归一化,该参数指的是
参与求和的方形区域的边长
2.alpha:默认1,尺度不变
3.beta:默认5,指数不变
4.norm_region:默认在通道之间归一化ACROSS_CHANNELS,还可以在通道内归一化WITHIN_CHANNEL
局部响应值归一化层同股哟对输入数据的局部归一化操作执行了一种侧抑制的机制。在通道间模
式下,局部区域 沿着临近通道延伸,而 没有空间扩展。在通道内模式下,局部区域在各自的通道
内部的图像平面上延伸。
每个输入值除以(1+(alpha/n)sigma(x^2))^beta实现归一化
4.Loss层:type:SoftmaxWithLoss多分类问题的损失
EulideanLoss
HingeLoss:参数可选:norm;正则项类型L1L2
输入:n*c*h*w预测n*1*1*1真实标签
输出:1*1*1*1计算的损失
layer{
name:”loss”
type:“HingeLoss”
bottom:”pred”
bottom:”label”
hinge_loss_param{
norm:L2}
}
SigmoisCrossEntronpyLoss交叉熵损失
InfogainLoss信息熵损失
5.Accuracy:准确率计算网络输出目标值的准确率
6.Activation:激活层
ReLU:可选参数negative_slope:设置激活函数在负数部分的斜率(默认0)
layer{
name:”relu1”
type:”Relu”
bottom;“conv1”
top:”conv1”}
Sigmoid:
layer{
name:”encode1neuron”
bottom:”encode1”
top:”encode1neuron”
type:”Sigmoid”}
TanH:
layer{
] name:”layer”
bottom:”in”
top:”out”}
type:”TanH”}
AbsVal;绝对值
Power:可选参数:power:默认1
scale:默认1
shift;默认0
(shift+scale*x)^power计算输出
BNLL;log(1+exp(x))计算输出
7.Data层:数据能通过数据层进入caffe网络,数据处于网络的最底层,数据可以从高效率的数据库中读取数据(LevelDB、LMDB),也
可以直接从内存中读取,若对读写效率要求不高,也可以从硬盘上HDFT文件或者普通的图片文件读取。常见的数据预处理操作(减
均值、尺度变换,随机裁剪,镜像)可以通过设定参数TansformationParameter来实现
数据库:类型data。
必填:source:数据库文件的路径
batch_size:网络单词输入数据的数量
可选:rand_skip:跳过开头的rand_skip*rand(0,1)个数据,通常在异步随机梯度下降法使用
backend;选择使用LEVELDB还是LMDB
内存数据:类型:MemoryData.
必填:batch_size,channels,height,width:指定从内存中读取的输入数据块
该层直接从内存中读取数据而不用拷贝。使用这个层时需要调用MemoryDataLayer::Reset(C++)或者Net.set_input_array(python)来指定数据源来源
HDF5:类型:HDF5Data
必填:source文件路径
batch_size
类型:HDF5Output:
必填:file_name:写入文件的路径
图像数据:类型:ImageData
必填:source:text文件的路径名,该text每一行存储一张照片的路径名和对应的标签
batch_size:打包成batch的图片数量
可选:rand_skip
shuffle:默认false
new_height,new_width:根据设置的值,输入的图片将会被调整成给定的尺寸
窗口:WindowData
Dummy:DummyData主要用来开发和调试
8.内积全连接层InnerProduct:必填:num_output:层的输出节点或者理解为滤波器个数
推荐:weight_filter
可选:bias_filter
bias_term
9.分裂Splitting:可以将输入的blob分裂也叫复制成对个输出blob的功能层,通常当一个blob需要给多个层作输入数据时该层会被使用
10.摊平Flattening:latten层用来将尺寸n*c*h*w的blob转换成一个尺寸n*(c*h*w)的输出blob
11.变形Reshape:可选:shape
layer{
reshape_param{
shape{
dim:0
dim:2
dim:3
dim:-1}}}
reshape层在不改变数据的情况下改变输入blob的维度,和flatten操作一样,处理过程在输入blob上进行,没有进行数据的拷贝。输入数
据的维度通过参数设定,使用正数直接指定输出blob的相应维度,也可以使用特殊值设定维度:0表示从层的底层blob中直接提取相应
的维度,即不改变对应的维度。-1表示用其他的维度计算该维度的值,通过保证数据总数个数不变来计算,因此最多设定一个-1
12.连结:类型:Contac:可选:axis:默认1。0表示沿着样本个数的维度串联(所有输入blob在通道上的维度相同),1表示沿着通道维度
串联(所有输入blob在样本个数维度上相同)
用来将多个输入blob连接成一个blob输出
13.切片:类型:Slice。该层按照指定维度(Num或channel)和切片位置的索引讲一个输入blob分成多个blob输出
14.逐个元素操作:Eltwise
15.找最大值的参数:ArgMax
16.SoftMax
17.均值方差标准化:MVN
*blob.cpp:Net中的数据和求导结果通过四维的blob传递,一个层有很多blobs
对data:weightblob大小维number×channel×height×width
对conv层:weightblob大小为output节点数×input节点数×height×width
对innerproduct层:weightblob大小为1*1×output节点数×input节点数
conv层和innerproduct层一样,也有weight和blas,所以在网络结构定义中我么会看到两blobs_lr,第一个是weights第二个是blas。类似
的,weight_decay也有两个
blob中,mutable_cpu/gpu_data()和cpu/gpu_data()用来管理memory,cpu/gpu_diff()和mutable_cpu/gpu_diff()用来计算求导结果。
两种数据值data和梯度diff;存储在cpu或gpu;两种数据访问方式动态(改变数值)或静态(不改变数值);
所以constDtype* cpu_data() const;
Dtype*mutable_cpu_data();换为gpu或diff类似定义
*slover.cpp:结合loss,用gradient更新weights。主要函数Init(),Solve(),ComputeUpdateValue(),Snapshot()快照拷贝,Restore()恢复,Test()
在solver.cpp中有三个solver,三类AdaGradSolver,SGDSolver,NesterovSolver
关于loss,可以同时有多个loss,可以加正则化
protobuffer在.proto文件中定义meaaasge类型,在.prototxt或.binaryproto文件中定义meaage的值
caffe的所有message定义在caffe/src/caffe/proto/caffe.proto
expriment在实验中主要用到两个protobuffer:solver和model的,分别定义solver参数学习率啥的和model结构
命令行接口cmdcaffe是caffe中用来模型训练,计算得分以及方法判断的工具。存放在caffe/build/tools目录下
1.训练caffe train命令
(1)从零开始学习模型
(2)可以从以保存的snapshots继续学习
(3)将已经训练好的模型应用在新的数据或任务上进行微调即fine_tuning学习
所有的训练都要添加-solversolver.prototxt参数完成solver的配置
caffetrain -solver examples/mnist/lenet_solver.prototxt训练lenet
caffetrain -solver examples/mnist/lenet_solver.prototxt -gpu 2在2号gpu上训练
所有继续训练都需要添加-snapshot model_iter_1000.solverstate参数来加载snapshot
caffetrain -solver examples/mnist/lenet_solver.prototxt -snapshotexamples/mnist/lenet_iter_5000.solverstate
微调训练需要添加-weightmodel.caffemodel参数完成模型初始化
caffetrain -solver examples/finetuning_on_flickr_style/solver.prototxt-weightmodel/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel
2.测试caffetest命令:
caffetest命令通过在testphase中运行模型得到分数,并且用这分数表示网络输出的最终结果。
网络结构必须被适当定义,生成accuracy或loss作为结果。测试过程中,终端会显示出每个batch的得分,最后输出全部batch得分的平
均值。
Caffetest -model examples/mnist/lenet_train_test.prototxt -weightexamples/mnist/lenet_iter_10000.caffemodel -gpu 0 -iterrations 100
3.caffetime命令:通过逐层计时与同步,执行模型检测。这是用来检测系统性能于测量模型的相对执行时间
在CPU上10iterations训练了lenet时间
affetime -model example/mnist/lenet_train_test.prototxt -iteration 10
在gpu上默认的50iterations训练lenet时间
caffetime -model examples/mnist/lenet_train_test.prototxt -weightsexamples/mnist/lenet_iter_10000.caffemodel -gpu 0 -iterration 10
4.诊断caffedevice_query命令:对于多gou机器上,在指定的gpu上运行,输出gpu细节信息用来参考于检测设备序列号。
查询第一块gpu
caffedevice_query -gpu 0
5.并行模式:caffe工具的-gpu标识,对于多gpu的模式,允许使用逗号分开不同的gpu的id号。
solver和net在每个gpu上都会被实例化,因此batch_size由于具有多个gpu而成倍的增加,增加的倍数为使用的gpu块数
caffetrain -solver examples/mnnist/lenet_solver.prototxt -gpu 0,1
caffetrain -solver examples/mnnist/lenet_solver.prototxt -gpu all
python接口pycaffe-是caffe的一个模块,脚本在caffe/python。通过importcaffe加载模型,导数参数都可以写入和读取
1.caffe.Net是加载、配置和运行模型的中心接口
2.caffe.Classifier与caffe.Detector为一般任务实现了便捷的接口
3.caffe.SGDSolver表示求解接口
4.caffe.io通过预处理与protocolbuffers,处理输入输出
5.caffe.draw实现数据结构的可视化
6.Caffeblobs通过numpyndarrays实现易用性与有效性