yolo 目标检测也已经被玩坏了,现在开始我的学习之路。
最简单的,先修改下网络的输出形式,传统的输出如下所示:
修改为如下所示的输出形式,和原来的没啥区别,主要是加如了“X”的效果,这个在src/image.c文件下实现。
好了,简单的开始后就是复杂的了。
先来解析下yolov3的源码:
yolov3 包含了多个不同的层,包括卷积层,池化层、残差网络等都是在cfg下预先定义好的,由YOLO源码的network 先读取网络,保存在net * 类中,还有再读取权重,然后开始计算。
yolov3 的算法流程由cfg 定义,parser.c中实现了这一文件的解析
network *parse_network_cfg(char *filename)
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;
不同的层会定义不同的操作,文件解析并将l.forward 定义为不同的操作。
数据保存再net * 中。
所以这个算法确实是非常的浪费内存,有过测试,这个算法起码需要2G的内存,要不说这个算法快呢?
然后大家就可以按照这个分支去看源码了,就没有那么麻烦了。
还有就是Makefile 的解析,应为要生成GPU的程序,记得修改为GPU=1。