[AI] YOLO v3 darknet 소스 코드 분석 main은 어디있는가?
젯슨 나노의 설치 및 샘플 동작이 궁금하신 분들은 아래 링크에서 먼저 보고오셔도 좋습니다.
https://wendys.tistory.com/143
젯슨 나노의 기본 동작은 확인해봤다면 이제 입맛에 맞게 응용을 해서 사용을 하고 싶은 마음이 들게 됩니다.
소스 코드 분석시 필요한 코드를 찾는 능력도 중요하지만 필요한 코드를 찾기위해선 YOLO같은 콘솔 응용프로그램에서는 main부터 찾아가는게 편하기때문에 main code 위치를 알려드리겠습니다.
그렇다면 이제 darknet YOLO v3 소스를 마음껏 뜯어고칠 수 있도록 소스를 찾아가 봅시다.
darknet/Makefile
darknet을 다운받은 경로로 가서 Makefile을 확인하여 main이 포함되어있는 소스코드를 확인할 수 있으며, 그 외에도 빌드 옵션들의 설정을 변경하거나 확인할 수 있습니다.
GPU=1
CUDNN=1
CUDNN_HALF=0
OPENCV=1
AVX=0
OPENMP=0
LIBSO=0
ZED_CAMERA=0
...
VPATH=./src/
EXEC=darknet
OBJDIR=./obj/
ifeq ($(LIBSO), 1)
LIBNAMESO=libdarknet.so
APPNAMESO=uselib
endif
CC=gcc
CPP=g++
NVCC=nvcc
OPTS=-Ofast
LDFLAGS= -lm -pthread
COMMON= -Iinclude/ -I3rdparty/stb/include
CFLAGS=-Wall -Wfatal-errors -Wno-unused-result -Wno-unknown-pragmas -fPIC
...
Value | Description |
VPATH=./src/ | 소스파일 경로는 ./src/로 정의되어있다. |
EXEC=darknet | main source file 이름은 darknet.c 이다. |
OBJDIR=./obj/ | build시 생성되는 object 파일들은 해당 경로에 출력된다. |
위에서 확인할 수 있듯이 EXEC=darknet임을 확인하여 ./src/darknet.c파일에 main함수가 존재한다는 것을 알 수 있습니다. 만약 다른 곳으로 이동하더라도 Makefile 정보를 이용하여 main source file을 찾으면 됩니다.
darknet/src/darknet.c
main source code를 보면 알 수 있는 점 중 하나는 다양한 명령어에 의해 실제로 어떻게 동작하는지를 따라가 볼 수 있게 됩니다.
int main(int argc, char **argv)
{
#ifdef _DEBUG
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
int i;
for (i = 0; i < argc; ++i) {
if (!argv[i]) continue;
strip_args(argv[i]);
}
//test_resize("data/bad.jpg");
//test_box();
//test_convolutional_layer();
if(argc < 2){
fprintf(stderr, "usage: %s <function>\n", argv[0]);
return 0;
}
gpu_index = find_int_arg(argc, argv, "-i", 0);
if(find_arg(argc, argv, "-nogpu")) {
gpu_index = -1;
printf("\n Currently Darknet doesn't support -nogpu flag. If you want to use CPU - please compile Darknet with GPU=0 in the Makefile, or compile darknet_no_gpu.sln on Windows.\n");
exit(-1);
}
#ifndef GPU
gpu_index = -1;
#else
if(gpu_index >= 0){
cuda_set_device(gpu_index);
CHECK_CUDA(cudaSetDeviceFlags(cudaDeviceScheduleBlockingSync));
}
#endif
if (0 == strcmp(argv[1], "average")){
average(argc, argv);
} else if (0 == strcmp(argv[1], "yolo")){
run_yolo(argc, argv);
} else if (0 == strcmp(argv[1], "voxel")){
run_voxel(argc, argv);
} else if (0 == strcmp(argv[1], "super")){
run_super(argc, argv);
} else if (0 == strcmp(argv[1], "detector")){
run_detector(argc, argv);
} else if (0 == strcmp(argv[1], "detect")){
float thresh = find_float_arg(argc, argv, "-thresh", .24);
int ext_output = find_arg(argc, argv, "-ext_output");
char *filename = (argc > 4) ? argv[4]: 0;
test_detector("cfg/coco.data", argv[2], argv[3], filename, thresh, 0.5, 0, ext_output, 0, NULL, 0);
} else if (0 == strcmp(argv[1], "cifar")){
run_cifar(argc, argv);
} else if (0 == strcmp(argv[1], "go")){
run_go(argc, argv);
} else if (0 == strcmp(argv[1], "rnn")){
run_char_rnn(argc, argv);
} else if (0 == strcmp(argv[1], "vid")){
run_vid_rnn(argc, argv);
} else if (0 == strcmp(argv[1], "coco")){
run_coco(argc, argv);
} else if (0 == strcmp(argv[1], "classify")){
predict_classifier("cfg/imagenet1k.data", argv[2], argv[3], argv[4], 5);
} else if (0 == strcmp(argv[1], "classifier")){
run_classifier(argc, argv);
} else if (0 == strcmp(argv[1], "art")){
run_art(argc, argv);
} else if (0 == strcmp(argv[1], "tag")){
run_tag(argc, argv);
} else if (0 == strcmp(argv[1], "compare")){
run_compare(argc, argv);
} else if (0 == strcmp(argv[1], "dice")){
run_dice(argc, argv);
} else if (0 == strcmp(argv[1], "writing")){
run_writing(argc, argv);
} else if (0 == strcmp(argv[1], "3d")){
composite_3d(argv[2], argv[3], argv[4], (argc > 5) ? atof(argv[5]) : 0);
} else if (0 == strcmp(argv[1], "test")){
test_resize(argv[2]);
} else if (0 == strcmp(argv[1], "captcha")){
run_captcha(argc, argv);
} else if (0 == strcmp(argv[1], "nightmare")){
run_nightmare(argc, argv);
} else if (0 == strcmp(argv[1], "rgbgr")){
rgbgr_net(argv[2], argv[3], argv[4]);
} else if (0 == strcmp(argv[1], "reset")){
reset_normalize_net(argv[2], argv[3], argv[4]);
} else if (0 == strcmp(argv[1], "denormalize")){
denormalize_net(argv[2], argv[3], argv[4]);
} else if (0 == strcmp(argv[1], "statistics")){
statistics_net(argv[2], argv[3]);
} else if (0 == strcmp(argv[1], "normalize")){
normalize_net(argv[2], argv[3], argv[4]);
} else if (0 == strcmp(argv[1], "rescale")){
rescale_net(argv[2], argv[3], argv[4]);
} else if (0 == strcmp(argv[1], "ops")){
operations(argv[2]);
} else if (0 == strcmp(argv[1], "speed")){
speed(argv[2], (argc > 3 && argv[3]) ? atoi(argv[3]) : 0);
} else if (0 == strcmp(argv[1], "oneoff")){
oneoff(argv[2], argv[3], argv[4]);
} else if (0 == strcmp(argv[1], "partial")){
partial(argv[2], argv[3], argv[4], atoi(argv[5]));
} else if (0 == strcmp(argv[1], "average")){
average(argc, argv);
} else if (0 == strcmp(argv[1], "visualize")){
visualize(argv[2], (argc > 3) ? argv[3] : 0);
} else if (0 == strcmp(argv[1], "imtest")){
test_resize(argv[2]);
} else {
fprintf(stderr, "Not an option: %s\n", argv[1]);
}
return 0;
}
기본 샘플에 보게 되면 detect, detector를 이용한 명령어를 가장 많이 볼 수 있게 되며, 그 외에도 이렇게나 많은 명령어들이 존재하고 있습니다.
darknet YOLO detect, detector 무슨 차이?
darknet yolo sample을 돌려봤을 때 사용했던 명령어는 바로 detect입니다.
./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg
그렇다면 detect와 detector 과연 무슨 차이가 있을까요??
Command | Description |
detect | 단일 이미지, 또는 멀티 이미지 등에서 물체를 인식할 때 사용 |
detector | 웹캠, 비디오 등 동영상에서 물체를 인식할 때 사용 |
약간의 차이점이 존재하네요
그리고 코드에서 보면 알 수 있듯이 detect 명령어를 사용할 때는 조건을 추가할 수 있게 됩니다.
float thresh = find_float_arg(argc, argv, "-thresh", .24);
int ext_output = find_arg(argc, argv, "-ext_output");
char *filename = (argc > 4) ? argv[4]: 0;
test_detector("cfg/coco.data", argv[2], argv[3], filename, thresh, 0.5, 0, ext_output, 0, NULL, 0);
Command | Description |
-thresh |
YOLO v3의 임계치를 조정할 수 있습니다. 원래 YOLO는 25% 이상인 물체만 표시를 하게 되는데, 해당 옵션을 이용하여 0% 이상인 모든 물체를 표시하게 하거나, 50% 이상의 물체만 탐지를 하는 등의 설정이 가능합니다. |
-ext_output |
결과에 대해 상세한 정보를 표시하는 옵션 |
이런 명령어들의 사용법은 darknet 공식 홈페이지를 통해서도 알 수 있지만 현재 개발이 활발하게 진행 중인 AlexeyAB 링크에서 확인하는 게 좋습니다. 저는 AlexeyAB의 darknet 소스를 이용하고 있습니다.
https://github.com/AlexeyAB/darknet
더 다양한 명령어들은 직접 분석해보도록 합니다 :)
'⌨ DEVELOPMENT > AI' 카테고리의 다른 글
[AI] 젯슨 나노(Jetson Nano) 명령어 하나로 최대 성능으로 사용하기 (2) | 2019.12.14 |
---|---|
[AI] YOLO v3 darknet - 이미지 여러개 순차적으로 처리하기 (4) | 2019.12.09 |
[AI] jetson Nano GPU Architecture is sm=5.3 (0) | 2019.11.24 |
[AI] jetson nano SSH가 접속이 되지 않을때 ssh-keygen -A 한방으로! (0) | 2019.11.21 |
[AI] 젯슨 나노(Jetson Nano) darknet YOLO v3 설치 및 샘플 돌려보기 (20) | 2019.10.02 |
[AI] 젯슨 나노(Jetson Nano) MSTSC 원격 제어 설정하기 (XRDP) (3) | 2019.09.30 |
[AI] NVIDIA 젯슨 나노(Jetson Nano) OS 설치 및 초기화 (13) | 2019.09.30 |
[AI] 인공지능 초소형 컴퓨터 NVIDIA 젯슨 나노(Jetson Nano) 개발자 키트 사양 및 살펴보기 (1) | 2019.09.21 |
댓글
이 글 공유하기
다른 글
-
[AI] jetson Nano GPU Architecture is sm=5.3
[AI] jetson Nano GPU Architecture is sm=5.3
2019.11.24 -
[AI] jetson nano SSH가 접속이 되지 않을때 ssh-keygen -A 한방으로!
[AI] jetson nano SSH가 접속이 되지 않을때 ssh-keygen -A 한방으로!
2019.11.21 -
[AI] 젯슨 나노(Jetson Nano) darknet YOLO v3 설치 및 샘플 돌려보기
[AI] 젯슨 나노(Jetson Nano) darknet YOLO v3 설치 및 샘플 돌려보기
2019.10.02 -
[AI] 젯슨 나노(Jetson Nano) MSTSC 원격 제어 설정하기 (XRDP)
[AI] 젯슨 나노(Jetson Nano) MSTSC 원격 제어 설정하기 (XRDP)
2019.09.30