【深度学习】【Caffe源代码解读3】笔记21 Caffe的基本数据结构之Net

/************************************************************************************************************************
文件说明:
        【1】Net就是一张洁面的【图纸】,对应相应的网络模型描述文件*.prototxt.
		【2】我们选择Caffe自带的CaffeNet模型描述文件,该模型描述文件位于
		          E:\caffeInstall2013\caffe-master\models\bvlc_reference_caffenet\deploy.prototxt
		【3】下面我们写一个Demo测试一下这个文件
运行结果:
        【1】通过下面的运行结果,我们可以看出,Net中即包含Layer对象,又包含Blob对象
		【2】其中,Blob对象用于存放每个Layer的输入/输出的中间结果
		【3】Layer则根据Net描述对指定的输入Blob进行进行某些计算处理(卷积、下采样、全连接、非线性变换、计算代价函数等),
		     输出结果放到指定的输出Blob中。
		【4】所有的Layer对象和Blob对象都用名字区分。
		【5】Blob和Layer同名,但并不代表他们之间有任何直接的联系。
		【6】我们可以通过函数has_blob()、has_layer()函数来查询当前Net对象是否包含指定名字的Blob或者Layer对象,如果返回值
		     为真,则可以进一步调用blob_by_name()、layer_by_name()函数直接获取相应的blob或layer指针,进行一些操作(如提取
			 某层计算输出的特征或者某个Blob的权值)
数据结构的描述:

开发环境:
         Win10+caffe+cuda7.5+opencv+vs2013
时间地点:
         陕西师范大学 文津楼 2017.8.7
作    者:
         九 月
*************************************************************************************************************************/
#include<vector>
#include<iostream>
#include<caffe/net.hpp>

using namespace cv;
using namespace std;

int main(void)
{
	std::string          proto("E:\\caffeInstall2013\\caffe-master\\models\\bvlc_reference_caffenet\\deploy.prototxt");
	caffe::Net<float>   netObject(proto,caffe::TEST);
	std::vector<string>  blobObjName = netObject.blob_names();        //【1】获取Net中所有Blob对象名
	std::vector<string>  layerObjName = netObject.layer_names();      //【2】获取Net中所有Layer的对象名

	for (int i = 0; i < blobObjName.size(); i++)
	{
		std::cout << "Blob#" << i << blobObjName[i] << std::endl;
	}

	for (int i = 0; i < layerObjName.size(); i++)
	{
		std::cout << "Blob#" << i << layerObjName[i] << std::endl;
	}

	std::system("pause");
	return 0;
}




/************************************************************************************************************************
文件说明:
        【1】Net在caffe中代表一个完整的CNN模型,它包含若干Layer实例。
		【2】在protoBuffer文本文件(prototxt)描述的经典网络结构如LeNet、AlexNet,这些结构反映在caffe代码实现上就是一个Net对
		     象。
		【3】通过本本块代码的阅读,你将会发现,Net是相对Blob、Layer更为复杂的设计。
		【4】通过合成和自动微分,网络同时定义了一个函数和其对应的梯度。通过合成各层的输出来计算这个函数,来执行给定的任务,
		     并通过合成各层的输出来计算这个函数,来执行给定的任务。
		【5】caffe模型是【端到端的机器学习模型】。
		【6】准确的说,Net是由一些列层Layer组成的有向无环图DAG计算图,caffe保留了计算图中所有的中间值以确保前向和反向迭代
		     的准确性。
		【7】一个典型的Net开始于Data layer----从磁盘加载数据开始,终止于loss layer,计算分类和重构这些任务的目标函数。
		【8】Net由一些列层和它们之间的相互连接构成,用的是一种文本建模语言。
Net说明:
         我们将Blob比作caffe的砖石,Layer比作Caffe的墙面,那么Net更像是工匠手中的图纸,描述每个墙面应该出现的位置。
开发环境:
         Win10+caffe+cuda7.5+opencv+vs2013
时间地点:
         陕西师范大学 文津楼 2017.8.7
作    者:
         九 月
*************************************************************************************************************************/
#ifndef CAFFE_NET_HPP_
#define CAFFE_NET_HPP_

#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "caffe/blob.hpp"
#include "caffe/common.hpp"
#include "caffe/layer.hpp"
#include "caffe/proto/caffe.pb.h"

namespace caffe 
{

template <typename Dtype>
class Net 
{
 public:
  /**********************************************************************************************************
  函数说明:
           Net类的显示构造函数
  函数参数:
           【1】const NetParameter& param--------网络参数
		   【2】const Net* root_net = NULL
  ***********************************************************************************************************/
  explicit Net(const NetParameter& param, const Net* root_net = NULL);
  /**********************************************************************************************************
  函数说明:
           Net类的显示构造函数
  函数参数:
          【1】const string& param_file---------网络模型的参数文件
          【2】Phase phase----------------------网络的阶段TRAIN/TEST,Phase这是个枚举类型
		  【3】const int level = 0
		  【4】const vector<string>* stages = NULL
		  【5】const Net* root_net = NULL)
  ***********************************************************************************************************/
  explicit Net(const string& param_file, Phase phase,const int level = 0, const vector<string>* stages = NULL,
                const Net* root_net = NULL);
  /**********************************************************************************************************
  函数说明:
          虚析构函数
  ***********************************************************************************************************/
  virtual ~Net() {}
  /**********************************************************************************************************
  函数说明:
          【1】Initialize a network with a NetParameter.
		  【2】用NetParameter对象初始化一个网络
  ***********************************************************************************************************/
  void Init(const NetParameter& param);
  /**********************************************************************************************************
  函数说明:
          【1】set phase,enable train and test with one network, for saving memory
          【2】设置阶段,允许训练和测试使用同一个网络
  ***********************************************************************************************************/
  void SetPhase(Phase phase);
  /**********************************************************************************************************
  函数说明:
          进行前向传播,返回结果
  ***********************************************************************************************************/
  const vector<Blob<Dtype>*>& Forward(Dtype* loss = NULL);
  /**********************************************************************************************************
  函数说明:
          进行前向传播,输入Blob已经预先填充
  ***********************************************************************************************************/
  const vector<Blob<Dtype>*>& ForwardPrefilled(Dtype* loss = NULL) 
  {
    LOG_EVERY_N(WARNING, 1000) << "DEPRECATED: ForwardPrefilled() "
		                       << "will be removed in a future version. Use Forward().";
    return Forward(loss);
  }
  /**********************************************************************************************************
  函数说明:
          Net前向传播的几种形式
  ***********************************************************************************************************/
  Dtype ForwardFromTo(int start, int end);
  Dtype ForwardFrom(int start);
  Dtype ForwardTo(int end);
  const vector<Blob<Dtype>*>& Forward(const vector<Blob<Dtype>* > & bottom,Dtype* loss = NULL);
  void ClearParamDiffs();
  /**********************************************************************************************************
  函数说明:
           几种不同形式的反向传播
  ***********************************************************************************************************/
  void Backward();
  void BackwardFromTo(int start, int end);
  void BackwardFrom(int start);
  void BackwardTo(int end);

  void Reshape();

  Dtype ForwardBackward() 
  {
    Dtype loss;
    Forward(&loss);
    Backward();
    return loss;
  }
  /**********************************************************************************************************
  函数说明:
          根据已经准备好的diff值更新网络权值
  ***********************************************************************************************************/
  void Update();
  void ShareWeights();
  void ShareTrainedLayersWith(const Net* other);
  void CopyTrainedLayersFrom(const NetParameter& param);
  void CopyTrainedLayersFrom(const string trained_filename);
  void CopyTrainedLayersFromBinaryProto(const string trained_filename);
  void CopyTrainedLayersFromHDF5(const string trained_filename);
  /**********************************************************************************************************
  函数说明:
           将一个序列化的网络写到网络模型文件中
  ***********************************************************************************************************/
  void ToProto(NetParameter* param, bool write_diff = false) const;
  void ToHDF5(const string& filename, bool write_diff = false) const;
  /**********************************************************************************************************
  函数说明:
          【1】返回网络的名字
		  【2】returns the network name.
  ***********************************************************************************************************/
  inline const string& name() const 
  { 
	  return name_; 
  }
  /**********************************************************************************************************
  函数说明:
          【1】返回层的名字
          【2】returns the layer names
  ***********************************************************************************************************/
  inline const vector<string>& layer_names() const 
  { 
	  return layer_names_; 
  }
  /**********************************************************************************************************
  函数说明:
          【1】返回Blob的名字
          【2】returns the blob names
  ***********************************************************************************************************/
  inline const vector<string>& blob_names() const 
  { 
	  return blob_names_; 
  }
  /**********************************************************************************************************
  函数说明:
          【1】返回Blob
          【2】returns the blobs
  ***********************************************************************************************************/
  inline const vector<shared_ptr<Blob<Dtype> > >& blobs() const 
  {
    return blobs_;
  }
  /**********************************************************************************************************
  函数说明:
          【1】返回layers
          【2】returns the layers
  ***********************************************************************************************************/
  inline const vector<shared_ptr<Layer<Dtype> > >& layers() const 
  {
    return layers_;
  }
  /**********************************************************************************************************
  函数说明:
          【1】返回阶段
          【2】returns the phase: TRAIN or TEST
  ***********************************************************************************************************/
  inline Phase phase() const 
  { 
	  return phase_; 
  }
  /**********************************************************************************************************
  函数说明:
          返回每个Layer的Bottom Blob
  ***********************************************************************************************************/
  inline const vector<vector<Blob<Dtype>*> >& bottom_vecs() const 
  {
    return bottom_vecs_;
  }
  /**********************************************************************************************************
  函数说明:
          返回每个Layer的Top Blob
  ***********************************************************************************************************/
  inline const vector<vector<Blob<Dtype>*> >& top_vecs() const 
  {
    return top_vecs_;
  }

  inline const vector<vector<int> >& bottom_id_vecs() const 
  {
    return bottom_id_vecs_;
  }
  inline const vector<vector<int> >& top_id_vecs() const 
  {
    return top_id_vecs_;
  }


  inline const vector<int> & top_ids(int i) const 
  {
    CHECK_GE(i, 0) << "Invalid layer id";
    CHECK_LT(i, top_id_vecs_.size()) << "Invalid layer id";
    return top_id_vecs_[i];
  }
 
  inline const vector<int> & bottom_ids(int i) const 
  {
    CHECK_GE(i, 0) << "Invalid layer id";
    CHECK_LT(i, bottom_id_vecs_.size()) << "Invalid layer id";
    return bottom_id_vecs_[i];
  }

  inline const vector<vector<bool> >& bottom_need_backward() const 
  {
    return bottom_need_backward_;
  }
  /**********************************************************************************************************
  函数说明:
           返回每个Blob是否参与loss计算
  ***********************************************************************************************************/
  inline const vector<Dtype>& blob_loss_weights() const 
  {
    return blob_loss_weights_;
  }
  /**********************************************************************************************************
  函数说明:
           返回每个Layer是否参与loss计算
  ***********************************************************************************************************/
  inline const vector<bool>& layer_need_backward() const 
  {
    return layer_need_backward_;
  }
  /// @brief returns the parameters
  inline const vector<shared_ptr<Blob<Dtype> > >& params() const 
  {
    return params_;
  }
  inline const vector<Blob<Dtype>*>& learnable_params() const 
  {
    return learnable_params_;
  }
  /// @brief returns the learnable parameter learning rate multipliers
  inline const vector<float>& params_lr() const { return params_lr_; }
  inline const vector<bool>& has_params_lr() const { return has_params_lr_; }
  /// @brief returns the learnable parameter decay multipliers
  inline const vector<float>& params_weight_decay() const {
    return params_weight_decay_;
  }
  inline const vector<bool>& has_params_decay() const {
    return has_params_decay_;
  }
  const map<string, int>& param_names_index() const {
    return param_names_index_;
  }
  inline const vector<int>& param_owners() const { return param_owners_; }
  inline const vector<string>& param_display_names() const {
    return param_display_names_;
  }
  /// @brief Input and output blob numbers
  inline int num_inputs() const { return net_input_blobs_.size(); }
  inline int num_outputs() const { return net_output_blobs_.size(); }
  inline const vector<Blob<Dtype>*>& input_blobs() const {
    return net_input_blobs_;
  }
  inline const vector<Blob<Dtype>*>& output_blobs() const {
    return net_output_blobs_;
  }
  inline const vector<int>& input_blob_indices() const {
    return net_input_blob_indices_;
  }
  inline const vector<int>& output_blob_indices() const {
    return net_output_blob_indices_;
  }
  bool has_blob(const string& blob_name) const;
  const shared_ptr<Blob<Dtype> > blob_by_name(const string& blob_name) const;
  bool has_layer(const string& layer_name) const;
  const shared_ptr<Layer<Dtype> > layer_by_name(const string& layer_name) const;

  void set_debug_info(const bool value) { debug_info_ = value; }

  // Helpers for Init.
  /**
   * @brief Remove layers that the user specified should be excluded given the current
   *        phase, level, and stage.
   */
  static void FilterNet(const NetParameter& param,
      NetParameter* param_filtered);
  /// @brief return whether NetState state meets NetStateRule rule
  static bool StateMeetsRule(const NetState& state, const NetStateRule& rule,
      const string& layer_name);

 protected:
  // Helpers for Init.
  /// @brief Append a new top blob to the net.
  void AppendTop(const NetParameter& param, const int layer_id,
                 const int top_id, set<string>* available_blobs,
                 map<string, int>* blob_name_to_idx);
  /// @brief Append a new bottom blob to the net.
  int AppendBottom(const NetParameter& param, const int layer_id,
                   const int bottom_id, set<string>* available_blobs,
                   map<string, int>* blob_name_to_idx);
  /// @brief Append a new parameter blob to the net.
  void AppendParam(const NetParameter& param, const int layer_id,
                   const int param_id);

  /// @brief Helper for displaying debug info in Forward.
  void ForwardDebugInfo(const int layer_id);
  /// @brief Helper for displaying debug info in Backward.
  void BackwardDebugInfo(const int layer_id);
  /// @brief Helper for displaying debug info in Update.
  void UpdateDebugInfo(const int param_id);


  string                             name_;         //【1】The network name
  Phase                              phase_;        //【2】The phase: TRAIN or TEST
  vector<shared_ptr<Layer<Dtype> > > layers_;       //【3】Individual layers in the net
  vector<string>                     layer_names_;  //【4】layer name
  map<string, int>                   layer_names_index_;
  vector<bool>                       layer_need_backward_;
  vector<shared_ptr<Blob<Dtype> > >   blobs_;       //【5】the blobs storing intermediate results between the layer.
  vector<string>                      blob_names_;
  map<string, int>                    blob_names_index_;
  vector<bool>                        blob_need_backward_;

  vector<vector<Blob<Dtype>*> >      bottom_vecs_;
  vector<vector<int> >               bottom_id_vecs_;
  vector<vector<bool> >             bottom_need_backward_;

  vector<vector<Blob<Dtype>*> >      top_vecs_;
  vector<vector<int> >              top_id_vecs_;

  vector<Dtype>                      blob_loss_weights_;
  vector<vector<int> >               param_id_vecs_;
  vector<int>                       param_owners_;
  vector<string>                     param_display_names_;
  vector<pair<int, int> >           param_layer_indices_;
  map<string, int>                  param_names_index_;

  vector<int>                       net_input_blob_indices_;
  vector<int>                      net_output_blob_indices_;
  vector<Blob<Dtype>*>              net_input_blobs_;
  vector<Blob<Dtype>*>              net_output_blobs_;

  vector<shared_ptr<Blob<Dtype> > > params_;
  vector<Blob<Dtype>*>              learnable_params_;

  vector<int>                      learnable_param_ids_;
  vector<float>                   params_lr_;
  vector<bool>                     has_params_lr_;
 
  vector<float>                    params_weight_decay_;
  vector<bool>                     has_params_decay_;

  size_t                           memory_used_;
  bool                            debug_info_;
  const Net* const               root_net_;
  DISABLE_COPY_AND_ASSIGN(Net);
};


}  // namespace caffe

#endif  // CAFFE_NET_HPP_

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值