Net由多个layer组成,是一个有向无环图(DAG)。
Net参数主要包括网络信息和每个layer的信息,Blob信息等,接口包括初始化Net来构建整个图,Net信息接口,初始化后Bolb数据输入等。
src/caffe/proto/caffe.proto
message NetParameter {
optional string name = ; // 网络名称
// DEPRECATED. See InputParameter. The input blobs to the network.
repeated string input = ; //网络输入的blob名称
// DEPRECATED. See InputParameter. The shape of the input blobs.
repeated BlobShape input_shape = ; //输入blob维度
// 4D input dimensions -- deprecated. Use "input_shape" instead.
// If specified, for each input blob there should be four
// values specifying the num, channels, height and width of the input blob.
// Thus, there should be a total of (4 * #input) numbers.
repeated int32 input_dim = ; //默认维度4,代表num, channels, height and width of the input blob
// 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.
optional bool force_backward = [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.
optional NetState state = ; //网络当前状态
// Print debugging information about results while running Net::Forward,
// Net::Backward, and Net::Update.
optional bool debug_info = [default = false]; //debug信息是否打印
// The layers that make up the net. Each of their configurations, including
// connectivity and behavior, is specified as a LayerParameter.
repeated LayerParameter layer = ; // ID设置为100,这样层描述会置于末尾
// DEPRECATED: use 'layer' instead.
repeated V1LayerParameter layers = ; //已经被淘汰
}
Net属性很少,但是其实对应真实的prototxt可以很长,关键在于用户可以自己配置和增加layer。
include/caffe/net.hpp
Net接口的头文件,包括一些Net接口的声明和实现,比如:
Net的构造函数和析构函数
template <typename Dtype>
class Net {
public:
explicit Net(const NetParameter& param);
explicit Net(const string& param_file, Phase phase,
const int level = , const vector<string>* stages = NULL);
virtual ~Net() {}
使用NetParameter对象初始化Net
/// @brief Initialize a network with a NetParameter.
void Init(const NetParameter& param);
Net 前向传播的几种接口
/**
* @brief Run Forward and return the result.
*
*/
const vector<Blob<Dtype>*>& Forward(Dtype* loss = NULL);
/// @brief DEPRECATED; use Forward() instead.
const vector<Blob<Dtype>*>& ForwardPrefilled(Dtype* loss = NULL) {
LOG_EVERY_N(WARNING, ) << "DEPRECATED: ForwardPrefilled() "
<< "will be removed in a future version. Use Forward().";
return Forward(loss);
}
Dtype ForwardFromTo(int start, int end);
Dtype ForwardFrom(int start);
Dtype ForwardTo(int end);
/// @brief DEPRECATED; set input blobs then use Forward() instead.
const vector<Blob<Dtype>*>& Forward(const vector<Blob<Dtype>* > & bottom,
Dtype* loss = NULL);
Net 后向传播的几种接口
void Backward();
void BackwardFromTo(int start, int end);
void BackwardFrom(int start);
void BackwardTo(int end);
从一个训练好的Net拷贝信息
void CopyTrainedLayersFrom(const NetParameter& param);
void CopyTrainedLayersFrom(const string trained_filename);
void CopyTrainedLayersFromBinaryProto(const string trained_filename);
void CopyTrainedLayersFromHDF5(const string trained_filename);
返回bottom信息
inline const vector<vector<Blob<Dtype>*> >& bottom_vecs() const {
return bottom_vecs_;
}
src/caffe/net.cpp
Net的源文件,Net接口的具体实现,比如
Net初始化
template <typename Dtype>
void Net<Dtype>::Init(const NetParameter& in_param) {
// Set phase from the state.
phase_ = in_param.state().phase();
// Filter layers based on their include/exclude rules and
// the current NetState.
NetParameter filtered_param;
FilterNet(in_param, &filtered_param);
LOG_IF(INFO, Caffe::root_solver())
<< "Initializing net from parameters: " << std::endl
<< filtered_param.DebugString();
// Create a copy of filtered_param with splits added where necessary.
NetParameter param;
InsertSplits(filtered_param, ¶m);
// Basically, build all the layers and set up their connections.
name_ = param.name();
map<string, int> blob_name_to_idx;
set<string> available_blobs;
memory_used_ = ;
…
Net中FilterNet构造函数
template <typename Dtype>
void Net<Dtype>::FilterNet(const NetParameter& param,
NetParameter* param_filtered) {
NetState net_state(param.state());
param_filtered->CopyFrom(param);
param_filtered->clear_layer();
for (int i = ; i < param.layer_size(); ++i) {
const LayerParameter& layer_param = param.layer(i);
const string& layer_name = layer_param.name();
CHECK(layer_param.include_size() == || layer_param.exclude_size() == )
…
Net初始化时将Top层的Bolb数据填充进layer
template <typename Dtype>
void Net<Dtype>::AppendTop(const NetParameter& param, const int layer_id,
const int top_id, set<string>* available_blobs,
map<string, int>* blob_name_to_idx) {
shared_ptr<LayerParameter> layer_param(
new LayerParameter(param.layer(layer_id)));
const string& blob_name = (layer_param->top_size() > top_id) ?
layer_param->top(top_id) : "(automatic)";
// Check if we are doing in-place computation
if (blob_name_to_idx && layer_param->bottom_size() > top_id &&
blob_name == layer_param->bottom(top_id)) {
// In-place computation
LOG_IF(INFO, Caffe::root_solver())
…
Net初始化时将Bottom层的Bolb数据填充进layer
template <typename Dtype>
int Net<Dtype>::AppendBottom(const NetParameter& param, const int layer_id,
const int bottom_id, set<string>* available_blobs,
map<string, int>* blob_name_to_idx) {
const LayerParameter& layer_param = param.layer(layer_id);
const string& blob_name = layer_param.bottom(bottom_id);
if (available_blobs->find(blob_name) == available_blobs->end()) {
LOG(FATAL) << "Unknown bottom blob '" << blob_name << "' (layer '"
<< layer_param.name() << "', bottom index " << bottom_id << ")";
}
const int blob_id = (*blob_name_to_idx)[blob_name];
LOG_IF(INFO, Caffe::root_solver())
<< layer_names_[layer_id] << " <- " << blob_name;
…