程序与技术分享:caffe的使用方法

简介: 程序与技术分享:caffe的使用方法

Caffe学习总结(更新中)


主要参考一个大牛的caffe学习系列博客:


这里说明一下:下面的测试分别在我自己的电脑和服务器上进行(服务器速度快),


  1.  关于caffe的简介


  caffe是一个清晰而高效的深度学习框架,纯粹的C++/CUDA架构,支持命令行、Python和MATLAB接口,可以在CPU和GPU直接无缝切换;


  caffe的主要优势:


    (1)CPU与GPU的无缝切换;


    (2)模型与优化都是通过配置文件来设置,无需代码;


  简洁好用不多说。


  2. Caffe环境的搭建,参考另一篇博客:Ubuntu14.04安装caffe。


  3.  Caffe总体框架介绍


  主要参考:深度学习框架Caffe源码解析;


  若想详细了解caffe源码,参考官方教程Tutorial Documentation或者看《caffe官方教程中译本》。


  还有一个博客写的很好,caffe源码解析:


  Caffe主要由Blob,Layer,Net 和 Solver这几个部分组成。


   1)Blob


    主要用来表示网络中的数据,包括训练数据,网络各层自身的参数(包括权值、偏置以及它们的梯度),网络之间传递的数据都是通过 Blob 来实现的,同时 Blob 数据也支持在 CPU 与 GPU 上存储,能够在两者之间做同步。


  2)Layer


    是对神经网络中各种层的一个抽象,包括我们熟知的卷积层和下采样层,还有全连接层和各种激活函数层等等。同时每种 Layer 都实现了前向传播和反向传播,并通过 Blob 来传递数据。


   3) Net


    是对整个网络的表示,由各种 Layer 前后连接组合而成,也是我们所构建的网络模型。


   4) Solver


    定义了针对 Net 网络模型的求解方法,记录网络的训练过程,保存网络模型参数,中断并恢复网络的训练过程。自定义 Solver 能够实现不同的网络求解方式。


完整巧妙不多说。


  4. 总流程(重点)


  完成一个简单的自己的网络模型训练预测,主要包含几个步骤:(以一个实例介绍)


  1) 准备数据;


  例1,学习系列博客上的数据,后面会用到,这里简单说明一下:


    可以从这里下载:


    共有500张图片,分为大巴车、恐龙、大象、鲜花和马五个类,每个类100张。编号分别以3,4,5,6,7开头,各为一类。从其中每类选出20张作为测试,其余80张作为训练。


    因此最终训练图片400张,测试图片100张,共5类。我将图片放在caffe根目录下的  data文件夹下面。即训练图片目录:data/re/train/ ,测试图片目录: data/re/test/。


  2) 数据格式处理,也就是把我们jpg,jpeg,png,tif等格式的图片(可能存在大小不一致的问题),处理转换成caffe中能够运行的db(leveldb/lmdb)文件。


  参考学习系列博客 Caffe学习系列(11):图像数据转换成db(leveldb/lmdb)文件 讲的非常详细。


    convert_imageset.cpp,存放在根目录下的tools文件夹下。编译之后,生成对应的可执行文件放在 buile/tools/ 下面,这个文件的作用就是用于将图片文件转换成caffe框架中能直接使用的db文件。


    该文件的使用格式:


      convert_imageset 【FLAGS】 ROOTFOLDER/ LISTFILE DB_NAME


    四个参数:


      FLAGS: 图片参数组,后面详细介绍;


      ROOTFOLDER/: 图片存放的绝对路径,从linux系统根目录开始;


      LISTFILE: 图片文件列表清单,一般为一个txt文件,一行一张图片;


      DB_NAME: 最终生成的db文件存放目录。


    其中第二个和第四个目录是自己决定的,不多说;


    先说第三个,所谓图片列表清单,也叫标签文件,一般该文件存放图片文件路径,以及该图片的标签(属于哪个类);一般来说,标签文件有两个,一个描述训练集合-train.txt,一个描述测试集合-test.txt,(可能还有描述验证的val.txt),


    例1中测试图片转换后的标签文件格式(test.txt)如下:


  那怎么由图片生成标签文件呢?


    当然图片很少的时候,直接手动输入就好了,但图片很多的情况,就需要用脚本文件来自动生成了。之前对脚本的编写不是很熟,有个快速上手的文章:


    其实非常简单( ̄▽ ̄))


    对于例1,在examples下面创建一个myfile的文件夹,来用存放配置文件和脚本文件。然后编写一个脚本create_filelist.sh,用来生成train.txt和test.txt清单文件。脚本(/examples/myfile/create_filelist.sh)编写如下:


#!/usr/bin/env sh


DATA=data/re/


MY=examples/myfile


echo "Create train.txt..."


rm -rf $MY/train.txt


for i in 3 4 5 6 7


do


find $DATA/train -name $i.jpg | cut -d '/' -f4-5 | sed "s/$/ $i/"$MY/train.txt


done


echo "Create test.txt..."


rm -rf $MY/test.txt


for i in 3 4 5 6 7


do


find $DATA/test -name $i.jpg | cut -d '/' -f4-5 | sed "s/$/ $i/"$MY/test.txt


done


echo "All done"


    生成的.txt文件,就可以作为第三个参数,直接使用了。


  最后了解一下第一个参数:即FLAGS这个参数组,有些什么内容:


    -gray: 是否以灰度图的方式打开图片。程序调用opencv库中的imread()函数来打开图片,默认为false


    -shuffle: 是否随机打乱图片顺序。默认为false


    -backend:需要转换成的db文件格式,可选为leveldb或lmdb,默认为lmdb


    -resize_width/resize_height: 改变图片的大小。在运行中,要求所有图片的尺寸一致,因此需要改变图片大小。 程序调用opencv库的resize()函数来对图片放大缩小,默认为0,不改变


    -check_size: 检查所有的数据是否有相同的尺寸。默认为false,不检查


    -encoded: 是否将原图片编码放入最终的数据中,默认为false


    -encode_type: 与前一个参数对应,将图片编码为哪一个格式:‘png','jpg'......


  继续看例1,于是将训练数据转换成lmdb文件命令如下:


    注:由于图片大小不一,因此这里统一转换成256256大小。


    类似的,将测试数据转换成lmdb文件命令如下:


    当然,由于参数比较多,依然可以写脚本(examples/myfile/create_lmdb.sh):


#!/usr/bin/env sh


MY=examples/myfile


echo "Create train lmdb.."


rm -rf $MY/img_train_lmdb


build/tools/convert_imageset \


--shuffle \


--resize_height=256 \


--resize_width=256 \


/home/xxx/caffe/data/re/ \


$MY/train.txt \


$MY/img_train_lmdb


echo "Create test lmdb.."


rm -rf $MY/img_test_lmdb


build/tools/convert_imageset \


--shuffle \


--resize_width=256 \


--resize_height=256 //代码效果参考:http://hnjlyzjd.com/hw/wz_24213.html

\

/home/xxx/caffe/data/re/ \


$MY/test.txt \


$MY/img_test_lmdb


echo "All Done.."


  这里的xxx是你具体的路径。


    运行成功后,会在 examples/myfile下面生成两个文件夹img_train_lmdb和img_test_lmdb,分别用于保存图片转换后的lmdb文件。


  3) 计算均值并保存


  图片减去均值再训练,会提高训练速度和精度。因此,一般都会有这个操作。


  caffe程序提供了一个计算均值的文件compute_image_mean.cpp,我们直接使用就可以了。


  对于例1,命令如下:


1 sudo build/tools/compute_image_mean examples/myfile/img_train_lmdb examples/myfile/mean.binaryproto


  compute_image_mean带两个参数,第一个参数是lmdb训练数据位置,第二个参数设定均值文件的名字及保存路径。


  运行成功后,会在 examples/myfile/ 下面生成一个mean.binaryproto的均值文件。


  4) 创建模型


  在caffe中是通过.prototxt配置文件来定义网络模型。


  例如,可以打开caffe自带的手写数字库MNIST例子的网络结构文件:


    sudo //代码效果参考:http://hnjlyzjd.com/xl/wz_24211.html

vim examples/mnist/lenet_train_test.prototxt

  这个网络模型是非常有名的LeNet模型,网络结构如下图。


  可以看到各个网络层是如何定义的:


    l 数据层(也叫输入层)


layer {


name: "mnist" //表示层名


type: "Data" //表示层的类型


top: "data"


top: "label"


include {


phase: TRAIN //表示仅在训练阶段起作用


}


transform_param {


scale: 0.00390625 //将图像像素值归一化


}


data_param {


source: "examples/mnist/mnist_train_lmdb" //数据来源


batch_size: 64 //训练时每个迭代的输入样本数量


backend: LMDB //数据类型


}


}


   关于数据层及参数的编写,参看学习系列(2):Caffe学习系列(2):数据层及参数


   简单介绍一下其中参数:


    name: 表示该层的名称,可随意取


    type: 层类型,如果是Data,表示数据来源于LevelDB或LMDB。根据数据的来源不同,数据层的类型也不同(后面会详细阐述)。一般在练习的时候,我们都是采 用的LevelDB或LMDB数据,因此层类型设置为Data。


    top或bottom: 每一层用bottom来输入数据,用top来输出数据。如果只有top没有bottom,则此层只有输出,没有输入。反之亦然。如果有多个 top或多个bottom,表示有多个blobs数据的输入和输出。


    data 与 label: 在数据层中,至少有一个命名为data的top。如果有第二个top,一般命名为label。 这种(data,label)配对是分类模型所必需的。


    include: 一般训练的时候和测试的时候,模型的层是不一样的。该层(layer)是属于训练阶段的层,还是属于测试阶段的层,需要用include来指定。如果没有include参数,则表示该层既在训练模型中,又在测试模型中。


    Transformations: 数据的预处理,可以将数据变换到定义的范围内。如设置scale为0.00390625,实际上就是1/255, 即将输入数据由0-255归一化到0-1之间。


  l 视觉层


  视觉层包括Convolution, Pooling, Local Response Normalization (LRN), im2col等层。


  关于视觉层及参数的编写,参看:Caffe学习系列(3):视觉层(Vision Layers)及参数


  仍然以mnist为例,


  mnist卷积层定义如下:


layer {


name: "conv1"


type: "Convolution"


bottom: "data" //输入是data


top: "conv1" //输出是卷积特征


param {


lr_mult: 1 //权重参数w的学习率倍数


}


param {


lr_mult: 2 //偏置参数b的学习率倍数


}


convolution_param {


num_output: 20


kernel_size: 5


stride: 1


weight_filler { //权重参数w的初始化方案,使用xavier算法


type: "xavier"


}


bias_filler {


type: "constant" //偏置参数b初始化化为常数,一般为0


}


}


}


  简单介绍一下其中参数:


    层类型:Convolution


    lr_mult: 学习率的系数,最终的学习率是这个数乘以solver.prototxt配置文件中的base_lr。如果有两个lr_mult, 则第一个表示权值的学习率,第二个表示偏置项的学习率。一般偏置项的学习率是权值学习率的两倍。


    在后面的convolution_param中,我们可以设定卷积层的特有参数。


    必须设置的参数:


    num_output: 卷积核(filter)的个数


    kernel_size: 卷积核的大小。如果卷积核的长和宽不等,需要用kernel_h和kernel_w分别设定


    其它参数:


     stride: 卷积核的步长,默认为1。也可以用stride_h和stride_w来设置。


     pad: 扩充边缘,默认为0,不扩充。 扩充的时候是左右、上下对称的,比如卷积核的大小为55,那么pad设置为2,则四个边缘都扩充2个像素,即宽度和高度都扩充了4个像素,这样卷积运算之后的特征图就不会变小。也可以通过pad_h和pad_w来分别设定。


     weight_filler: 权值初始化。 默认为“constant",值全为0,很多时候我们用"xavier"算法来进行初始化,也可以设置为”gaussian"


     bias_filler: 偏置项的初始化。一般设置为"constant",值全为0。


     bias_term: 是否开启偏置项,默认为true, 开启


     group: 分组,默认为1组。如果大于1,我们限制卷积的连接操作在一个子集内。如果我们根据图像的通道来分组,那么第i个输出分组只能与第i个输入分组进行连接。


    输入:nc0w0h0


    输出:nc1w1h1


    其中,c1就是参数中的num_output,生成的特征图个数


    w1=(w0+2pad-kernel_size)/stride+1;


    h1=(h0+2pad-kernel_size)/stride+1;


    如果设置stride为1,前后两次卷积部分存在重叠。如果设置pad=(kernel_size-1)/2,则运算后,宽度和高度不变。


  mnist的Pooling层,也叫池化层,为了减少运算量和数据维度而设置的一种层。


  LeNet总共有两个,其中一个定义如下:


layer {


name: "pool1"


type: "Pooling"


bottom: "conv1"


top: "pool1"


pooling_param {


pool: MAX


kernel_size: 2


stride: 2


}


}


  层类型:Pooling


  必须设置的参数:


   kernel_size: 池化的核大小。也可以用kernel_h和kernel_w分别设定。


  其它参数:


   pool: 池化方法,默认为MAX。目前可用的方法有MAX, AVE, 或STOCHASTIC


    pad: 和卷积层的pad的一样,进行边缘扩充。默认为0


    stride: 池化的步长,默认为1。一般我们设置为2,即不重叠。也可以用stride_h和stride_w来设置。


  还有Local Response Normalization (LRN)层和im2col层等,在LeNet中没有定义,可以参看AlexNet或GoogLenet等更复杂的模型。


  l 激活层


  关于激活层及参数的编写,参看Caffe学习系列(4):激活层(Activiation Layers)及参数


  在LeNet中,用到的激活函数是ReLU / Rectified-Linear and Leaky-ReLU,


  ReLU是目前使用最多的激活函数,主要因为其收敛更快,并且能保持同样效果。标准的ReLU函数为max(x, 0),当x>0时,输出x; 当x<=0时,输出0。


    f(x)=max(x,0)。


  定义如下:


layer {


name: "relu1"


type: "ReLU"


bottom: "ip1"


top: "ip1"


}


  层类型:ReLU


  可选参数:


    negative_slope:默认为0. 对标准的ReLU函数进行变化,如果设置了这个值,那么数据为负数时,就不再设置为0,而是用原始数据乘以negative_slope。


  RELU层支持in-place计算,这意味着bottom的输出和输入相同以避免内存的消耗。


  l 其他层


  包括:softmax_loss层,Inner Product层,accuracy层,reshape层和dropout层等,参看Caffe学习系列(5):其它常用层及参数,不多说。


  l 关于模型编写的一个总结:


  Caffe学习系列(6):Blob,Layer and Net以及对应配置文件的编写


  一个完整网络例子:


  第一层:name为mnist, type为Data,没有输入(bottom),只有两个输出(top),一个为data,一个为label


  第二层:name为ip,type为InnerProduct, 输入数据data, 输出数据ip


  第三层:name为loss, type为SoftmaxWithLoss,有两个输入,一个为ip,一个为label,有一个输出loss,没有画出来。


  对应的配置文件prototxt就可以这样写:


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"


}


  5) 编写配置文件


   主要参看Caffe学习系列(7):solver及其配置 和Caffe学习系列(8):solver优化方法


   先看一下mnist中配置文件(一般是..solver.prototxt文件):


1 sudo vim examples/mnist/lenet_solver.prototxt


   配置文件如下:


sudo vim examples/mnist/lenet_solver.prototxt


配置文件如下:


# The train/test net protocol buffer definition


net: "examples/mnist/lenet_train_test.prototxt" //设置深度网络模型,就是介绍的模型。


# test_iter specifies how many forward passes the test should carry out.


# In the case of MNIST, we have test batch size 100 and 100 test iterations,


# covering the full 10,000 testing images.


test_iter: 100 //这个要与test layer中的batch_size结合起来理解。mnist数据中测试样本总数为10000,一次性执行全部数据效率很低,因此我们将测试数据分成几个批次来执行,每个批次的数量就是batch_size。假设我们设置batch_size为100,则需要迭代100次才能将10000个数据全部执行完。因此test_iter设置为100。执行完一次全部数据,称之为一个epoch


# Carry out testing every 500 training iterations.


test_interval: 500 // 测试间隔。也就是每训练500次,才进行一次测试。


# The base learning rate, momentum and the weight decay of the network.


base_lr: 0.01


momentum: 0.9 //上一次梯度更新的权重


weight_decay: 0.0005 <span style="color: rgba(0, 128, 0,

相关文章
|
8月前
|
开发框架 移动开发 小程序
强烈推荐:绝对是好用的小程序开源框架
强烈推荐:绝对是好用的小程序开源框架
140 0
|
机器学习/深度学习 JavaScript 数据挖掘
DL框架之MXNet :深度学习框架之MXNet 的简介、安装、使用方法、应用案例之详细攻略
MXNet 是亚马逊(Amazon)选择的深度学习库,并且也许是最优秀的库之一。它拥有类似于 Theano 和 TensorFlow 的数据流图,为多 GPU 配置提供了良好的配置,有着类似于 Lasagne 和 Blocks 更高级别的模型构建块,并且可以在你可以想象的任何硬件上运行(包括手机)。对 Python 的支持只是其冰山一角—MXNet 同样提供了对 R、Julia、C++、Scala、Matlab,和 Javascript 的接口。
DL框架之MXNet :深度学习框架之MXNet 的简介、安装、使用方法、应用案例之详细攻略
|
2月前
|
机器学习/深度学习 存储 PyTorch
还没了解MIGraphX推理框架?试试这篇让你快速入门
MIGraphX是一款用于DCU上的深度学习推理引擎,它的目的是为了简化和优化端到端的模型部署流程,包括模型优化、代码生成和推理。MIGraphX能够处理多种来源的模型,如TensorFlow和Pytorch,并提供用户友好的编程界面和工具,使得用户可以集中精力在业务推理开发上,而不需要深入了解底层硬件细节。
125 0
|
8月前
|
并行计算 PyTorch 算法框架/工具
关于在安装caffe2环境中遇到的坑整理(欢迎入坑讨论)
关于在安装caffe2环境中遇到的坑整理(欢迎入坑讨论)
|
存储 并行计算 API
【CUDA学习笔记】第九篇:基本计算机视觉操作【上】(附实践源码下载)(一)
【CUDA学习笔记】第九篇:基本计算机视觉操作【上】(附实践源码下载)(一)
93 0
|
存储 并行计算 计算机视觉
【CUDA学习笔记】第九篇:基本计算机视觉操作【上】(附实践源码下载)(二)
【CUDA学习笔记】第九篇:基本计算机视觉操作【上】(附实践源码下载)(二)
95 0
|
TensorFlow 算法框架/工具 iOS开发
《从零到一:IOS平台TensorFlow入门及应用详解(附源码)》电子版地址
从零到一:IOS平台TensorFlow入门及应用详解(附源码)
101 0
《从零到一:IOS平台TensorFlow入门及应用详解(附源码)》电子版地址
|
PyTorch 算法框架/工具
pytorch使用方法积累
1. net.parameters()查看网络参数 2. torch.optim.lr_scheduler.MultiStepLR 2.1 学习率的参数配置
80 0
|
机器学习/深度学习 TensorFlow 算法框架/工具
DL框架之MXNet :深度学习框架之MXNet 的简介、安装、使用方法、应用案例之详细攻略(二)
DL框架之MXNet :深度学习框架之MXNet 的简介、安装、使用方法、应用案例之详细攻略
DL框架之MXNet :深度学习框架之MXNet 的简介、安装、使用方法、应用案例之详细攻略(二)
|
机器学习/深度学习 API Python
DL框架之MXNet :深度学习框架之MXNet 的简介、安装、使用方法、应用案例之详细攻略(三)
DL框架之MXNet :深度学习框架之MXNet 的简介、安装、使用方法、应用案例之详细攻略
DL框架之MXNet :深度学习框架之MXNet 的简介、安装、使用方法、应用案例之详细攻略(三)