darknet源码中的cfg文件读取由函数parse_network_cfg(cfgfile)中的read_cfg(file)函数搞定。
如下代码所示,最终解析后的属性和参数保存于section:
network parse_network_cfg(char *filename)
{
// 从神经网络结构参数文件中读入所有神经网络层的结构参数,
// 存储到sections中,
// sections的每个node包含一层神经网络的所有结构参数
list *sections = read_cfg(filename);
具体来说每一层(cfg中的每一层)都保存在结构体section中:
定义于src/parser.c
typedef struct{
char *type;//保存了cfg中层的名字
list *options;//保存了当前层对应的参数
}section;
而对应层的参数主要用到的结构是list结构:
定义于src/list.c文件中:
list *make_list()
{
list *l = malloc(sizeof(list));
l->size = 0;
l->front = 0;
l->back = 0;
return l;
}
主要流程为:
1. 读取type流程
parse_network_cfg(cfgfile)—>read_cfg(file)—>list_insert(sections, current)
2. 读取对应type下的属性和数据
parse_network_cfg(cfgfile)—>read_cfg(file)—>read_option–>option_insert—>list_insert
读取type流程代码
1.0 src/parser.c/parese_network_cfg
network parse_network_cfg(char *filename)
{
// 从神经网络结构参数文件中读入所有神经网络层的结构参数,存储到sections中,
// sections的每个node包含一层神经网络的所有结构参数
list *sections = read_cfg(filename);
// 获取sections的第一个节点,可以查看一下cfg/***.cfg文件,其实第一块参数(以[net]开头)不是某层神经网络的参数,
// 而是关于整个网络的一些通用参数,比如学习率,衰减率,输入图像宽高,batch大小等,
// 具体的关于某个网络层的参数是从第二块开始的,如[convolutional],[maxpool]...,
// 这些层并没有编号,只说明了层的属性,但层的参数都是按顺序在文件中排好的,读入时,
// sections链表上的顺序就是文件中的排列顺序。
node *n = sections->front;
if(!n) error("Config file has no sections");
// 创建网络结构并动态分配内存:输入网络层数为sections->size - 1,sections的第一段不是网络层,而是通用网络参数
network net = make_network(sections->size - 1);
// 所用显卡的卡号(gpu_index在cuda.c中用extern关键字声明)
// 在调用parse_network_cfg()之前,使用了cuda_set_device()设置了gpu_index的值号为当前活跃GPU卡号
net.gpu_index = gpu_index;
// size_params结构体元素不含指针变量
size_params params;
// 提取
section *s = (section *)n->val;
list *options = s->options;
if(!is_network(s)) error("First section must be [net] or [network]");
parse_net_options(options, &net);
params.h = net.h;
params.w = net.w;
params.c = net.c;
params.inputs = net.inputs;
params.batch = net.batch;
params.time_steps = net.time_steps;
params.net = net;
size_t workspace_size = 0;
n = n->next;
int count = 0;
free_section(s);
// 此处stderr不是错误提示,而是输出结果提示,提示网络结构
fprintf(stderr, "layer filters size input output\n");
w