본문 바로가기

IT/Deeplearning

[Object Detection / Deeplearning ] YOLO Darknet v2 - [1]

이번 포스팅에서는 YOLO Darknet version2의 구성에 대해서 포스팅하겠습니다.

YOLO Darknet이 어떤것인지에 대한 설명은 않겠습니다.




1. YOLO Darknet


YOLO Darknet의 홈페이지 및 깃허브 코드는 아래에서 확인하실 수 있습니다.


YOLO Darknet Github


YOLO Darknet 디렉토리 계층


Darknet
.
├── cfg
├── data
├── examples
├── include
├── LICENSE
├── LICENSE.fuck
├── LICENSE.gen
├── LICENSE.gpl
├── LICENSE.meta
├── LICENSE.mit
├── LICENSE.v1
├── Makefile
├── python
├── README.md
├── scripts
└── src


2. cfg

cfg 폴더를 열어보면 .cfg 확장자를 가진 여러 파일들을 확인할 수 있습니다.

여기서 cfg파일을 하나 열어서 확인해보면, DIGITS과 유사한 txt파일임을 확인할 수 있습니다.


# : 일종의 주석으로 사용됩니다.

   : 상단에 Testing과 Training이 주석으로 되어있으면서 Training부 하단에 batch와 subdivisions가 주석되어있는데

     학습 시킬 때는, Testing의 batch와 subdivisions를 주석 처리해주시고, Training부의 주석을 해제해주시면 됩니다.


height / width / channels : Input Image의 width, height, channel의 수를 의미합니다. 학습시 및 테스트 시에 Darknet에서 

                                          해당 파라미터에 맞춰서 OpenCV 혹은 STB 라이브러리에서 Resize를 해서 Input에 넣어줍니다.


그 외의 기타 파라미터들이 있지만, Data Augmentation에 대한 파라미터 및 Object Detection을 위한 기타 파라미터이므로 

이에 대한 설명을 생략하도록 하겠습니다.


Darknet은 딥러닝 C 프레임워크이기 때문에 코드상에서 지원되는 기능이라면 cfg의 변경만으로 본인만의 모델을 만들어서 

학습 및 테스트를 할 수 있게 만들어져있습니다.


yolo-voc.cfg

[net]
# Testing
batch=1
subdivisions=1
# Training
# batch=64
# subdivisions=8
height=416
width=416
channels=3
momentum=0.9
decay=0.0005
angle=0
saturation = 1.5
exposure = 1.5
hue=.1

learning_rate=0.001
burn_in=1000
max_batches = 80200
policy=steps
steps=40000,60000
scales=.1,.1

[convolutional]
batch_normalize=1
filters=32
size=3
stride=1
pad=1
activation=leaky

[maxpool]
size=2
stride=2

[convolutional]
batch_normalize=1
filters=64
size=3
stride=1
pad=1
activation=leaky

[maxpool]
size=2
stride=2

[convolutional]
batch_normalize=1
filters=128
size=3
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=64
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=128
size=3
stride=1
pad=1
activation=leaky

[maxpool]
size=2
stride=2

[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky

[maxpool]
size=2
stride=2

[convolutional]
batch_normalize=1
filters=512
size=3
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=512
size=3
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=512
size=3
stride=1
pad=1
activation=leaky

[maxpool]
size=2
stride=2

[convolutional]
batch_normalize=1
filters=1024
size=3
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=1024
size=3
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=leaky

[convolutional]
batch_normalize=1
filters=1024
size=3
stride=1
pad=1
activation=leaky


#######

[convolutional]
batch_normalize=1
size=3
stride=1
pad=1
filters=1024
activation=leaky

[convolutional]
batch_normalize=1
size=3
stride=1
pad=1
filters=1024
activation=leaky

[route]
layers=-9

[convolutional]
batch_normalize=1
size=1
stride=1
pad=1
filters=64
activation=leaky

[reorg]
stride=2

[route]
layers=-1,-4

[convolutional]
batch_normalize=1
size=3
stride=1
pad=1
filters=1024
activation=leaky

[convolutional]
size=1
stride=1
pad=1
filters=125
activation=linear


[region]
anchors =  1.3221, 1.73145, 3.19275, 4.00944, 5.05587, 8.09892, 9.47112, 4.84053, 11.2364, 10.0071
bias_match=1
classes=20
coords=4
num=5
softmax=1
jitter=.3
rescore=1

object_scale=5
noobject_scale=1
class_scale=1
coord_scale=1

absolute=1
thresh = .6
random=1


3. data

data 폴더에는 Darknet에서 Object Detection시 박스를 그려주고 label을 표시해주기 위한 폰트와 .names확장자를 갖는 

label list, 테스트 이미지들이 있습니다. 아래는 data 폴더 내부 계층입니다. labels라는 폴더 안에 각종 폰트들이 들어가있습니다.

그리고 coco.names를 대표적으로 살펴보겠습니다. coco.names는 coco 데이터셋의 label list입니다. 

보시면 80개의 클래스 이름들이 모두 적혀있는 것을 확인할 수 있습니다.


data
.
├── 9k.labels
├── 9k.names
├── 9k.tree
├── coco9k.map
├── coco.names
├── dog.jpg
├── eagle.jpg
├── giraffe.jpg
├── goal.txt
├── horses.jpg
├── imagenet.labels.list
├── imagenet.shortnames.list
├── inet9k.map
├── labels
├── person.jpg
├── scream.jpg
└── voc.names



coco.names


person
bicycle
car
motorbike
aeroplane
bus
train
truck
boat
traffic light
fire hydrant
stop sign
parking meter
bench
bird
cat
dog
horse
sheep
cow
elephant
bear
zebra
giraffe
backpack
umbrella
handbag
tie
suitcase
frisbee
skis
snowboard
sports ball
kite
baseball bat
baseball glove
skateboard
surfboard
tennis racket
bottle
wine glass
cup
fork
knife
spoon
bowl
banana
apple
sandwich
orange
broccoli
carrot
hot dog
pizza
donut
cake
chair
sofa
pottedplant
bed
diningtable
toilet
tvmonitor
laptop
mouse
remote
keyboard
cell phone
microwave
oven
toaster
sink
refrigerator
book
clock
vase
scissors
teddy bear
hair drier
toothbrush


4. examples

examples폴더에는 darknet에서 지원하는 여러 모델들의 메인 함수들이 있습니다.

해당 c파일들은 모두 특정 함수들에 대한 파일이며, 추후에 darknet을 실행할 때, darknet 바로 뒤에 함수 argument로 들어가게됩니다.


examples
.
├── art.c
├── attention.c
├── captcha.c
├── cifar.c
├── classifier.c
├── coco.c
├── darknet.c
├── detector.c
├── detector.py
├── detector-scipy-opencv.py
├── dice.c
├── go.c
├── lsd.c
├── nightmare.c
├── regressor.c
├── rnn.c
├── rnn_vid.c
├── segmenter.c
├── super.c
├── swag.c
├── tag.c
├── voxel.c
├── writing.c
└── yolo.c


5. include

Include 폴더에는 darknet.h 하나만 있습니다.

darknet.h안에는 darknet에서 사용되는 모든 구조체들과 전역 함수 및 변수들이 선언되어있습니다.

include
.
└── darknet.h


6. python

해당 폴더는 제가 사용해보지 않는 부분인데, Darknet을 Python에서 사용가능하게 랩핑해놓은 예제 코드이지 않을까 추측하고 있습니다.

python
.
├── darknet.py
└── proverbot.py


7. scripts

scripts 폴더 안에는 VOC Fascal 포맷이라던가, 여러가지 Object detection 및 다른 공개된 데이터 셋들의 

label format을 yolo darknet안에서 사용할 수 있는 labeling format으로 변환해주는 script파일들이 있습니다.

scripts
.
├── dice_label.sh
├── gen_tactic.sh
├── get_coco_dataset.sh
├── imagenet_label.sh
└── voc_label.py


8. src

src 폴더에는 darknet에 사용되는 코드들이 모두 모여져 있습니다.

nvidia GPU에서 병렬처리를 위한 .cu 파일부터 시작해서 forawrd, backpropagation코드를 위한 파일 등 기타 코드들이 모두 있습니다.


src
.
├── activation_kernels.cu
├── activation_layer.c
├── activation_layer.h
├── activations.c
├── activations.h
├── avgpool_layer.c
├── avgpool_layer.h
├── avgpool_layer_kernels.cu
├── batchnorm_layer.c
├── batchnorm_layer.h
├── blas.c
├── blas.h
├── blas_kernels.cu
├── box.c
├── box.h
├── classifier.h
├── col2im.c
├── col2im.h
├── col2im_kernels.cu
├── compare.c
├── connected_layer.c
├── connected_layer.h
├── convolutional_kernels.cu
├── convolutional_layer.c
├── convolutional_layer.h
├── cost_layer.c
├── cost_layer.h
├── crnn_layer.c
├── crnn_layer.h
├── crop_layer.c
├── crop_layer.h
├── crop_layer_kernels.cu
├── cuda.c
├── cuda.h
├── data.c
├── data.h
├── deconvolutional_kernels.cu
├── deconvolutional_layer.c
├── deconvolutional_layer.h
├── demo.c
├── demo.h
├── detection_layer.c
├── detection_layer.h
├── dropout_layer.c
├── dropout_layer.h
├── dropout_layer_kernels.cu
├── gemm.c
├── gemm.h
├── gru_layer.c
├── gru_layer.h
├── im2col.c
├── im2col.h
├── im2col_kernels.cu
├── image.c
├── image.h
├── layer.c
├── layer.h
├── list.c
├── list.h
├── local_layer.c
├── local_layer.h
├── lstm_layer.c
├── lstm_layer.h
├── matrix.c
├── matrix.h
├── maxpool_layer.c
├── maxpool_layer.h
├── maxpool_layer_kernels.cu
├── network.c
├── network.h
├── normalization_layer.c
├── normalization_layer.h
├── option_list.c
├── option_list.h
├── parser.c
├── parser.h
├── region_layer.c
├── region_layer.h
├── reorg_layer.c
├── reorg_layer.h
├── rnn_layer.c
├── rnn_layer.h
├── route_layer.c
├── route_layer.h
├── shortcut_layer.c
├── shortcut_layer.h
├── softmax_layer.c
├── softmax_layer.h
├── stb_image.h
├── stb_image_write.h
├── tree.c
├── tree.h
├── utils.c
└── utils.h


9. Makefile

Makefile은 YOLO Darknet을 리눅스에서 make할 때, 쓰이는 파일이며, 구성은 다음과 같습니다.

주로 compile 옵션 및 커스텀 옵션들 (GPU 사용 / OpenCV 사용 / cuDNN 사용 / OpenMP 사용 / Debug 모드 사용)들이 적혀있습니다.

GPU=0
CUDNN=0
OPENCV=0
OPENMP=0
DEBUG=0

ARCH= -gencode arch=compute_30,code=sm_30 \
      -gencode arch=compute_35,code=sm_35 \
      -gencode arch=compute_50,code=[sm_50,compute_50] \
      -gencode arch=compute_52,code=[sm_52,compute_52]
#      -gencode arch=compute_20,code=[sm_20,sm_21] \ This one is deprecated?

# This is what I use, uncomment if you know your arch and want to specify
# ARCH= -gencode arch=compute_52,code=compute_52

VPATH=./src/:./examples
SLIB=libdarknet.so
ALIB=libdarknet.a
EXEC=darknet
OBJDIR=./obj/

CC=gcc
NVCC=nvcc 
AR=ar
ARFLAGS=rcs
OPTS=-Ofast
LDFLAGS= -lm -pthread 
COMMON= -Iinclude/ -Isrc/
CFLAGS=-Wall -Wno-unknown-pragmas -Wfatal-errors -fPIC

ifeq ($(OPENMP), 1) 
CFLAGS+= -fopenmp
endif

ifeq ($(DEBUG), 1) 
OPTS=-O0 -g
endif

CFLAGS+=$(OPTS)

ifeq ($(OPENCV), 1) 
COMMON+= -DOPENCV
CFLAGS+= -DOPENCV
LDFLAGS+= `pkg-config --libs opencv` 
COMMON+= `pkg-config --cflags opencv` 
endif

ifeq ($(GPU), 1) 
COMMON+= -DGPU -I/usr/local/cuda/include/
CFLAGS+= -DGPU
LDFLAGS+= -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand
endif

ifeq ($(CUDNN), 1) 
COMMON+= -DCUDNN 
CFLAGS+= -DCUDNN
LDFLAGS+= -lcudnn
endif

OBJ=gemm.o utils.o cuda.o deconvolutional_layer.o convolutional_layer.o list.o image.o activations.o im2col.o col2im.o blas.o crop_layer.o dropout_layer.o maxpool_layer.o softmax_layer.o data.o matrix.o network.o connected_layer.o cost_layer.o parser.o option_list.o detection_layer.o route_layer.o box.o normalization_layer.o avgpool_layer.o layer.o local_layer.o shortcut_layer.o activation_layer.o rnn_layer.o gru_layer.o crnn_layer.o demo.o batchnorm_layer.o region_layer.o reorg_layer.o tree.o  lstm_layer.o
EXECOBJA=captcha.o lsd.o super.o art.o tag.o cifar.o go.o rnn.o segmenter.o regressor.o classifier.o coco.o yolo.o detector.o nightmare.o attention.o darknet.o
ifeq ($(GPU), 1) 
LDFLAGS+= -lstdc++ 
OBJ+=convolutional_kernels.o deconvolutional_kernels.o activation_kernels.o im2col_kernels.o col2im_kernels.o blas_kernels.o crop_layer_kernels.o dropout_layer_kernels.o maxpool_layer_kernels.o avgpool_layer_kernels.o
endif

EXECOBJ = $(addprefix $(OBJDIR), $(EXECOBJA))
OBJS = $(addprefix $(OBJDIR), $(OBJ))
DEPS = $(wildcard src/*.h) Makefile include/darknet.h

#all: obj backup results $(SLIB) $(ALIB) $(EXEC)
all: obj  results $(SLIB) $(ALIB) $(EXEC)


$(EXEC): $(EXECOBJ) $(ALIB)
	$(CC) $(COMMON) $(CFLAGS) $^ -o $@ $(LDFLAGS) $(ALIB)

$(ALIB): $(OBJS)
	$(AR) $(ARFLAGS) $@ $^

$(SLIB): $(OBJS)
	$(CC) $(CFLAGS) -shared $^ -o $@ $(LDFLAGS)

$(OBJDIR)%.o: %.c $(DEPS)
	$(CC) $(COMMON) $(CFLAGS) -c $< -o $@

$(OBJDIR)%.o: %.cu $(DEPS)
	$(NVCC) $(ARCH) $(COMMON) --compiler-options "$(CFLAGS)" -c $< -o $@

obj:
	mkdir -p obj
backup:
	mkdir -p backup
results:
	mkdir -p results

.PHONY: clean

clean:
	rm -rf $(OBJS) $(SLIB) $(ALIB) $(EXEC) $(EXECOBJ)



이번 포스팅에서는 YOLO Darknet의 구성에 대해서 포스팅하였습니다.

다음 포스팅에서는 YOLO Darknet의 설치와 기본 사용방법에 대해서 포스팅하도록 하겠습니다.