首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >caffe随记(二) --- 数据结构简介

caffe随记(二) --- 数据结构简介

作者头像
TeeyoHuang
发布2017-12-28 14:25:28
7720
发布2017-12-28 14:25:28
举报

caffe随记(二) --- 数据结构简介

注:这篇文章博文我写的内容有点多,建议看一下左上角的目录,对本文结构有个大致了解。

1、Blob

Blob其实从代码的角度看,它是一个模板类。Blob封装了运行时的数据信息(存储、交换和处理网络中正反向传播时的数据和导数信息),并且在CPU和GPU之间具有同步处理的能力。

对于图像处理来说,Blob是一个四维数组,(N, C, H ,W), 其中N表示图片的数量,C表示图片的通道数,H表示图片的高度, W表示图片的宽度。除了图片数据,Blob也可以用于非图片数据。比如传统的多层感知机,就是比较简单的全连接网络,用2D的Blob,调用innerProduct层来计算就可以了。

在模型中设定的参数,也是用Blob来表示和运算。它的维度会根据参数的类型不同而不同。比如:在一个卷积层中,输入一张3通道图片,有96个卷积核,每个核大小为11*11,因此这个Blob是96*3*11*11. 而在一个全连接层中,假设输入1024通道图片,输出1000个数据,则Blob为1000*1024。

Caffe.proto中Blob的描述

// Specifies the shape (dimensions) of a Blob.该结构描述Blob的形状信息
message BlobShape {
  repeated int64 dim = 1 [packed = true]; // 只包含若干int64类型的值,分别表示Blob每个维度的大小。packed表示这些值紧密排布
}

message BlobProto {   //该结构表示Blob载磁盘中序列化后的形态
  optional BlobShape shape = 7;              //可选,包括一个个BlobShape对象
  repeated float data = 5 [packed = true];   //包括若干的(repeated)浮点类型的元素,存储数据,权值;元素数目由shape或者(num,channels,height,width)确定
  repeated float diff = 6 [packed = true];   //包括若干的浮点类型的元素,来存储增量信息(diff),维度与上面的data一致
  repeated double double_data = 8 [packed = true];  //与data并列,只是类型是double
  repeated double double_diff = 9 [packed = true];  //与diff并列,只是类型是double

  // 4D dimensions -- deprecated.  Use "shape" instead. 可选的维度信息,新版本Caffe推荐使用shape来代替
  optional int32 num = 1 [default = 0];
  optional int32 channels = 2 [default = 0];
  optional int32 height = 3 [default = 0];
  optional int32 width = 4 [default = 0];
}

// The BlobProtoVector is simply a way to pass multiple blobproto instances around.存放多个BlobProto实例的对应Index,易于引用 
message BlobProtoVector {
  repeated BlobProto blobs = 1;
}

2、Layer

Layer是caffe模型的本质内容和执行计算的基本单元。至少有一个输入Blob(Bottom Blob)和一个输出Blob(Top Blob),部分Layer带有权值和偏置项。

每一种类型的层都定义了三种关键的计算:setup, forward, backward

●setup: Layer的建立和初始化,以及在整个模型中的连接初始化。

●forward: 从bottom得到输入数据,进行计算,并将计算结果送到top,进行输出。

●backward: 从Layer的输出端top得到数据的梯度,计算当前层的梯度,并将计算结果送到bottom,向前传递。

Ⅰ、Caffe.proto中Layer的描述,

这个才是一切Layer的根本,如果第一次看不明白,可以看完我后面举的各种Layer的例子之后再回头来看一遍

## 后面接的是我的翻译

// NOTE
// Update the next available ID when you add a new LayerParameter field.
//  ##注意,当在LayerParameter中新增字段时,需要为其更新下一个可用ID。
// LayerParameter next available layer-specific ID: 151 (last added: box_annotator_ohem_param) 
// ##LayerParameter中下一个可用的ID是151(最近一次增加的是box_annotator_ohem_param,即下面数字为150的那个)
// ## 层参数{名称,类型,输入底,输出顶,阶段,损失加权系数,全局乘数,}  
message LayerParameter {
  optional string name = 1; // the layer name    ##层的名称
  optional string type = 2; // the layer type    ##层的类型
  repeated string bottom = 3; // the name of each bottom blob ##各个输入Blob的名称
  repeated string top = 4; // the name of each top blob       ##各个输出Blob的名称

  // The train / test phase for computation. ##计算时phase是train还是test
  optional Phase phase = 10;

  // The amount of weight to assign each top blob in the objective.
  // Each layer assigns a default value, usually of either 0 or 1,
  // to each top blob.
  // ##每层输出blob在目标损失函数中的加权系数,每层默认为0或1
  repeated float loss_weight = 5;

  // Specifies training parameters (multipliers on global learning constants,
  // and the name and other settings used for weight sharing).
  //##指定训练参数(全局学习率上的乘数lr_mrlt (即与solver中的base_lr相乘) )  
  repeated ParamSpec param = 6;

  // The blobs containing the numeric parameters of the layer.
  // ##包含每层数值参数的blobs
  repeated BlobProto blobs = 7;

  // Specifies whether to backpropagate to each bottom. If unspecified,
  // Caffe will automatically infer whether each input needs backpropagation
  // to compute parameter gradients. If set to true for some inputs,
  // backpropagation to those inputs is forced; if set false for some inputs,
  // backpropagation to those inputs is skipped.
  //##指定是否需要向底部进行反向传播,如果没有指定Caffe会自动推断每个输入是否需要反向传播来计算参数梯度。
  //##如果对某些输入设置为true,则强制对这些输入的反向传播;
  //##如果某些输入设置为false,则跳过这些输入的反向传播。
  // The size must be either 0 or equal to the number of bottoms.
  // ##这个参数的数量必须为0或者等于bottom blobs的数量
  repeated bool propagate_down = 11;

  // Rules controlling whether and when a layer is included in the network,
  // based on the current NetState.  You may specify a non-zero number of rules
  // to include OR exclude, but not both.  If no include or exclude rules are
  // specified, the layer is always included.  If the current NetState meets
  // ANY (i.e., one or more) of the specified rules, the layer is
  // included/excluded.
  //## Rules控制每层是否被包含在网络中,基于当前的NetState. 
  //##你可使用一个非0数字规则(参考proto中关于message NetStateRule的描述)来指定include或者exclude,但不能同时指定二者。
  //##如果没有指定include或者exclude,这个layer通常默认include。
  //##如果当前NetState满足任何(即一个或多个)指定的规则,则该层被包括/排除。
  repeated NetStateRule include = 8;
  repeated NetStateRule exclude = 9;

  // Parameters for data pre-processing. ##数据预处理的参数
  optional TransformationParameter transform_param = 100;

  // Parameters shared by loss layers.   ##loss layer共享的参数
  optional LossParameter loss_param = 101;

  // Layer type-specific parameters. 
  // ##层类型指定参数
  // Note: certain layers may have more than one computational engine
  // for their implementation. These layers include an Engine type and
  // engine parameter for selecting the implementation.
  // The default for the engine is set by the ENGINE switch at compile-time.
  // ##注意:某些层可能有多个计算引擎用于实现。这些层包括用于选择实现的引擎类型和引擎参数。
  optional AccuracyParameter accuracy_param = 102;
  optional ArgMaxParameter argmax_param = 103;
  optional BatchNormParameter batch_norm_param = 139;
  optional BoxAnnotatorOHEMParameter box_annotator_ohem_param = 150;
  optional BiasParameter bias_param = 141;
  optional ConcatParameter concat_param = 104;
  optional ContrastiveLossParameter contrastive_loss_param = 105;
  optional ConvolutionParameter convolution_param = 106;
  optional CropParameter crop_param = 144;
  optional DataParameter data_param = 107;
  optional DropoutParameter dropout_param = 108;
  optional DummyDataParameter dummy_data_param = 109;
  optional EltwiseParameter eltwise_param = 110;
  optional ELUParameter elu_param = 140;
  optional EmbedParameter embed_param = 137;
  optional ExpParameter exp_param = 111;
  optional FlattenParameter flatten_param = 135;
  optional HDF5DataParameter hdf5_data_param = 112;
  optional HDF5OutputParameter hdf5_output_param = 113;
  optional HingeLossParameter hinge_loss_param = 114;
  optional ImageDataParameter image_data_param = 115;
  optional InfogainLossParameter infogain_loss_param = 116;
  optional InnerProductParameter inner_product_param = 117;
  optional InputParameter input_param = 143;
  optional LogParameter log_param = 134;
  optional LRNParameter lrn_param = 118;
  optional MemoryDataParameter memory_data_param = 119;
  optional MVNParameter mvn_param = 120;
  optional ParameterParameter parameter_param = 145;
  optional PoolingParameter pooling_param = 121;
  optional PowerParameter power_param = 122;
  optional PReLUParameter prelu_param = 131;
  optional PSROIPoolingParameter psroi_pooling_param = 149;
  optional PythonParameter python_param = 130;
  optional RecurrentParameter recurrent_param = 146;
  optional ReductionParameter reduction_param = 136;
  optional ReLUParameter relu_param = 123;
  optional ReshapeParameter reshape_param = 133;
  optional ROIPoolingParameter roi_pooling_param = 147;
  optional ScaleParameter scale_param = 142;
  optional SigmoidParameter sigmoid_param = 124;
  optional SmoothL1LossParameter smooth_l1_loss_param = 148;
  optional SoftmaxParameter softmax_param = 125;
  optional SPPParameter spp_param = 132;
  optional SliceParameter slice_param = 126;
  optional TanHParameter tanh_param = 127;
  optional ThresholdParameter threshold_param = 128;
  optional TileParameter tile_param = 138;
  optional WindowDataParameter window_data_param = 129;
  optional MILDataParameter mil_data_param = 0x004d4944; //"MID"
  optional MILParameter mil_param = 0x004d494c; //"MIL"
}

Ⅱ、一些常用Layer的例子:

①Data Layers

数据层是每个模型的最底层,是模型的入口,不仅提供数据的输入,也提供数据从Blobs转换成别的格式进行保存输出。通常数据的预处理(如减去均值, 放大缩小, 裁剪和镜像等),也在这一层设置参数实现。

数据来源可以来自高效的数据库(如LevelDB和LMDB),也可以直接来自于内存、也可来自磁盘的HDF5文件图片文件

A、数据来源于数据库

示例

layer {

  name: "mnist" # 表示这个layer叫什么名字,无具体限制

  type: "Data"    # 层类型,如果是Data,表示数据来源于LevelDB或LMDB

  top: "data"      #  top表示把数据输出到哪个Blob去

  top: "label"     # 因为这是Data层,所以没有Bottom只有Top

  include {

    phase: TRAIN #表示这个Layer在train阶段有效,还有的是TEST阶段有效

  }

  transform_param {     # 这是图像变换的参数

    scale: 0.00390625   # 实际上就是1/256, 即将输入数据由0-255归一化到0-1之间

    mean_file_size: "examples/cifar10/mean.binaryproto"

                                   # 用一个配置文件来进行均值操作

    mirror: 1                 # 1表示开启镜像,0表示关闭,也可用true和false来表示

    crop_size: 227       # 剪裁一 227*227的图块,训练阶段随机剪裁,测试阶段中间裁剪

  }

 data_param {

    source:"examples/mnist/mnist_train_lmdb" # 数据库文件的路径,必填参数

    batch_size: 64                                   # 网络单次输入数据的数量,必填参数

    backend: LMDB   # 选择使用LevelDB还是LMDB,默认是LevelDB,可选填

  }

}

B、数据来源于内存

示例

layer {

  top: "data"

  top: "label"

  name:"memory_data"

  type: "MemoryData"

 memory_data_param{  # 其特有的参数,每次读取一个大小为batch_size的数据块

# 这4个参数都为必填

    batch_size: 2

    height: 100

    width: 100

    channels: 1

  }

  transform_param {

    scale: 0.0078125

    mean_file:"mean.proto"

    mirror: false

  }

}

C、数据来源于HDF5

示例

layer {

  name: "data"

  type: "HDF5Data"

  top: "data"

  top: "label"

 hdf5_data_param {  # 这里面的两个参数也为必填项

    source:"examples/hdf5_classification/data/train.txt"

    batch_size: 10

  }

}

D、数据来源于图像

layer {

  name: "data"

  type: "ImageData"

  top: "data"

  top: "label"

  transform_param {

    mirror: false

    crop_size: 227

    mean_file:"data/ilsvrc12/imagenet_mean.binaryproto"

  }

image_data_param {

    source:"examples/_temp/file_list.txt"

    # text文件的路径名,此文件的每一行存储一张图片的路径名和对应的标签,必填

    batch_size: 50     #  每一次处理的图片的个数,必填

    new_height: 256  # 根据设置的值,输入的图片将会被调整为给定的高度,选填

    new_width : 256  # 根据设置的值,输入的图片将会被调整为给定的宽度,选填

  }

}

E、数据来源于窗口Windows

layer {

  name: "data"

  type: "WindowData"

  top: "data"

  top: "label"

  include {

    phase: TRAIN

  }

  transform_param {

    mirror: true

    crop_size: 227

    mean_file:"data/ilsvrc12/imagenet_mean.binaryproto"

  }

 window_data_param{

    source:"examples/finetune_pascal_detection/window_file_2007_trainval.txt" #必填

    batch_size: 128  # 必填

    fg_threshold: 0.5

    bg_threshold: 0.5

    fg_fraction: 0.25

    context_pad: 16

    crop_mode:"warp"

  }

}

②Convolution Layers

卷积层,是卷积神经网络(CNN)的核心层。

layer {

  name: "conv1"

  type:"Convolution"

  bottom: "data"

  top: "conv1"

  param {

    lr_mult: 1            # 权值 w的学习率倍数,最终的学习率是这个数乘以solver.prototxt配置文件中的base_lr

    decay_mult:1     # 衰减因子(可选填)

  }

  param {

    lr_mult: 2        # 偏置 b的学习率倍数,一般都设置为权值倍数的2倍

decay_mult:0     # 衰减因子(可选填)

  }

  convolution_param {

    num_output: 20  # 卷积核的数量,必填

pad: 2             # 填充,默认为0

    kernel_size: 5    # 卷积核的高度和宽度,必填

    stride: 1             # 步长

    group : 1            # 指定分组卷积操作的组数,默认为1

    weight_filler{      # 权值初始化参数

      type: "xavier"   #  ”xavier” 算法来进行初始化,也可以设置为”Gaussian”

     }

    bias_filler{              # 偏置初始化参数

      type:"constant"    # 偏置值初始化为常数,默认值为0

      value: 0

     }

  }

}   

③ReLU Layer

layer {

  name: "relu1"

  type: "ReLu"

  bottom: "conv1"

  top: " conv1"      # ReLu层的输入输出一般都是指向同一个Blob

}

④pooling Layers

池化层

layer {

  name: "pool1"

  type: "Pooling"

  bottom: "conv1"

  top: "pool1"

  pooling_param {

    pool: MAX       # 池化方法,有最大池化MAX, 均值池化AVE, 随机池化STOCHASTIC

    kernel_size: 3 # 池化窗口的高度和宽度,必填

    stride: 2          # 步长,默认值为1

  }

InerProduct Layers

全连接层,把输入当作成一个向量,输出也是一个简单向量(把输入数据blobs的width和height全变为1)。

layer {

  name: "fc1"

  type:"InnerProduct"

  bottom: "pool1"

  top: "ip1"

  param {

    lr_mult: 1

    decay_mult:1

  }

  param {

    lr_mult: 2

    decay_mult:0

  }

  inner_product_param {

    num_output: 500  # 全连接层的输出节点或滤波器的个数,必填

    weight_filler {      

type: "gaussian"       #参数初始化方案,必填项,默认为”constant", 值全为0,也用"xavier"算法来进行初始化,也可以设置为”gaussian"   

std: 0.01

    }

    bias_filler {

      type:"constant"

    }

  }

}

全连接层实际上也是一种卷积层,只是它的卷积核大小和原数据大小一致。因此它的参数基本和卷积层的参数一样。

⑥Dropout Layers

这就是AlexNet中提出的防止过拟合的方法dropout

layer {

  name: "drop1"

  type: "Dropout"

  bottom: "fc1"

  top: "fc1"

  dropout_param {

    dropout_ratio: 0.5   # 默认0.5,可选填

  }

}

⑦SoftmaxWithLoss Layers

layer {

  name: "loss"

  type: "SoftmaxWithLoss"

  bottom: "fc1"

  bottom: "label"

  top: "loss"

}

⑧Softmax Layers

layers { 

  name: "prob" 

  type: “Softmax" 

  bottom: " fc1" 

  top: "prob"      #  probability的缩写

}

#这里要注意区分一下 SoftmaxWithLoss和 Softmax的区别

·SoftmaxWithLoss,计算出的是loss值

·Softmax只计算出每个类别的概率似然值

若只是想得到每个类别的概率似然值,则只需使用softmax层即可,就不需调用SoftmaxWithLoss。

⑨Accuracy Layers

输出分类(预测)精确度,只有test阶段才有,因此需要加入include参数

layer {

  name: "accuracy"

  type: "Accuracy"

  bottom: "ip2"

  bottom: "label"

  top: "accuracy"

  include {

phase:TEST  # 必填

  }

}

其实还有其他很多的Layer,但是常用的基本就是上述的这些了,其他各种Layer网上都也有很多的介绍。

这个时候再回头看一下前面贴的caffe.proto中关于Layer的描述,你会发现其实就是在那个框架下选填参数的问题

3、Net

Nets类负责按照网络定义文件将需要的layers和中间blobs进行实例化,并将所有的Layers组合成一个有向无环图。

Nets还提供了在整个网络上进行前向传播与后向传播的接口。

Ⅰ、Caffe.proto中Net的描述

所有Net也是根据这个描述来构造的

message NetParameter {
  optional string name = 1; // consider giving the network a name .#给network一个名字

  // DEPRECATED. See InputParameter. The input blobs to the network.  #已弃用,参考新版中的InputParameter. 本来表示输入network的Blobs
  repeated string input = 3; 

  // DEPRECATED. See InputParameter. The shape of the input blobs.  #已弃用,参考新版中的InputParameter. 本来表示输入Blob的维度信息
  repeated BlobShape input_shape = 8; 

  // 4D input dimensions -- deprecated.  Use "input_shape" instead. # 指定Blobs的4D输入形状 -- 已改为新版:input_shape代替
  // If specified, for each input blob there should be four values specifying the num, channels, height and width of the input blob.
  // #如要使用旧版,对每个输入的blob都需要指定4个参数,Num×Channel×H×W  

  // Thus, there should be a total of (4 * #input) numbers. #因此 input_dim需要重复4次
  repeated int32 input_dim = 4;


  // Whether the network will force every layer to carry out backward operation.
  // If set False, then whether to carry out backward is determined
  // automatically according to the net structure and learning rates.
  //#网络是否强制每个层执行后向传播计算。如果设置为false,那么是否执行后向传播计算由网络结构和学习速率自动确定
  optional bool force_backward = 5 [default = false];

  // The current "state" of the network, including the phase, level, and stage.
  // Some layers may be included/excluded depending on this state and the states
  // specified in the layers' include and exclude fields.
  //#网络的当前状态"state"包括"phase","level","stage"。(还没弄懂level和stage是什么)  
  //#一些layers可能会被包括/排除 根据layers里面具体设置的state信息
  optional NetState state = 6;

  // Print debugging information about results while running Net::Forward,
  // Net::Backward, and Net::Update.
  //#运行Net::Forward, Net::Backward, and Net::Update时是否打印结果信息
  optional bool debug_info = 7 [default = false];

  // The layers that make up the net.  Each of their configurations, including
  // connectivity and behavior, is specified as a LayerParameter.
  //#构成net的layers。每个layer的链接和行为通过LayerParameter配置
  repeated LayerParameter layer = 100;  // ID 100 so layers are printed last.


  // DEPRECATED: use 'layer' instead. # 已弃用,使用layer代替
  repeated V1LayerParameter layers = 2;
}

Ⅱ、Net举例

我以 caffe/examples/mnist/lenet_train_test.prototxt 所定义的Lenet为例子,各位自行感受一下

至此,caffe中的三个层次的数据结构 Blob、Layer、Net就介绍完了,内容有点多,但是值得细看。不足之处还望各位不吝赐教,若有版权问题请评论留言或私信,侵删。

可能各位已经发现caffe.proto这个里面的描述很重要了,后面有空我会专门写一篇博文,但是也推荐各位自行去阅读,想用好caffe必读caffe.proto

4、官方文档

看完上面三部分介绍之后如果各位看官觉得还有闲情逸致,然后不放心我的笔记的话,推荐看一下caffe自带的对于这部分的描述,

对于数据结构的描述,除了我上面说的caffe.proto中对其各种定义之外,caffe中还有个地方也做了叙述

那就是 caffe/docs/tutorial 文件夹

有个 net_layer_blob.md文件,可用vim打开

windows版本的可以用文本文档打开,然后也就是caffe自己自带的说明书,我就不贴出来了,有点长

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-08-03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、Blob
  • 2、Layer
    • Ⅰ、Caffe.proto中Layer的描述,
      • Ⅱ、一些常用Layer的例子:
        • ①Data Layers
        • ②Convolution Layers
        • ③ReLU Layer
        • ④pooling Layers
        • ⑤InerProduct Layers
        • ⑥Dropout Layers
        • ⑦SoftmaxWithLoss Layers
        • ⑧Softmax Layers
        • ⑨Accuracy Layers
    • 3、Net
      • Ⅰ、Caffe.proto中Net的描述:
        • Ⅱ、Net举例
        • 4、官方文档
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档