Caffe学习日记2

    xiaoxiao2026-05-06  3

    为了学习Caffe的源码,自己使用的开发环境是Ubuntu Desktop 14.04 LTS和Nsight Eclipse Edition,然后将Caffe源代码导入Nsight Eclipse Edition,最后Build Project即可。[1][3][4][5]

    1. caffe.proto

    Google Protocol Buffer在.proto文件中定义message类型,而在.prototxt或.binaryproto文件中定义message的值。Caffe的所有message定义在$CAFFE/src/caffe/proto/caffe.proto中。caffe.proto中定义了很多结构化数据,以BlobProto为例,如下所示:

    message BlobProto { optional BlobShape shape = 7; repeated float data = 5 [packed = true]; repeated float diff = 6 [packed = true]; repeated double double_data = 8 [packed = true]; repeated double double_diff = 9 [packed = true]; // 4D dimensions -- deprecated. Use "shape" instead. optional int32 num = 1 [default = 0]; optional int32 channels = 2 [default = 0]; optional int32 height = 3 [default = 0]; optional int32 width = 4 [default = 0]; }

    解析:

    (1)required:初始值必须提供。

    (2)optional:如果未被初始化,那么一个默认值将赋予该字段。

    (3)repeated:该字段可以重复多个。

    (4)由于一些历史原因,基本数值类型的repeated的字段并没有被尽可能地高效编码。在新的代码中,用户应该使用特殊选项[packed=true]来保证更高效的编码。

    说明:在caffe/src/caffe/proto文件夹下,通过编译caffe.proto生成.pb.cc和.pb.h文件,并且caffe.proto文件中的每一个消息都有一个对应的类。[编译命令:protoc --proto_path=caffe/src/caffe/proto --cpp_out=caffe/src/caffe/protocaffe/src/caffe/proto/caffe.proto]

     

    2. Blob,Layer,Net,Solver [17]

    (1)Blob:基础的数据结构,用来保存学习到的参数以及网络传输过程中产生数据的类。

    解析:

    在更高一级的Layer中,Blob表示学习到的参数的形式,如下所示:

    vector<shared_ptr<Blob<Dtype>>> blobs_;

    使用Blob容器,因为某些Layer包含多组学习参数(比如,多个卷积核的卷积层),以及Layer所传递的数据形式。如下所示:

    vector<Blob<Dtype>*> &bottom; vector<Blob<Dtype>*> *top 说明:Blob是Caffe中数据操作基本单位,我们可以把它理解为N维数组,Blob可以表示为(N*C*H*W)这样一个4D数组。其中,N表示图片的数量,C表示图片的通道数,H和W分别表示图片的高度和宽度。

    (2)Layer:网络的基本单元,由此派生出了各种层类。修改这部分代码的人主要是研究特征表达方向的。

    Caffe中主要分为5大类Layer,如下所示:

    1)NeuronLayer类

    解析:

    定义于neuron_layers.hpp中,其派生类主要是元素级别的运算(比如Dropout运算,激活函数ReLu,Sigmoid等),运算均为同址计算(in-place computation,返回值覆盖原值而占用新的内存)。比如ReLULayer,TanHLayer和SigmoidLayer等。

    2)LossLayer类

    解析:定义于loss_layers.hpp中,其派生类会产生loss,只有这些层能够产生loss。比如EuclideanLossLayer,SoftmaxWithLossLayer和HingeLossLayer等。

    3)数据层

    解析:定义于data_layer.hpp中,作为网络的最底层,主要实现数据格式的转换。比如DataLayer,HDF5DataLayer和ImageDataLayer等。

    4)视觉层

    解析:定义于vision_layers.hpp,实现特征表达功能,更具体地说包含卷积操作,Pooling操作,它们基本都会产生新的内存占用(Pooling相对较小)。比如ConvolutionLayer,PoolingLayer和LRNLayer等。

    5)网络连接层和激活函数

    解析:定义于common_layers.hpp,Caffe提供了单个层与多个层的连接,并在这个头文件中声明。比如ConcatLayer,InnerProductLayer和SoftmaxLayer等。

    特别说明:

    在新版的Caffe中没有找到vision_layers.hppcommon_layers.hpp头文件。Layer类派生出来的层类通过实现Forward和Backward(CPU和部分GPU)这两个虚函数,产生了各式各样功能的层类。Forward是根据

    bottom计算top的过程,而Backward是根据top计算bottom的过程。

    (3)Net:网络的搭建,将Layer所派生出的层类组合成网络。

    解析:Net用容器的形式将多个Layer有序地放在一起,其自身实现的功能主要是对逐层Layer进行初始化,以及提供Update()的接口(更新网络参数),本身不能对参数进行有效地学习过程。

    (4)Solver:Net的求解,修改这部分代码人主要是研究DL求解方向的。

    解析:Solver类中包含一个Net的指针,主要是实现了训练模型参数所采用的优化算法,根据优化算法的不同会派生不同的类,而基于这些子类就可以对网络进行正常的训练过程。

    3. 在MNIST数据集上用Caffe训练LeNet模型配置文件详解 [22][28]

    层的定义均在$CAFFE_ROOT/examples/mnist/lenet_train_test.prototxt中。

    (1)Data Layer

    解析:

    layer { name: "mnist" type: "Data" transform_param { # 转换参数 scale: 0.00390625 # 把输入像素灰度归一到[0, 1),即1/256=0.00390625 } data_param { # 数据参数 source: "mnist_train_lmdb" # 从mnist_train_lmdb中读入数据 backend: LMDB # 文件格式 batch_size: 64 # 批次大小为64,即一次处理64条数据 } top: "data" # 这层后面连接data和label的Blob空间 top: "label" }

    说明:

    如果在Data Layer中有include { phase: TRAIN },那么表示该层属于训练阶段的层,因为通常训练和测试阶段,模式的层是不一样的。如果没有include参数,那么表示训练和测试阶段模型的层是一样的。Caffe的数据来源可以是高效的数据库(LevelDB、LMDB),内存(MemoryData),HDF5文件(HDF5Data)和图片格式文件(ImageData)等。

    (2)Convolution Layer

    layer { name: "conv1" type: "Convolution" param { lr_mult: 1 } # 权重学习率和运行时求解器学习率一样,并且是偏置学习率的2倍 param { lr_mult: 2 } convolution_param { # 卷积参数 num_output: 20 # 输出单元数20 kernel_size: 5 # 卷积核的大小为5*5 stride: 1 # 步长为1 weight_filler { # 使用xavier算法自动确定基于输入和输出神经元数量的初始规模 type: "xavier" } bias_filler { # 偏置值初始化为常量,默认为0 type: "constant" } } bottom: "data" # 前面使用data,后面生成conv1的Blob空间 top: "conv1" } (3)Pooling Layer layer { name: "pool1" type: "Pooling" pooling_param { kernel_size: 2 # 卷积核的大小为2*2 stride: 2 # 步长为2 pool: MAX # 池化的方式为最大池化 } bottom: "conv1" # 前面使用conv1,后面生成pool1的Blob空间 top: "pool1" } (4)Fully Connected Layer layer { name: "ip1" type: "InnerProduct" param { lr_mult: 1 } param { lr_mult: 2 } inner_product_param { # 全连接层参数 num_output: 500 # 输出500个节点 weight_filler { type: "xavier" # 使用xavier算法自动确定基于输入和输出神经元数量的初始规模 } bias_filler { type: "constant" # 偏置值初始化为常量,默认为0 } } bottom: "pool2" # 前面使用pool2,后面生成ip1的Blob空间 top: "ip1" }

    (5)ReLU(Rectified Linear Units) Layer

    ayer { name: "relu1" type: "ReLU" bottom: "ip1" # 输入数据 top: "ip1" # 输出数据 } 说明:

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

    (6)Loss Layer

    layer { name: "loss" type: "SoftmaxWithLoss" # 该softmax_loss层同时实现了SOFTMAX和多项Logistic损失 bottom: "ip2" bottom: "label" } 说明:除上述层外,还有softmax层,softmax_loss层,Inner Product层,accuracy层(测试阶段),reshape层和dropout层(防止过拟合)。

    (7)Solver配置文件

    求解器的定义均在$CAFFE_ROOT/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 # 如果batch_size=100,并且100次测试迭代,那么覆盖100*100张测试图片 # 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 # 权重衰减 # The learning rate policy # 学习策略,有固定学习率(cifar10)和每步递减学习率(imagenet) lr_policy: "inv" gamma: 0.0001 power: 0.75 # Display every 100 iterations display: 100 # 每迭代100次显示一次 # The maximum number of iterations max_iter: 10000 # 最大迭代次数10000次 # snapshot intermediate results snapshot: 5000 # 每5000次迭代存储一次快照到电脑 snapshot_prefix: "examples/mnist/lenet" # 快照的位置和名字为examples/mnist/lenet # solver mode: CPU or GPU solver_mode: GPU # 选择是用CPU训练还是用GPU训练 说明:

    在深度网络中,loss function往往是非凸的,没有解析解。我们需要通过优化算法来求解,而Slover就是配置优化算法,它的主要作用就是交替调用前向(forward)算法和后向(backward)算法来更新参数,从而最小化loss。Caffe提供了6种优化算法,包括Stochastic Gradient Descent (type: "SGD");AdaDelta (type: "AdaDelta");Adaptive Gradient (type: "AdaGrad");Adam (type: "Adam");Nesterov’s Accelerated Gradient (type: "Nesterov");RMSprop (type: "RMSProp")。[29]

    参考文献:

    [1] Build and Debug Caffe in Eclipse Nsight:http://www.pittnuts.com/2015/06/build-and-debug-caffe-in-nsight/

    [2] Caffe使用笔记:https://www.douban.com/note/536308279/?type=like

    [3] (Caffe,LeNet)Eclipse单步调试:http://blog.csdn.net/mounty_fsc/article/details/51089864

    [4] Eclipse调试的Python接口(动态链接库_caffe.so):http://blog.csdn.net/mounty_fsc/article/details/51092967

    [5] Caffe调试Ubuntu 14.04+Eclipse:http://blog.csdn.net/yaoxingfu72/article/details/47999795

    [6] Caffe深度学习薛开宇笔记实例:http://wenku.baidu.com/view/9cb585cc02020740bf1e9b60.html

    [7] 基于卷积神经网络的深度学习算法与应用研究:http://wenku.baidu.com/view/88e56336aef8941ea66e05b7.html

    [8] 神经网络与深度学习讲义:http://wenku.baidu.com/view/1ba45d78aa00b52acec7ca2e.html

    [9] Caffe Tutorial:http://wenku.baidu.com/view/5459b198de80d4d8d15a4fa6.html

    [10] Caffe源码简单解析:http://blog.163.com/yuyang_tech/blog/static/2160500832015713105052452/

    [11] Caffe源代码解析:http://download.csdn.net/detail/u013403054/8888099

    [12] Caffe源码解析:http://wenku.baidu.com/link?url=4tEdbpTXsHDOx4w4S30MbLYcJaqKR81OaqGCSvhF_ty0NWDgAlSeC_ThYxtOGaabx5gtzPHROEWcUsEfBVDeoVdZZNW3DB79dAX_2M7-0LC

    [13] Caffe的配置过程:http://blog.csdn.net/brightming/article/details/51106629

    [14] Nsight Eclipse Edition Getting Started Guide:http://docs.nvidia.com/cuda/nsight-eclipse-edition-getting-started-guide/index.html#abstract

    [15] Caffe环境搭建:http://blog.csdn.net/hjimce/article/details/48781693

    [16] Protobuf语言指南:http://www.cnblogs.com/dkblog/archive/2012/03/27/2419010.html

    [17] 深度学习Caffe的代码怎么读?:http://www.zhihu.com/question/27982282/answer/39350629

    [18] Deep Learning:https://yufeigan.github.io/

    [19] 梳理Caffe代码Layer:http://blog.csdn.net/langb2014/article/details/50988275

    [20] Neural Networks and Deep Learning:http://neuralnetworksanddeeplearning.com/index.html

    [21] Developing new layers:https://github.com/BVLC/caffe/wiki/Development

    [22] Training LeNet on MNIST with Caffe:http://caffe.berkeleyvision.org/gathered/examples/mnist.html

    [23] NVIDIA CUDA初级教程视频:http://www.iqiyi.com/a_19rrhbvoe9.html

    [24] Making a Caffe Layer:http://chrischoy.github.io/research/making-caffe-layer/

    [25] Hacker's guide to Neural Networks:http://karpathy.github.io/neuralnets/

    [26] 一亩半分地:http://blog.csdn.net/xizero00?viewmode=contents

    [27] 深度学习源码解读:https://zhuanlan.zhihu.com/p/20377462

    [28] MNIST在Caffe上进行训练与学习:http://wenku.baidu.com/link?url=dyzXfLx7aqsjv1XkfcmpMyC8XLZKgtIzDLjwDyeFUMpZF7Dk8Xj9mzWeC2956JHAQD6TBganUoP0C8Gqc_xW4X0Ih_fJfiGU5AvofQdn1B_

    [29] Caffe学习系列(7):solver及其配置:http://www.cnblogs.com/denny402/p/5074049.html

    转载请注明原文地址: https://ju.6miu.com/read-1309409.html
    最新回复(0)