zoukankan      html  css  js  c++  java
  • 【caffe Layer】代码中文注释

    src/caffe/proto/caffe.proto 中LayerParameter部分

      1 // NOTE
      2 // Update the next available ID when you add a new LayerParameter field.
      3 // 如果增加一个新的LayerParameter域,需要更新下一个可用的ID
      4 // LayerParameter next available layer-specific ID: 147 (last added: recurrent_param)
      5 message LayerParameter {
      6   optional string name = 1; // the layer name 名称
      7   optional string type = 2; // the layer type 类型
      8   repeated string bottom = 3; // the name of each bottom blob 输入的Bottom Blob的名称
      9   repeated string top = 4; // the name of each top blob 输出的Top Blob名称
     10 
     11   // The train / test phase for computation.当前阶段TRAIN或TEST
     12   optional Phase phase = 10;
     13 
     14   // The amount of weight to assign each top blob in the objective.
     15   // Each layer assigns a default value, usually of either 0 or 1,
     16   // to each top blob.
     17   // 为每个输出Top Blob分配对损失函数的权重,每个Layer都有默认值,0表示不参与计算,1表示参与损失函数计算
     18   repeated float loss_weight = 5;
     19 
     20   // Specifies training parameters (multipliers on global learning constants,
     21   // and the name and other settings used for weight sharing).
     22   // 指定训练参数(例如相对全局学习常熟的缩放因子,以及用于权值共享的名称或其他设置)
     23   repeated ParamSpec param = 6;
     24 
     25   // The blobs containing the numeric parameters of the layer.
     26   // 承载该曾数值参数的Blob
     27   repeated BlobProto blobs = 7;
     28 
     29   // Specifies whether to backpropagate to each bottom. If unspecified,
     30   // Caffe will automatically infer whether each input needs backpropagation
     31   // to compute parameter gradients. If set to true for some inputs,
     32   // backpropagation to those inputs is forced; if set false for some inputs,
     33   // backpropagation to those inputs is skipped.
     34   // 是否对Bottom Blob进行反向传播过程。该字段维度应与Bottom Blob个数一致。
     35   // The size must be either 0 or equal to the number of bottoms.
     36   repeated bool propagate_down = 11;
     37 
     38   // Rules controlling whether and when a layer is included in the network,
     39   // based on the current NetState.  You may specify a non-zero number of rules
     40   // to include OR exclude, but not both.  If no include or exclude rules are
     41   // specified, the layer is always included.  If the current NetState meets
     42   // ANY (i.e., one or more) of the specified rules, the layer is
     43   // included/excluded.
     44   // 控制某个层在某个时刻是否包含在网络中(基于当前的NetState)
     45   // 可以为include或exclude指定非零值(不能同时)
     46   // 如果没有规则,该层一直包含在网络中
     47   // 如果当前的NetState满足一定条件,那么该层被包含或被排斥
     48   repeated NetStateRule include = 8;
     49   repeated NetStateRule exclude = 9;
     50 
     51   // Parameters for data pre-processing. 数据预处理参数
     52   optional TransformationParameter transform_param = 100;
     53 
     54   // Parameters shared by loss layers. 所有损失层共享的参数
     55   optional LossParameter loss_param = 101;
     56 
     57   // Layer type-specific parameters.特定类型层参数
     58   // 注意:一些层实现时可能有多于一种计算引擎,这些层通过选择引擎类型和引擎参数来实现。
     59   // 默认引擎是在编译阶段由引擎开关设置的
     60   // Note: certain layers may have more than one computational engine
     61   // for their implementation. These layers include an Engine type and
     62   // engine parameter for selecting the implementation.
     63   // The default for the engine is set by the ENGINE switch at compile-time.
     64   optional AccuracyParameter accuracy_param = 102;
     65   optional ArgMaxParameter argmax_param = 103;
     66   optional BatchNormParameter batch_norm_param = 139;
     67   optional BiasParameter bias_param = 141;
     68   optional ConcatParameter concat_param = 104;
     69   optional ContrastiveLossParameter contrastive_loss_param = 105;
     70   optional ConvolutionParameter convolution_param = 106;
     71   optional CropParameter crop_param = 144;
     72   optional DataParameter data_param = 107;
     73   optional DropoutParameter dropout_param = 108;
     74   optional DummyDataParameter dummy_data_param = 109;
     75   optional EltwiseParameter eltwise_param = 110;
     76   optional ELUParameter elu_param = 140;
     77   optional EmbedParameter embed_param = 137;
     78   optional ExpParameter exp_param = 111;
     79   optional FlattenParameter flatten_param = 135;
     80   optional HDF5DataParameter hdf5_data_param = 112;
     81   optional HDF5OutputParameter hdf5_output_param = 113;
     82   optional HingeLossParameter hinge_loss_param = 114;
     83   optional ImageDataParameter image_data_param = 115;
     84   optional InfogainLossParameter infogain_loss_param = 116;
     85   optional InnerProductParameter inner_product_param = 117;
     86   optional InputParameter input_param = 143;
     87   optional LogParameter log_param = 134;
     88   optional LRNParameter lrn_param = 118;
     89   optional MemoryDataParameter memory_data_param = 119;
     90   optional MVNParameter mvn_param = 120;
     91   optional ParameterParameter parameter_param = 145;
     92   optional PoolingParameter pooling_param = 121;
     93   optional PowerParameter power_param = 122;
     94   optional PReLUParameter prelu_param = 131;
     95   optional PythonParameter python_param = 130;
     96   optional RecurrentParameter recurrent_param = 146;
     97   optional ReductionParameter reduction_param = 136;
     98   optional ReLUParameter relu_param = 123;
     99   optional ReshapeParameter reshape_param = 133;
    100   optional ScaleParameter scale_param = 142;
    101   optional SigmoidParameter sigmoid_param = 124;
    102   optional SoftmaxParameter softmax_param = 125;
    103   optional SPPParameter spp_param = 132;
    104   optional SliceParameter slice_param = 126;
    105   optional TanHParameter tanh_param = 127;
    106   optional ThresholdParameter threshold_param = 128;
    107   optional TileParameter tile_param = 138;
    108   optional WindowDataParameter window_data_param = 129;
    109 }

     include/caffe/layer.hpp

      1 #ifndef CAFFE_LAYER_H_
      2 #define CAFFE_LAYER_H_
      3 
      4 #include <algorithm>
      5 #include <string>
      6 #include <vector>
      7 
      8 #include "caffe/blob.hpp"
      9 #include "caffe/common.hpp"
     10 #include "caffe/layer_factory.hpp"
     11 #include "caffe/proto/caffe.pb.h"
     12 #include "caffe/util/math_functions.hpp"
     13 
     14 /**
     15  Forward declare boost::thread instead of including boost/thread.hpp
     16  to avoid a boost/NVCC issues (#1009, #1010) on OSX.
     17  */
     18 namespace boost { class mutex; }
     19 
     20 namespace caffe {
     21 
     22 /**
     23  * @brief An interface for the units of computation which can be composed into a
     24  *        Net.
     25  *
     26  * Layer%s must implement a Forward function, in which they take their input
     27  * (bottom) Blob%s (if any) and compute their output Blob%s (if any).
     28  * They may also implement a Backward function, in which they compute the error
     29  * gradients with respect to their input Blob%s, given the error gradients with
     30  * their output Blob%s.
     31  */
     32 template <typename Dtype>
     33 class Layer {
     34  public:
     35   /**
     36    * You should not implement your own constructor. Any set up code should go
     37    * to SetUp(), where the dimensions of the bottom blobs are provided to the
     38    * layer.
     39    */
     40    // 显式构造函数,从LayerParameter中加载配置
     41   explicit Layer(const LayerParameter& param)
     42     : layer_param_(param) {
     43       // Set phase and copy blobs (if there are any).
     44       phase_ = param.phase();//设置当前阶段(训练或预测)
     45       if (layer_param_.blobs_size() > 0) {
     46         blobs_.resize(layer_param_.blobs_size());
     47         //按照layer_param_设置本身Blob对象个数,并依次把每个Blob对象尺寸调整为与layer_param_中Blob尺寸一致
     48         for (int i = 0; i < layer_param_.blobs_size(); ++i) {
     49           blobs_[i].reset(new Blob<Dtype>());
     50           blobs_[i]->FromProto(layer_param_.blobs(i));
     51         }
     52       }
     53     }
     54   virtual ~Layer() {}
     55 
     56   /**
     57    * @brief Implements common layer setup functionality.
     58    *
     59    * @param bottom the preshaped input blobs
     60    * @param top
     61    *     the allocated but unshaped output blobs, to be shaped by Reshape
     62    *
     63    * Checks that the number of bottom and top blobs is correct.
     64    * Calls LayerSetUp to do special layer setup for individual layer types,
     65    * followed by Reshape to set up sizes of top blobs and internal buffers.
     66    * Sets up the loss weight multiplier blobs for any non-zero loss weights.
     67    * This method may not be overridden.
     68    */
     69    //配置函数,实现常用层配置借口,不可被覆盖
     70   void SetUp(const vector<Blob<Dtype>*>& bottom,
     71       const vector<Blob<Dtype>*>& top) {
     72     CheckBlobCounts(bottom, top);//检查blob
     73     LayerSetUp(bottom, top);     //与层类型相关的配置过程
     74     Reshape(bottom, top);        //对TopBlob进行变形
     75     SetLossWeights(top);         //设置损失权值因子Blob
     76   }
     77 
     78   /**
     79    * @brief Does layer-specific setup: your layer should implement this function
     80    *        as well as Reshape.
     81    *
     82    * @param bottom
     83    *     the preshaped input blobs, whose data fields store the input data for
     84    *     this layer
     85    * @param top
     86    *     the allocated but unshaped output blobs
     87    *
     88    * This method should do one-time layer specific setup. This includes reading
     89    * and processing relevent parameters from the <code>layer_param_</code>.
     90    * Setting up the shapes of top blobs and internal buffers should be done in
     91    * <code>Reshape</code>, which will be called before the forward pass to
     92    * adjust the top blob sizes.
     93    */
     94    //层配置虚函数,做特定类型层相关配置,由该类型层自己实现
     95   virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
     96       const vector<Blob<Dtype>*>& top) {}
     97 
     98   /**
     99    * @brief Adjust the shapes of top blobs and internal buffers to accommodate
    100    *        the shapes of the bottom blobs.
    101    *
    102    * @param bottom the input blobs, with the requested input shapes
    103    * @param top the top blobs, which should be reshaped as needed
    104    *
    105    * This method should reshape top blobs as needed according to the shapes
    106    * of the bottom (input) blobs, as well as reshaping any internal buffers
    107    * and making any other necessary adjustments so that the layer can
    108    * accommodate the bottom blobs.
    109    */
    110    //纯虚函数。变形函数,修改Top Blob以及内部Blob缓冲区形状
    111   virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
    112       const vector<Blob<Dtype>*>& top) = 0;
    113 
    114   /**
    115    * @brief Given the bottom blobs, compute the top blobs and the loss.
    116    *
    117    * @param bottom
    118    *     the input blobs, whose data fields store the input data for this layer
    119    * @param top
    120    *     the preshaped output blobs, whose data fields will store this layers'
    121    *     outputs
    122    * 
    eturn The total loss from the layer.
    123    *
    124    * The Forward wrapper calls the relevant device wrapper function
    125    * (Forward_cpu or Forward_gpu) to compute the top blob values given the
    126    * bottom blobs.  If the layer has any non-zero loss_weights, the wrapper
    127    * then computes and returns the loss.
    128    *
    129    * Your layer should implement Forward_cpu and (optionally) Forward_gpu.
    130    */
    131    // 前向传播函数
    132    // 给定Bottom Blob,计算TopBlob和loss,返回值为当前层的loss
    133    // 该函数会调用相应设备包装函数,如Forward_cpu or Forward_gpu来实现真正计算过程
    134    // 如果该层有非零loss权重参数,包装函数会计算并返回loss
    135    // 派生类应该实现Forward_cpu,Forward_gpu(可选)
    136   inline Dtype Forward(const vector<Blob<Dtype>*>& bottom,
    137       const vector<Blob<Dtype>*>& top);
    138 
    139   /**
    140    * @brief Given the top blob error gradients, compute the bottom blob error
    141    *        gradients.
    142    *
    143    * @param top
    144    *     the output blobs, whose diff fields store the gradient of the error
    145    *     with respect to themselves
    146    * @param propagate_down
    147    *     a vector with equal length to bottom, with each index indicating
    148    *     whether to propagate the error gradients down to the bottom blob at
    149    *     the corresponding index
    150    * @param bottom
    151    *     the input blobs, whose diff fields will store the gradient of the error
    152    *     with respect to themselves after Backward is run
    153    *
    154    * The Backward wrapper calls the relevant device wrapper function
    155    * (Backward_cpu or Backward_gpu) to compute the bottom blob diffs given the
    156    * top blob diffs.
    157    *
    158    * Your layer should implement Backward_cpu and (optionally) Backward_gpu.
    159    */
    160    //反向传播函数
    161    //给定输出的Top Blob误差梯度,计算输入的Bottom Blob的误差梯度
    162    //propagate_down为多路开关,与Bottom Blob矢量维度相同,每个值表示是否将误差梯度传递到对应的Bottom Blob
    163    //该函数会调用相应设备包装函数,如Backward_cpu and (可选) Backward_gpu实现计算过程,由派生类负责实现
    164   inline void Backward(const vector<Blob<Dtype>*>& top,
    165       const vector<bool>& propagate_down,
    166       const vector<Blob<Dtype>*>& bottom);
    167 
    168   /**
    169    * @brief Returns the vector of learnable parameter blobs.
    170    */
    171   vector<shared_ptr<Blob<Dtype> > >& blobs() {
    172     return blobs_;//返回Layer内部可训练的权值、偏置项Blob向量
    173   }
    174 
    175   /**
    176    * @brief Returns the layer parameter.
    177    */
    178    //返回Layer初始化参数(由ProtoBuffer提供)
    179   const LayerParameter& layer_param() const { return layer_param_; }
    180 
    181   /**
    182    * @brief Writes the layer parameter to a protocol buffer
    183    */
    184    //将Layer初始化参数写入ProtoBuffer缓冲区
    185   virtual void ToProto(LayerParameter* param, bool write_diff = false);
    186 
    187   /**
    188    * @brief Returns the scalar loss associated with a top blob at a given index.
    189    */
    190    //返回与某个Top Blob相关的标量loss值
    191   inline Dtype loss(const int top_index) const {
    192     return (loss_.size() > top_index) ? loss_[top_index] : Dtype(0);
    193   }
    194 
    195   /**
    196    * @brief Sets the loss associated with a top blob at a given index.
    197    */
    198    //设置与某个Top Blob相关的标量loss值
    199   inline void set_loss(const int top_index, const Dtype value) {
    200     if (loss_.size() <= top_index) {
    201       loss_.resize(top_index + 1, Dtype(0));
    202     }
    203     loss_[top_index] = value;
    204   }
    205 
    206   /**
    207    * @brief Returns the layer type.
    208    */
    209    //返回层类型字符串,便于识别,由派生类实现
    210   virtual inline const char* type() const { return ""; }
    211 
    212   /**
    213    * @brief Returns the exact number of bottom blobs required by the layer,
    214    *        or -1 if no exact number is required.
    215    *
    216    * This method should be overridden to return a non-negative value if your
    217    * layer expects some exact number of bottom blobs.
    218    */
    219    //返回Layer需要的输入Bottom Blob数目,-1表示不关心,需要派生类实现
    220   virtual inline int ExactNumBottomBlobs() const { return -1; }
    221   /**
    222    * @brief Returns the minimum number of bottom blobs required by the layer,
    223    *        or -1 if no minimum number is required.
    224    *
    225    * This method should be overridden to return a non-negative value if your
    226    * layer expects some minimum number of bottom blobs.
    227    */
    228   virtual inline int MinBottomBlobs() const { return -1; }
    229   /**
    230    * @brief Returns the maximum number of bottom blobs required by the layer,
    231    *        or -1 if no maximum number is required.
    232    *
    233    * This method should be overridden to return a non-negative value if your
    234    * layer expects some maximum number of bottom blobs.
    235    */
    236   virtual inline int MaxBottomBlobs() const { return -1; }
    237   /**
    238    * @brief Returns the exact number of top blobs required by the layer,
    239    *        or -1 if no exact number is required.
    240    *
    241    * This method should be overridden to return a non-negative value if your
    242    * layer expects some exact number of top blobs.
    243    */
    244   //返回Layer需要的输出Top Blob数目,-1表示不关心,需要派生类实现
    245   virtual inline int ExactNumTopBlobs() const { return -1; }
    246   /**
    247    * @brief Returns the minimum number of top blobs required by the layer,
    248    *        or -1 if no minimum number is required.
    249    *
    250    * This method should be overridden to return a non-negative value if your
    251    * layer expects some minimum number of top blobs.
    252    */
    253   virtual inline int MinTopBlobs() const { return -1; }
    254   /**
    255    * @brief Returns the maximum number of top blobs required by the layer,
    256    *        or -1 if no maximum number is required.
    257    *
    258    * This method should be overridden to return a non-negative value if your
    259    * layer expects some maximum number of top blobs.
    260    */
    261   virtual inline int MaxTopBlobs() const { return -1; }
    262   /**
    263    * @brief Returns true if the layer requires an equal number of bottom and
    264    *        top blobs.
    265    *
    266    * This method should be overridden to return true if your layer expects an
    267    * equal number of bottom and top blobs.
    268    */
    269    //返回Layer是否有相同的输入输出Blob,需要派生类实现
    270   virtual inline bool EqualNumBottomTopBlobs() const { return false; }
    271 
    272   /**
    273    * @brief Return whether "anonymous" top blobs are created automatically
    274    *        by the layer.
    275    *
    276    * If this method returns true, Net::Init will create enough "anonymous" top
    277    * blobs to fulfill the requirement specified by ExactNumTopBlobs() or
    278    * MinTopBlobs().
    279    */
    280    //返回是否允许匿名Top Blob,即由该层自动创建。
    281    //如果为真,Net::Init 会创建足够多的匿名Top Blob来满足 ExactNumTopBlobs() or MinTopBlobs()需求
    282   virtual inline bool AutoTopBlobs() const { return false; }
    283 
    284   /**
    285    * @brief Return whether to allow force_backward for a given bottom blob
    286    *        index.
    287    *
    288    * If AllowForceBackward(i) == false, we will ignore the force_backward
    289    * setting and backpropagate to blob i only if it needs gradient information
    290    * (as is done when force_backward == false).
    291    */
    292    //是否允许强制反向传播。如果AllowForceBackward(i) == false,忽略force_backward设定
    293   virtual inline bool AllowForceBackward(const int bottom_index) const {
    294     return true;
    295   }
    296 
    297   /**
    298    * @brief Specifies whether the layer should compute gradients w.r.t. a
    299    *        parameter at a particular index given by param_id.
    300    *
    301    * You can safely ignore false values and always compute gradients
    302    * for all parameters, but possibly with wasteful computation.
    303    */
    304    //该Layer是否计算相对权值或偏置项的梯度,具体相对谁由param_id指定
    305   inline bool param_propagate_down(const int param_id) {
    306     return (param_propagate_down_.size() > param_id) ?
    307         param_propagate_down_[param_id] : false;
    308   }
    309   /**
    310    * @brief Sets whether the layer should compute gradients w.r.t. a
    311    *        parameter at a particular index given by param_id.
    312    */
    313    //设置该Layer是否计算相对权值或偏置项的梯度,具体相对谁由param_id指定
    314   inline void set_param_propagate_down(const int param_id, const bool value) {
    315     if (param_propagate_down_.size() <= param_id) {
    316       param_propagate_down_.resize(param_id + 1, true);
    317     }
    318     param_propagate_down_[param_id] = value;
    319   }
    320 
    321 
    322  protected:
    323   /** The protobuf that stores the layer parameters */
    324   LayerParameter layer_param_;//保存Layer参数的ProtoBuffer对象
    325   /** The phase: TRAIN or TEST */
    326   Phase phase_;//Layer当前所属阶段,可选TRAIN或TEST
    327   /** The vector that stores the learnable parameters as a set of blobs. */
    328   vector<shared_ptr<Blob<Dtype> > > blobs_;//Layer内部权值偏置项,由Blob组织
    329   /** Vector indicating whether to compute the diff of each param blob. */
    330   vector<bool> param_propagate_down_;//标志位,是否计算对应的参数的误差梯度
    331 
    332   /** The vector that indicates whether each top blob has a non-zero weight in
    333    *  the objective function. */
    334   vector<Dtype> loss_;//标志位,在目标函数中是否每个Top Blob都有非零权值
    335 
    336   //以下四个函数会在派生类中经常看到
    337   
    338   /** @brief Using the CPU device, compute the layer output. */
    339   virtual void Forward_cpu(const vector<Blob<Dtype>*>& bottom,
    340       const vector<Blob<Dtype>*>& top) = 0;
    341   /**
    342    * @brief Using the GPU device, compute the layer output.
    343    *        Fall back to Forward_cpu() if unavailable.
    344    */
    345   virtual void Forward_gpu(const vector<Blob<Dtype>*>& bottom,
    346       const vector<Blob<Dtype>*>& top) {
    347     // LOG(WARNING) << "Using CPU code as backup.";
    348     return Forward_cpu(bottom, top);
    349   }
    350 
    351   /**
    352    * @brief Using the CPU device, compute the gradients for any parameters and
    353    *        for the bottom blobs if propagate_down is true.
    354    */
    355   virtual void Backward_cpu(const vector<Blob<Dtype>*>& top,
    356       const vector<bool>& propagate_down,
    357       const vector<Blob<Dtype>*>& bottom) = 0;
    358   /**
    359    * @brief Using the GPU device, compute the gradients for any parameters and
    360    *        for the bottom blobs if propagate_down is true.
    361    *        Fall back to Backward_cpu() if unavailable.
    362    */
    363   virtual void Backward_gpu(const vector<Blob<Dtype>*>& top,
    364       const vector<bool>& propagate_down,
    365       const vector<Blob<Dtype>*>& bottom) {
    366     // LOG(WARNING) << "Using CPU code as backup.";
    367     Backward_cpu(top, propagate_down, bottom);
    368   }
    369 
    370   /**
    371    * Called by the parent Layer's SetUp to check that the number of bottom
    372    * and top Blobs provided as input match the expected numbers specified by
    373    * the {ExactNum,Min,Max}{Bottom,Top}Blobs() functions.
    374    */
    375    //校验输入输出Blob数目是否满足Layer要求
    376   virtual void CheckBlobCounts(const vector<Blob<Dtype>*>& bottom,
    377                                const vector<Blob<Dtype>*>& top) {
    378     if (ExactNumBottomBlobs() >= 0) {
    379       CHECK_EQ(ExactNumBottomBlobs(), bottom.size())
    380           << type() << " Layer takes " << ExactNumBottomBlobs()
    381           << " bottom blob(s) as input.";
    382     }
    383     if (MinBottomBlobs() >= 0) {
    384       CHECK_LE(MinBottomBlobs(), bottom.size())
    385           << type() << " Layer takes at least " << MinBottomBlobs()
    386           << " bottom blob(s) as input.";
    387     }
    388     if (MaxBottomBlobs() >= 0) {
    389       CHECK_GE(MaxBottomBlobs(), bottom.size())
    390           << type() << " Layer takes at most " << MaxBottomBlobs()
    391           << " bottom blob(s) as input.";
    392     }
    393     if (ExactNumTopBlobs() >= 0) {
    394       CHECK_EQ(ExactNumTopBlobs(), top.size())
    395           << type() << " Layer produces " << ExactNumTopBlobs()
    396           << " top blob(s) as output.";
    397     }
    398     if (MinTopBlobs() >= 0) {
    399       CHECK_LE(MinTopBlobs(), top.size())
    400           << type() << " Layer produces at least " << MinTopBlobs()
    401           << " top blob(s) as output.";
    402     }
    403     if (MaxTopBlobs() >= 0) {
    404       CHECK_GE(MaxTopBlobs(), top.size())
    405           << type() << " Layer produces at most " << MaxTopBlobs()
    406           << " top blob(s) as output.";
    407     }
    408     if (EqualNumBottomTopBlobs()) {
    409       CHECK_EQ(bottom.size(), top.size())
    410           << type() << " Layer produces one top blob as output for each "
    411           << "bottom blob input.";
    412     }
    413   }
    414 
    415   /**
    416    * Called by SetUp to initialize the weights associated with any top blobs in
    417    * the loss function. Store non-zero loss weights in the diff blob.
    418    */
    419    //该函数在Layer的Setup函数中调用,主要目的是初始化与TopBlob相关的loss权重,放到top blob的diff域
    420    //实际由Forward()计算loss
    421    //loss_weight==0 表示当前层不参与loss计算,大部分layer属于这一类
    422    //loss_weight==1 表示当前层参与loss计算,损失层(LossLayer)属于这一类
    423   inline void SetLossWeights(const vector<Blob<Dtype>*>& top) {
    424     //从ProtoBuffer对象中获得Layer参数,这里需要loss_weight参数
    425     const int num_loss_weights = layer_param_.loss_weight_size();
    426     if (num_loss_weights) {//如果ProtoBuffer中至少有一个loss_weight 参数
    427       //loss_weight个数应该与TopBlob相同,或者不要Loss_weigth参数
    428       CHECK_EQ(top.size(), num_loss_weights) << "loss_weight must be "
    429           "unspecified or specified once per top blob.";
    430       //遍历每一个Top Blob
    431       for (int top_id = 0; top_id < top.size(); ++top_id) {
    432         //从ProtoBuffer对象中获得loss_weight参数(0或者1)
    433         const Dtype loss_weight = layer_param_.loss_weight(top_id);
    434         if (loss_weight == Dtype(0)) { continue; }//为0,跳过
    435         this->set_loss(top_id, loss_weight);//不为0,进行网络的相关设置
    436         const int count = top[top_id]->count();//本地记录loss_weight的值
    437         Dtype* loss_multiplier = top[top_id]->mutable_cpu_diff();
    438         //将loss_weight写入TopBlob的diff中,传递到需要使用的地方,实现远程同步
    439         caffe_set(count, loss_weight, loss_multiplier);
    440       }
    441     }
    442   }
    443 
    444  private:
    445   DISABLE_COPY_AND_ASSIGN(Layer);//禁用拷贝构造函数和赋值运算函数
    446 };  // class Layer
    447 
    448 // Forward and backward wrappers. You should implement the cpu and
    449 // gpu specific implementations instead, and should not change these
    450 // functions.
    451 //前向传播函数、后向传播函数的包装,不需要修改这两个函数
    452 //使用时只需要在派生类中改写Forward_cpu等
    453 template <typename Dtype>
    454 inline Dtype Layer<Dtype>::Forward(const vector<Blob<Dtype>*>& bottom,
    455     const vector<Blob<Dtype>*>& top) {
    456   Dtype loss = 0;
    457   Reshape(bottom, top);
    458   switch (Caffe::mode()) {//判断计算设备
    459   case Caffe::CPU://在CPU上执行Forward计算
    460     Forward_cpu(bottom, top);//调用CPU版本的Forward
    461     //如果需要计算loss还需要进一步操作
    462     for (int top_id = 0; top_id < top.size(); ++top_id) {
    463       if (!this->loss(top_id)) { continue; }
    464       const int count = top[top_id]->count();
    465       //若为损失层,则已经通过Forward函数计算出全局损失函数,放在Top Blob data中
    466       const Dtype* data = top[top_id]->cpu_data();
    467       //若loss_weight不为0,则已经在SetLossWeight中将loss权重放在Top Blob diff 中
    468       const Dtype* loss_weights = top[top_id]->cpu_diff();
    469       loss += caffe_cpu_dot(count, data, loss_weights);//加权loss之和,得到标量loss
    470     }
    471     break;
    472   case Caffe::GPU:
    473     Forward_gpu(bottom, top);
    474 #ifndef CPU_ONLY
    475     for (int top_id = 0; top_id < top.size(); ++top_id) {
    476       if (!this->loss(top_id)) { continue; }
    477       const int count = top[top_id]->count();
    478       const Dtype* data = top[top_id]->gpu_data();
    479       const Dtype* loss_weights = top[top_id]->gpu_diff();
    480       Dtype blob_loss = 0;
    481       caffe_gpu_dot(count, data, loss_weights, &blob_loss);
    482       loss += blob_loss;
    483     }
    484 #endif
    485     break;
    486   default:
    487     LOG(FATAL) << "Unknown caffe mode.";
    488   }
    489   return loss;
    490 }
    491 //反向传播函数,直接调用对应设备函数
    492 template <typename Dtype>
    493 inline void Layer<Dtype>::Backward(const vector<Blob<Dtype>*>& top,
    494     const vector<bool>& propagate_down,
    495     const vector<Blob<Dtype>*>& bottom) {
    496   switch (Caffe::mode()) {
    497   case Caffe::CPU:
    498     Backward_cpu(top, propagate_down, bottom);
    499     break;
    500   case Caffe::GPU:
    501     Backward_gpu(top, propagate_down, bottom);
    502     break;
    503   default:
    504     LOG(FATAL) << "Unknown caffe mode.";
    505   }
    506 }
    507 //将层配置参数序列化为ProtoBuffer
    508 // Serialize LayerParameter to protocol buffer
    509 template <typename Dtype>
    510 void Layer<Dtype>::ToProto(LayerParameter* param, bool write_diff) {
    511   param->Clear();
    512   param->CopyFrom(layer_param_);
    513   param->clear_blobs();
    514   for (int i = 0; i < blobs_.size(); ++i) {
    515     blobs_[i]->ToProto(param->add_blobs(), write_diff);
    516   }//权值偏置项也会保存
    517 }
    518 
    519 }  // namespace caffe
    520 
    521 #endif  // CAFFE_LAYER_H_

     待更新

    摘抄参考赵永科《深度学习 21天实战caffe》

  • 相关阅读:
    使用docker 创建SSL 证书
    定时任务知识清单列表
    Spring Tool Suite介绍
    常用的正则表达式
    MD5加密--项目案例
    MD5加密简单使用
    啥是MD5?
    SpringBoot整合Redis
    StringRedisTemplate操作redis数据
    013-- mysql常用的查询优化方法
  • 原文地址:https://www.cnblogs.com/xiangfeidemengzhu/p/7099160.html
Copyright © 2011-2022 走看看