作用:对 top输出到多个 Layer的情况进行分割,建立完整的网络结构
重要的参数说明举例:
- layer_idx_to_layer_name[i] 记录各层的名称,如 [0x00000000] "input"
- blob_name_to_last_top_idx[“conv1”]=(1,0) 这个例子相当于说”conv1” 这层是第1层的第0个top,
- bottom_idx_to_source_top_idx[bottom_idx=(2,0)] = (1,0); 相当于说:第2层,第0个bottom,对应着第1层,第0个top 即: [(0x00000001, 0x00000000)] (0x00000000, 0x00000000)
- top_idx_to_bottom_count[(1,0)]=2 表示第1个layer的第0个top有2个top(blob?),要分叉,程序会对此建立新的分叉层
理解:整个函数分为两个部分
1. 遍历整个网络,记录每一个Layer的top的使用情况,记录结构放在 top_idx_to_bottom_count中。
2. 遍历整个网络,对 top_idx_to_bottom_count > 1 的情况进行处理: 分两步走
第一步. 首先是对有多个top层的Layer进行分割,主要的做法是在该层的后面新建一个Layer ,这个新的Layer的会按照 top_idx_to_bottom_count 的个数和约定的分割名称(SplitBlobName)去新建top,参考void ConfigureSplitLayer…
第二步,是对使用同一个top的后续层的bottom的blob进行改名(使用与上一步相同的命名规则)。
下面是源码
void InsertSplits(const NetParameter& param, NetParameter* param_split) {
// Initialize by copying from the input NetParameter.
param_split->CopyFrom(param);
param_split->clear_layer();
map blob_name_to_last_top_idx;
map bottom_idx_to_source_top_idx;
map top_idx_to_bottom_count;
map top_idx_to_loss_weight;
map top_idx_to_bottom_split_idx;
map layer_idx_to_layer_name; // 每层网络的名称
for (int i = 0; i < param.layer_size(); ++i) {
const LayerParameter& layer_param = param.layer(i);
layer_idx_to_layer_name[i] = layer_param.name();
for (int j = 0; j < layer_param.bottom_size(); ++j) {
const string& blob_name = layer_param.bottom(j);
if (blob_name_to_last_top_idx.find(blob_name) ==
blob_name_to_last_top_idx.end()) {
LOG(FATAL) 1) {
// 如果要分叉(对应多个top)
const string& layer_name = layer_idx_to_layer_name[i]; //第i层的名称
const string& blob_name = layer_param->top(j); // 第j个top的blob名称
LayerParameter* split_layer_param = param_split->add_layer(); // 新建一层
const float loss_weight = top_idx_to_loss_weight[top_idx];
// 第i层的第j个top有的loss_weight
ConfigureSplitLayer(layer_name, blob_name, j, split_count,
loss_weight, split_layer_param);
if (loss_weight) {
layer_param->clear_loss_weight();
top_idx_to_bottom_split_idx[top_idx]++;
}
}
}
}
}