Darknet - Custom Layer
Darknet - Custom Layer
Note: This post is based on AlexeyAB/darknet version, the procedure of pjreddie/darknet version may differ slightly (have not tried, maybe identical).
8 steps to build your own deep learning lego module in Darknet:
-
Define LAYER_TYPE
Add LAYER_TYPE for your custom layer inlayer.h
typedef enum { // ... CUSTOM; } LAYER_TYPE;
-
Define layer string
Add layer string for your custom layer inparser.c
LAYER_TYPE string_to_layer_type(char * type) { // ... if (strcmp(type, "[custom]")==0) return CUSTOM; }
Then darknet would be able to recognize your custom layer in cfg file:
[net] #... [custom] #...
-
Implement your custom layer:
custom_layer.c
andcustom_layer.h
Should contain at least 4 functions:layer make_custom_layer(int batch, int w, int h, .....); void forward_custom_layer(const layer l, network_state state); void backward_custom_layer(const layer l, network_state state); void resize_custom_layer(layer *l, int w, int h);
(optional) If you want to train it with GPU, implement these:
#ifdef GPU void forward_custom_layer_gpu(const layer l, network_state state); void backward_custom_layer_gpu(const layer l, network_state state); #endif
-
In
parser.c
Include source file of your custom layer(to use
make_custom_layer()
):#include "custom_layer.h"
Implement the parse function:
layer parse_custom(list *options, size_params params) { int param1 = option_find_int(options, "param1", 1); //... layer l = make_custom_layer(params.batch, params.w, params.h, param1, ...); l.param2 = option_find_float(options, "param2", .1); //... return l; }
Add your parse function in
parse_network_cfg_custom()
:network parse_network_cfg_custom(char *filename, int batch) { //... while(n){ //... LAYER_TYPE lt = string_to_layer_type(s->type); if(lt == CONVOLUTIONAL){ l = parse_convolutional(options, params); }else if(lt == CUSTOM){ l = parse_custom(options, params); } } //... return net; }
-
In
network.c
Include source file of your custom layer(to use
resize_custom_layer()
):#include "custom_layer.h"
Modify
int resize_network(network *net, int w, int h)
function:int resize_network(network *net, int w, int h) { //... for (i = 0; i < net->n; ++i){ layer l = net->layers[i]; if(l.type == CONVOLUTIONAL){ resize_convolutional_layer(&l, w, h); }else if(l.type == CUSTOM){ resize_custom_layer(&l, w, h); }
-
[optional] If your custom layer is used to produce results(like YOLO, REGION or DETECTION):
Implement
custom_num_detections()
andget_custom_detections()
incustom_layer.c
, then modify 2 functions innetwork.c
(to count the detections and get the detections):int num_detections(network *net, float thresh) { int i; int s = 0; for (i = 0; i < net->n; ++i) { if (l.type == CUSTOM) { s += custom_num_detections(l, thresh); } //... } return s; } void fill_network_boxes(network *net, int w, int h, float thresh, float hier, int *map, int relative, detection *dets, int letter) { int prev_classes = -1; int j; for (j = 0; j < net->n; ++j) { layer l = net->layers[j]; if (l.type == CUSTOM){ int count = get_custom_detections(...); //... } //... } }
-
Add
custom_layer.c
andcustom_layer.h
in your Visual Studio Solutionbuild/darknet.sln
Or add
custom_layer.o
in yourMakefile
-
Rebuild your project
Post cover image from Lego Store | Copenhagen