/************************************************************************************************************************
文件说明:
【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_