AlexeyAB
2018-04-03 1b2c70f82a9ec88c60bb277f9f5f0073c96691e7
Detection is accelerated by 7 percent (fused conv and batch_norm layers)
4 files modified
41 ■■■■■ changed files
src/demo.c 2 ●●● patch | view | raw | blame | history
src/detector.c 3 ●●●●● patch | view | raw | blame | history
src/network.c 35 ●●●●● patch | view | raw | blame | history
src/network.h 1 ●●●● patch | view | raw | blame | history
src/demo.c
@@ -148,7 +148,7 @@
        load_weights(&net, weightfile);
    }
    set_batch_network(&net, 1);
    fuse_conv_batchnorm(net);
    srand(2222222);
    if(filename){
src/detector.c
@@ -419,6 +419,7 @@
        load_weights(&net, weightfile);
    }
    set_batch_network(&net, 1);
    fuse_conv_batchnorm(net);
    srand(time(0));
    //list *plist = get_paths("data/coco_val_5k.list");
@@ -526,6 +527,7 @@
        load_weights(&net, weightfile);
    }
    set_batch_network(&net, 1);
    fuse_conv_batchnorm(net);
    srand(time(0));
    list *plist = get_paths(valid_images);
@@ -1022,6 +1024,7 @@
        load_weights(&net, weightfile);
    }
    set_batch_network(&net, 1);
    fuse_conv_batchnorm(net);
    srand(2222222);
    clock_t time;
    char buff[256];
src/network.c
@@ -748,3 +748,38 @@
    free(net.workspace);
#endif
}
void fuse_conv_batchnorm(network net)
{
    int j;
    for (j = 0; j < net.n; ++j) {
        layer *l = &net.layers[j];
        if (l->type == CONVOLUTIONAL) {
            printf(" Fuse Convolutional layer \t\t l->size = %d  \n", l->size);
            if (l->batch_normalize) {
                int f;
                for (f = 0; f < l->n; ++f)
                {
                    l->biases[f] = l->biases[f] - l->scales[f] * l->rolling_mean[f] / (sqrtf(l->rolling_variance[f]) + .000001f);
                    const size_t filter_size = l->size*l->size*l->c;
                    int i;
                    for (i = 0; i < filter_size; ++i) {
                        int w_index = f*filter_size + i;
                        l->weights[w_index] = l->weights[w_index] * l->scales[f] / (sqrtf(l->rolling_variance[f]) + .000001f);
                    }
                }
                l->batch_normalize = 0;
                push_convolutional_layer(*l);
            }
        }
        else {
            printf(" Skip layer: %d \n", l->type);
        }
    }
}
src/network.h
@@ -138,6 +138,7 @@
int get_network_nuisance(network net);
int get_network_background(network net);
void fuse_conv_batchnorm(network net);
#ifdef __cplusplus
}