이 영역을 누르면 첫 페이지로 이동
웬디의 기묘한 이야기 블로그의 첫 페이지로 이동

웬디의 기묘한 이야기

페이지 맨 위로 올라가기

웬디의 기묘한 이야기

C/C++ Windows Hooking 개발자의 블로그 입니다! 이곳은 개발 외에도 저의 취미들이 공유되는 기묘한 이야기가 펼쳐집니다.

[AI] YOLO v3 darknet 소스 코드 분석 main은 어디있는가?

  • 2019.11.18 22:52
  • ⌨ DEVELOPMENT/AI
반응형

젯슨 나노의 설치 및 샘플 동작이 궁금하신 분들은 아래 링크에서 먼저 보고오셔도 좋습니다.

 

https://wendys.tistory.com/143

 

[AI] 젯슨 나노(Jetson Nano) darknet YOLO v3 설치 및 샘플 돌려보기

젯슨 나노 (jetson nano) darknet 신경망 오픈소스 프로젝트 YOLO v3 설치하기 https://pjreddie.com/darknet/ Darknet: Open Source Neural Networks in C Nightmare Use Darknet's black magic to conjure ghost..

wendys.tistory.com

 

젯슨 나노의 기본 동작은 확인해봤다면 이제 입맛에 맞게 응용을 해서 사용을 하고 싶은 마음이 들게 됩니다.

소스 코드 분석시 필요한 코드를 찾는 능력도 중요하지만 필요한 코드를 찾기위해선 YOLO같은 콘솔 응용프로그램에서는 main부터 찾아가는게 편하기때문에 main code 위치를 알려드리겠습니다.

 

그렇다면 이제 darknet YOLO v3 소스를 마음껏 뜯어고칠 수 있도록 소스를 찾아가 봅시다.

 

https://pjreddie.com/media/files/papers/YOLOv3.pdf

 

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

 

AlexeyAB/darknet

Windows and Linux version of Darknet Yolo v3 & v2 Neural Networks for object detection (Tensor Cores are used) - AlexeyAB/darknet

github.com

더 다양한 명령어들은 직접 분석해보도록 합니다 :)

반응형
저작자표시 비영리 변경금지 (새창열림)

'⌨ 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

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • [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
다른 글 더 둘러보기

정보

웬디의 기묘한 이야기 블로그의 첫 페이지로 이동

웬디의 기묘한 이야기

  • 웬디의 기묘한 이야기의 첫 페이지로 이동

검색

메뉴

  • 홈
  • 태그
  • 방명록
  • 이야기

카테고리

  • 분류 전체보기 (204)
    • MY STORY (2)
    • 📸 WALKING WITH YOU (85)
      • 아이슬란드 신혼여행 이야기 (14)
      • 대한민국 구석구석 (62)
      • CONTAX N1 + T* 28-80mm (4)
      • SAMSUNG NX3000 (1)
      • 어느 멋진 날 (4)
    • ⌨ DEVELOPMENT (80)
      • BOOK:Review (1)
      • AI (13)
      • C++ (26)
      • Python (10)
      • WIndows Hooking (9)
      • Windows Kernel (3)
      • Design Pattern (3)
      • Debugging (9)
      • Tools (0)
      • Project (1)
      • Android (1)
      • 상업용 무료폰트 (4)
    • OS (4)
      • News (0)
      • Windows 일반 (4)
    • 모바일 (2)
      • 모바일 게임 (2)
    • 멘사 퍼즐 (9)
    • 생활 꿀 TIP (7)
      • 건강 (3)
      • 일상 (2)
    • 물생활 (8)
      • 골든볼 라미네지 롱핀 (8)
    • IT 기기 (2)
    • BLOG (4)
      • TISTORY BLOG TIP (3)

최근 글

인기 글

댓글

공지사항

아카이브

태그

  • c
  • 카페
  • AI
  • windbg
  • c++
  • 해외여행
  • 신혼여행
  • 아이슬란드

나의 외부 링크

  • kernel undocument api
  • 지구 관찰자의 일기
  • 지구와 지구곰

정보

WENDYS의 웬디의 기묘한 이야기

웬디의 기묘한 이야기

WENDYS

블로그 구독하기

  • 구독하기
  • RSS 피드

방문자

  • 전체 방문자
  • 오늘
  • 어제

티스토리

  • 티스토리 홈
  • 이 블로그 관리하기
  • 글쓰기
Powered by Tistory / Kakao. © WENDYS. Designed by Fraccino.

티스토리툴바