zoukankan      html  css  js  c++  java
  • Darknet源码阅读notes

    darknet notes

    some functions

    char *basecfg(char *cfgfile)
    {
        char *c = cfgfile;
        char *next;
        while((next = strchr(c, '/')))
        {
            c = next+1;
        }
        c = copy_string(c);
        next = strchr(c, '.');
        if (next) *next = 0;
        return c;
    }

    C 库函数 char *strchr(const char *str, int c) 在参数 str 所指向的字符串中搜索第一次出现字符 c(一个无符号字符)的位置。返回的next实际上是指向c的指针,用%s打出来也就是c(包含)之后的字符串。while 当还有斜杠时,继续往后找,没有斜杠就退出,也就是指向最后一个斜杠。与点号匹配去后缀名。

    typedef struct network{
        int n;
        int batch;
        size_t *seen;
        int *t;
        float epoch;
        int subdivisions;
        layer *layers;
        float *output;
        learning_rate_policy policy;
    
        float learning_rate;
        float momentum;
        float decay;
        float gamma;
        float scale;
        float power;
        int time_steps;
        int step;
        int max_batches;
        float *scales;
        int   *steps;
        int num_steps;
        int burn_in;
    
        int adam;
        float B1;
        float B2;
        float eps;
    
        int inputs;
        int outputs;
        int truths;
        int notruth;
        int h, w, c;
        int max_crop;
        int min_crop;
        float max_ratio;
        float min_ratio;
        int center;
        float angle;
        float aspect;
        float exposure;
        float saturation;
        float hue;
        int random;
    
        int gpu_index;
        tree *hierarchy;
    
        float *input;
        float *truth;
        float *delta;
        float *workspace;
        int train;
        int index;
        float *cost;
        float clip;
    
    #ifdef GPU
        float *input_gpu;
        float *truth_gpu;
        float *delta_gpu;
        float *output_gpu;
    #endif
    
    } network;

    darknet.h中对network的定义。

    network *load_network(char *cfg, char *weights, int clear)
    {
        network *net = parse_network_cfg(cfg);
        if(weights && weights[0] != 0){
            load_weights(net, weights);
        }
        if(clear) (*net->seen) = 0;
        return net;
    }

    通过cfg文件和已有的权重加载网络模型。从cfg到网络的过程有函数parse_network_cfg实现。首先看如何读入cfg文件到list* 类型。

    list *read_cfg(char *filename)
    {
        FILE *file = fopen(filename, "r");
        if(file == 0) file_error(filename);
        char *line;
        int nu = 0;
        list *options = make_list();
        section *current = 0;
        while((line=fgetl(file)) != 0){
            ++ nu;
            strip(line);
            switch(line[0]){
                case '[':
                    current = malloc(sizeof(section));
                    list_insert(options, current);
                    current->options = make_list();
                    current->type = line;
                    break;
                case '':
                case '#':
                case ';':
                    free(line);
                    break;
                default:
                    if(!read_option(line, current->options)){
                        fprintf(stderr, "Config file error line %d, could parse: %s
    ", nu, line);
                        free(line);
                    }
                    break;
            }
        }
        fclose(file);
        return options;
    }

    可以看出,先判断每一行有没有内容。这里的read_cfg读到一个[ ]中括号,就开一块内存,并且把它加入到现有的options的list中。遇到反斜杠0,#或;都直接break。如果不是按照规则写的则报错。返回options。

    下面再看parse_network_cfg

    network *parse_network_cfg(char *filename)
    {
        list *sections = read_cfg(filename);
        node *n = sections->front;
        if(!n) error("Config file has no sections");
        network *net = make_network(sections->size - 1);
        net->gpu_index = gpu_index;
        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);
        fprintf(stderr, "layer     filters    size              input                output
    ");
        while(n){
            params.index = count;
            fprintf(stderr, "%5d ", count);
            s = (section *)n->val;
            options = s->options;
            layer l = {0};
            LAYER_TYPE lt = string_to_layer_type(s->type);
            if(lt == CONVOLUTIONAL){
                l = parse_convolutional(options, params);
            }else if(lt == DECONVOLUTIONAL){
                l = parse_deconvolutional(options, params);
            }else if(lt == LOCAL){
                l = parse_local(options, params);
            }else if(lt == ACTIVE){
                l = parse_activation(options, params);
            }else if(lt == LOGXENT){
                l = parse_logistic(options, params);
            }else if(lt == L2NORM){
                l = parse_l2norm(options, params);
            }else if(lt == RNN){
                l = parse_rnn(options, params);
            }else if(lt == GRU){
                l = parse_gru(options, params);
            }else if (lt == LSTM) {
                l = parse_lstm(options, params);
            }else if(lt == CRNN){
                l = parse_crnn(options, params);
            }else if(lt == CONNECTED){
                l = parse_connected(options, params);
            }else if(lt == CROP){
                l = parse_crop(options, params);
            }else if(lt == COST){
                l = parse_cost(options, params);
            }else if(lt == REGION){
                l = parse_region(options, params);
            }else if(lt == YOLO){
                l = parse_yolo(options, params);
            }else if(lt == DETECTION){
                l = parse_detection(options, params);
            }else if(lt == SOFTMAX){
                l = parse_softmax(options, params);
                net->hierarchy = l.softmax_tree;
            }else if(lt == NORMALIZATION){
                l = parse_normalization(options, params);
            }else if(lt == BATCHNORM){
                l = parse_batchnorm(options, params);
            }else if(lt == MAXPOOL){
                l = parse_maxpool(options, params);
            }else if(lt == REORG){
                l = parse_reorg(options, params);
            }else if(lt == AVGPOOL){
                l = parse_avgpool(options, params);
            }else if(lt == ROUTE){
                l = parse_route(options, params, net);
            }else if(lt == UPSAMPLE){
                l = parse_upsample(options, params, net);
            }else if(lt == SHORTCUT){
                l = parse_shortcut(options, params, net);
            }else if(lt == DROPOUT){
                l = parse_dropout(options, params);
                l.output = net->layers[count-1].output;
                l.delta = net->layers[count-1].delta;
    #ifdef GPU
                l.output_gpu = net->layers[count-1].output_gpu;
                l.delta_gpu = net->layers[count-1].delta_gpu;
    #endif
            }else{
                fprintf(stderr, "Type not recognized: %s
    ", s->type);
            }
            l.clip = net->clip;
            l.truth = option_find_int_quiet(options, "truth", 0);
            l.onlyforward = option_find_int_quiet(options, "onlyforward", 0);
            l.stopbackward = option_find_int_quiet(options, "stopbackward", 0);
            l.dontsave = option_find_int_quiet(options, "dontsave", 0);
            l.dontload = option_find_int_quiet(options, "dontload", 0);
            l.dontloadscales = option_find_int_quiet(options, "dontloadscales", 0);
            l.learning_rate_scale = option_find_float_quiet(options, "learning_rate", 1);
            l.smooth = option_find_float_quiet(options, "smooth", 0);
            option_unused(options);
            net->layers[count] = l;
            if (l.workspace_size > workspace_size) workspace_size = l.workspace_size;
            free_section(s);
            n = n->next;
            ++count;
            if(n){
                params.h = l.out_h;
                params.w = l.out_w;
                params.c = l.out_c;
                params.inputs = l.outputs;
            }
        }
        free_list(sections);
        layer out = get_network_output_layer(net);
        net->outputs = out.outputs;
        net->truths = out.outputs;
        if(net->layers[net->n-1].truths) net->truths = net->layers[net->n-1].truths;
        net->output = out.output;
        net->input = calloc(net->inputs*net->batch, sizeof(float));
        net->truth = calloc(net->truths*net->batch, sizeof(float));
    #ifdef GPU
        net->output_gpu = out.output_gpu;
        net->input_gpu = cuda_make_array(net->input, net->inputs*net->batch);
        net->truth_gpu = cuda_make_array(net->truth, net->truths*net->batch);
    #endif
        if(workspace_size){
            //printf("%ld
    ", workspace_size);
    #ifdef GPU
            if(gpu_index >= 0){
                net->workspace = cuda_make_array(0, (workspace_size-1)/sizeof(float)+1);
            }else {
                net->workspace = calloc(1, workspace_size);
            }
    #else
            net->workspace = calloc(1, workspace_size);
    #endif
        }
        return net;
    }
    

    主要内容就是通过读出来的每个LAYERTYPE调用不同的parse某种layer 的函数,生成网络结构,并且把参数如batch等传进net。举栗子:parse_convolutional如下:

    convolutional_layer parse_convolutional(list *options, size_params params)
    {
        int n = option_find_int(options, "filters",1);
        int size = option_find_int(options, "size",1);
        int stride = option_find_int(options, "stride",1);
        int pad = option_find_int_quiet(options, "pad",0);
        int padding = option_find_int_quiet(options, "padding",0);
        int groups = option_find_int_quiet(options, "groups", 1);
        if(pad) padding = size/2;
    
        char *activation_s = option_find_str(options, "activation", "logistic");
        ACTIVATION activation = get_activation(activation_s);
    
        int batch,h,w,c;
        h = params.h;
        w = params.w;
        c = params.c;
        batch=params.batch;
        if(!(h && w && c)) error("Layer before convolutional layer must output image.");
        int batch_normalize = option_find_int_quiet(options, "batch_normalize", 0);
        int binary = option_find_int_quiet(options, "binary", 0);
        int xnor = option_find_int_quiet(options, "xnor", 0);
    
        convolutional_layer layer = make_convolutional_layer(batch,h,w,c,n,groups,size,stride,padding,activation, batch_normalize, binary, xnor, params.net->adam);
        layer.flipped = option_find_int_quiet(options, "flipped", 0);
        layer.dot = option_find_float_quiet(options, "dot", 0);
    
        return layer;
    }
    

    (to be continued)

    2018年7月11日17:49:57

  • 相关阅读:
    Ubuntu16.04上安装搜狗输入法
    RAM的分类
    解耦技巧——依赖注入!
    傻瓜式学Python3——列表
    Java Builder 模式,你搞懂了么?
    String 源码浅析(一)
    线上CPU100%?看看这篇是怎么排查的!
    生物医学工程SCI期刊投稿(转)
    免费下载文献
    泰山攻略
  • 原文地址:https://www.cnblogs.com/morikokyuro/p/13256716.html
Copyright © 2011-2022 走看看