Net类是Solve类的一个成员,在net.cpp中定义了对Net的所有操作,其中包括:
- Init
- GetLearningRateAndWeightDecay
- ForwardPrefilled
- Backward
- ShareTrainedLayersWith
- CopyTrainedLayersFrom
- ToProto
- Update
- has_blob
- blob_by_name
- has_layer
- layer_by_name
Net(const NetParameter& param)
功能:调用Init函数初始化网络
输入:NetParameter& param
输出:无
Net(const string& param_file)
功能:调用Init函数初始化网络
输入:string& param_file
输出:无
Init(const NetParameter& in_param)
功能:初始化网络
输入:NetParameter& in_param
输出:无
步骤:
<1> 调用InsertSplits()函数从in_param读入新网络到param
<2> 定义name_,blob_name_to_idx,available_blobs,num_layers
<3> param.input_size()返回输入层blob的个数;
param.input(i)表示第i个blob的名字;
param.layers_size()返回网络的层数。
<4> 对每一个输入层的blob:
- 产生一块和当前blob一样大的空间 e.g. imput_dim=[12 55 66 39 20 24 48 64]表示第一个blob的四个维数为 12 55 66 39,第二个为 20 24 48 64 接着blob_pointer指向这块空间
- blob_pointer压到blobs_中
vector<shared_ptr<Blob<Dtype>>> blobs_
- blob_name压到blob_names_中
vector<string> blob_names_
- param.force_backward()压到blob_need_backward_中
vector<bool> blob_need_backward_
- i 压到 net_input_blob_indices_中 net_input_blob_indices_ -> vector
- blob_pointer.get() 压到 net_input_blobs_中
注意与blobs_的区别
vector<shared_ptr<Blob<Dtype>>> blobs_
vector<Blob<Dtype>*> net_input_blobs_
shared_ptr类型的参数调用.get()则得到Blob*类型 map<string, int> blob_name_to_idx
- 初始化为输入层的每个blob的名字
set<string> available_blobs
- 计算所需内存
memory_used += blob_pointer->count()
<5> 存每一层的输入blob指针 vector<vector<Blob<Dtype>*> > bottom_vecs_
存每一层输入(bottom)的id vector<vector<int> > bottom_id_vecs_
存每一层输出(top)的blob vector<vector<Blob<Dtype>*> > top_vecs_
用网络的层数param.layers_size()去初始化上面四个变量
vector<vector<int> > top_id_vecs_
<6> 对第i层(很大的一个for循环):
- param.layers(i)返回的是关于第当前层的参数:
layer_param = param.layers(i)
- 把当前层的参数转换为
shared_ptr<Layer<Dtype>>
,并压入到layers_中 - 把当前层的名字压入到layer_names_:
vector<string> layer_names_
- 判断当前层是否需要反馈
need_backward = param.force_backward()
-
下面开始产生当前层:分为处理bottom的blob和top的blob两个步骤
对第j个bottom的blob:- layer_param.bottom_size()存的是当前层的输入blob数量
- layer_param.bottom(j)存的是第j个输入blob的名字
- 读取当前blob的id,其中blob_name_to_idx在输入层初始化过了
blob_name_to_idx[blob_name] = i
- 输出当前blob的名字
- 存入第j个输入blob的指针
bottom_vecs_[i].push_back(blobs_[blob_id].get())
- 存入第j个输入blob的id
bottom_id_vecs_[i].push_back(blob_id)
- 更新need_backward
- 从available_blobs中删除第j个blob的名字
对第j个top的blob:
- layer_param.top_size()存的是当前层的输出blob数量
- layer_param.top(j)存的是第j个输出blob的名字
- 判断是否进行同址计算
- 输出当前blob的名字
- 定义一块新的blob空间,用blob_pointer指向这块空间
- 把这个指针存入到blobs_中
- 把blob_name、force_backward、idx存入对应的容器中
- 向available_blobs插入当前blob的名字
- top_vecs_[i]对于第i层,插入当前blob的指针
- top_id_vecs_[i]对于第i层,插入当前blob的id
- 输出当前层位于top的blob的信息
- 计算所需内存
- 判断当前层i是否需要backward
<7> 所有名字在available_blobs中的blob为当前层的输出blob,
存入net_output_blobs_
中
<8> 建立每个blob的name和index的对应关系map:blob_names_index_
<9> 建立每个层的name和index的对应关系map:layer_names_index_
<10> 调用GetLearningRateAndWeightDecay函数
GetLearningRateAndWeightDecay()
功能:收集学习速率和权重衰减,即更新params_、params_lr_和params_weight_decay_
输入:无
输出:无
步骤:对每一层
1. 把当前层的所有blob存入params_中
params_// The parameters in the network
2. 如果有lr, 则把当前层的所有blob的lr存入params_lr_中; 否则, lr默认为1
3. 如果有 weight_decay,则把当前层的所有 blob 的 weight_decay
存入 params_weight_decay_ 中
4. 否则,weight_decay 默认为1
ForwardPrefilled(Dtype* loss)
功能:前馈预先填满,即预先进行一次前馈
输入:Dtype* loss
输出:net_output_blobs_,前馈后的输出层blob:vector
Forward(const vector<Blob<Dtype>*> & bottom, Dtype* loss)
功能:把网络输入层的blob读到net_input_blobs_,然后进行前馈,计算出loss
输入:整个网络输入层的blob
输出:整个网络输出层的blob
Forward(const string& input_blob_protos, Dtype* loss)
功能:Forward的重载,只是输入层的blob以string的格式传入
Backward()
功能:对整个网络进行反向传播
ShareTrainedLayersWith(Net* other)
功能:从Other网络复制某些层
步骤:对Other网络的第i层(源层):
1. 定义一个Layer的指针指向第i层
2. 读取第i层(源层)的名字
3. 找通过名字来找目标层
如果没找到,即target_layer_id == layer_names_.size()
则忽略Other的第i层,即Other的第i层不需要share给网络
4. 如果找到了,即other的第i层需要share给网络,
则把目标层的所有blob读到target_blobs中
- 判断目标层和源层的blob数量是否相等
- 判断每个blob大小是否相等
- 调用ShareData函数把源层的blob赋给目标层的blob
CopyTrainedLayersFrom(const NetParameter& param)
功能:和ShareTrainedLayersWith一样
步骤:不同的是调用FromProto函数把源层的blob赋给目标层的blob
CopyTrainedLayersFrom(const string trained_filename)
功能:从文件中读入NetParameter param,然后调用CopyTrainedLayersFrom()
ToProto(NetParameter* param, bool write_diff)
功能:把网络的参数存入prototxt中
步骤:
1. 设置网络的名字:param->set_name(name_)
2. 加入输入层blob的名字
3. 对于第i层:
- 加入bottom的blob的名字
- 加入top的blob的名字
- 写到proto中
Update()
功能:更新params_中blob的值
has_blob(const string& blob_name)
功能:判断是否存在名字为blob_name的blob
blob_by_name(const string& blob_name)
功能:给一个blob的名字,返回这个blob的指针
has_layer(const string& layer_name)
功能:判断是否存在名字为layer_name的layer
layer_by_name(const string& layer_name)
功能:给一个layer的名字,返回这个layer的指针
版权声明:本文为博主原创文章,未经博主允许不得转载。