0. Introduction
공식 사이트에 있는 아래의 명령을 파고 들어가 보는 것으로 시작을 해봅니다.
./darknet detector test cfg/coco.data cfg/yolov3.cfg yolov3.weights data/dog.jpg
- 실행 파일(darknet.exe)의 시작 지점은 당연 main입니다. 차례차례 들어가 봅니다.
- main(example/darknet.c) -> run_detector(src/detector.c) -> test_detector(src/detector.c) 함수가 나타납니다.
- test_detector 함수의 아래와 같은 코드로 인해서, 위의 인자는 아래의 각 (포인터) 변수가 가리키게 됩니다.
포인터 변수 | 가리키는 인자(Argument) |
char *datacfg = argv[3]; | cfg/coco.data |
char *cfg = argv[4]; | cfg/yolov3.cfg |
char *weights = (argc > 5) ? argv[5] : 0; | yolov3.weights |
char *filename = (argc > 6) ? argv[6] : 0; | data/dog.jpg |
- 본인이 본 코드 분석을 통해 알고자 하는 것은 다음과 같습니다.
1. 각 데이터는 어떻게 준비가 되어 있어야 하며
2. 학습은 어떻게 이루어 지고, 가중치는 어떤 방식으로 .weight파일에 저장이 되는지
3. .cfg 파일은 어떤 정보를 담고 있는지
4. 최종적으로 이미지 데이터(.jpg)가 어떻게 학습된 가중치에 의해서 추론이 되어 지는지
시간이 걸리겠지만, 핵심 적인 부분 위주로 조금씩 포스팅 해볼 생각입니다.
본인도 C 언어를 오래 했지만, 이렇게 방대한 분량을 혼자서 작업했다니 저자에게 경의로움을 느낍니다.
1. test_detector 함수 개괄
- 코드를 먼저 살펴 봅니다. 주요 함수를 파악해 봅니다.
- test_detector 함수에서 가장 앞의 4개 인자에는 앞에서 설명한 값이 들어갑니다.
- 즉, 아래와 같이 읽어 들이게 됩니다.
list *options = read_data_cfg("cfg/coco.data")
network *net = load_network("cfg/yolov3.cfg", "yolov3.weights", 0)
image im = load_image_color("data/dog.jpg", 0, 0)
- 따라서, read_data_cfg, load_network, load_image_color 이 세개 함수를 살펴볼 필요가 있을 것입니다.
- 그리고, image, layer 의 자료구조도 같이 살펴볼 필요가 있을 것 같습니다.
- 추론 부분에서 쓰이는 함수 4가지도 같이 살펴볼 것입니다. 즉, 추가로 살펴볼 함수 4개는 아래와 같습니다.
- network_predict, get_network_boxes, do_nms_sort, draw_detections
※ 본인이 개인적으로 궁금한 부분은 어떻게 가중치를 읽어와서 추론을 하는지 이므로 음영으로 칠한 두개 함수(load_network, network_predict)를 조금더 중점적으로 볼듯 합니다.
void test_detector(char *datacfg, char *cfgfile, char *weightfile, char *filename, float thresh, float hier_thresh, char *outfile, int fullscreen)
{
list *options = read_data_cfg(datacfg);
char *name_list = option_find_str(options, "names", "data/names.list");
char **names = get_labels(name_list);
image **alphabet = load_alphabet();
network *net = load_network(cfgfile, weightfile, 0);
set_batch_network(net, 1);
srand(2222222);
double time;
char buff[256];
char *input = buff;
float nms=.45;
while(1){
if(filename){
strncpy(input, filename, 256);
} else {
printf("Enter Image Path: ");
fflush(stdout);
input = fgets(input, 256, stdin);
if(!input) return;
strtok(input, "\n");
}
image im = load_image_color(input,0,0);
image sized = letterbox_image(im, net->w, net->h);
//image sized = resize_image(im, net->w, net->h);
//image sized2 = resize_max(im, net->w);
//image sized = crop_image(sized2, -((net->w - sized2.w)/2), -((net->h - sized2.h)/2), net->w, net->h);
//resize_network(net, sized.w, sized.h);
layer l = net->layers[net->n-1];
float *X = sized.data;
time=what_time_is_it_now();
network_predict(net, X);
printf("%s: Predicted in %f seconds.\n", input, what_time_is_it_now()-time);
int nboxes = 0;
detection *dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, 0, 1, &nboxes);
//printf("%d\n", nboxes);
//if (nms) do_nms_obj(boxes, probs, l.w*l.h*l.n, l.classes, nms);
if (nms) do_nms_sort(dets, nboxes, l.classes, nms);
draw_detections(im, dets, nboxes, thresh, names, alphabet, l.classes);
free_detections(dets, nboxes);
if(outfile){
save_image(im, outfile);
}
else{
save_image(im, "predictions");
#ifdef OPENCV
make_window("predictions", 512, 512, 0);
show_image(im, "predictions", 0);
#endif
}
free_image(im);
free_image(sized);
if (filename) break;
}
}
'Code Review' 카테고리의 다른 글
Mitigating the Effect of Incidental Correlations on Part-based Learning (0) | 2024.01.09 |
---|---|
Test Title (0) | 2024.01.09 |