본문 바로가기
Deep Learning

YOLOv3를 활용한 전동킥보드 헬멧 미착용 감시 시스템 만들기 3

by 자라자 2021. 5. 13.

연구 기간별 수행 내용

 

- 32~ 39: 팀 빌딩 및 연구실 컨택

 

전자공학과 지능정보처리 연구실 교수님께 지도받게 되었다. 초기 연구 주제는 음식의 칼로리를 계산해주는 AI를 만드는 것이었다. 음식 사진을 찍으면 어떤 음식인지 인식하고 그것의 평균적인 칼로리를 알려주는 서비스를 구상했다. Zoom으로 진행된 면담에서는 교수님께서 Object detection에 대한 공부를 더 해볼 것을 권유하셨다. 그래서 아직 해당 분야에 대한 이해가 충분하지 않다는 것을 깨닫고 관련 자료를 찾아서 학습하기로 하였다. 교수님께서는 지능정보처리연구실 석사과정을 멘토로 배정해주셨다.

 

- 39~ 314: Object detection 관련 공부, 연구 계획서 제출

 

PR12와 같은 논문 리뷰를 비롯하여 각종 블로그와 유튜브, github 소스들을 보면서 Object detection을 공부하였다.

- 317~ 321: 1차 멘토링

 

공부 도중에 생긴 의문점을 바탕으로 멘토님께 메일을 드렸고, 그에 대한 피드백을 받았다. 상담 내용을 요약하자면 다음과 같다. 우선 연구 주제에 관하여, 음식의 칼로리를 추정한다는 막연한 주제만 생각했을 뿐이지 어떤 모델을 쓰고 어떤 데이터 셋을 쓸 지에 관한 구체적인 계획은 전혀 없었다. 그리고 그것을 찾아보는 과정에서 생각보다 어려울 수 있는 것과 이미 국내에서 상용화된 앱이 있다는 것을 알게 되면서 음식 분류라는 주제를 계속 가지고 가는 게 좋을지 여쭤보았다. 또 모델을 완전히 밑바닥부터 만들어야 하는 건지, 오픈 소스를 기반으로 변형을 해서 써도 되는 건지에 대한 것도 여쭤보았다. 이에 대한 피드백으로 관련 논문과 데이터 셋 등 공부할 자료들을 주셨고, 또 연구의 중심을 구현보다는 응용에 초점을 맞추어서 하는 것이 좋겠다고 하셨다. 해당 내용에 관한 원문은 멘토 의견에 기술하겠다.

 

- 322: 2차 멘토링

 

주제가 명확하게 확정된 상황이 아니었기 때문에 추가적으로 주제를 생각해서 학교를 직접 방문했다. 온라인으로 진행할 수도 있었으나 학교를 방문한 이유는 gpu 서버를 발급 받을 수 있었기 때문이다. 인공지능연계전공 학생들에게 할당된 서버를 발급받고, 사용법을 익히고, 설치하면서 주제에 대한 상담을 이어나갔다.

3가지 아이디어를 생각해서 가져갔다. Object detection 자체를 바꾸고 싶지는 않아서 해당 범위 안의 주제를 모색했다. 첫 번째는 서울시 공공자전거인 따릉이의 헬멧 미착용 경보 시스템을 만드는 것이었다. 공공자전거 자체에 카메라를 부착하거나, 자전거 대여소에 카메라를 설치하고, 헬멧을 착용하지 않으면 자전거를 대여할 수 없도록 하는 시스템이었다. 가장 큰 문제는 현실적으로 비용 문제가 많이 발생하며, 헬멧 착용 자체가 법적으로 처벌 규정이 없으므로 강요할 수 없는 점도 있었다. 두 번째 아이디어는 보드게임 루미큐브를 자동으로 풀어주는 AI였다. 유튜브에서 카드 게임이나 스도쿠 관련해서 object detection을 활용하여 풀어주는 아이디어가 재밌어서 이를 루미큐브와 접목하고자 하였다. 마지막 아이디어는 사회적 거리 두기에 관한 아이디어였다. 5인 이상 집합금지가 법적으로 규정되어있으므로 object detection을 활용하여 5명 이상의 사람이 밀집되어 있으면 잡아내는 시스템을 생각했다. 이 주제들을 가지고 멘토님과 상담을 했는데 우선 루미큐브는 졸업 작품으로 그다지 좋지 않은 주제일 것 같다는 의견을 들었고, 알고리즘에 더 치중되어 있을 것 같다는 판단을 들었다. 세 번째 주제도 나쁘지는 않지만, 첫 번째 자전거 관련 주제가 가장 적합하다고 하셨다. 그리고 자전거뿐만 아니라 전동킥보드로 확장하면 좋을 것 같다고 하셨다. 513일부터 시행되는 법령이 있으니 알아보라고 하셨고, 이에 따라 도로교통법을 공부하면서 이를 반영하고, 자전거 대신 킥보드로 주제를 좁히면 의무화를 이용하여 강제성을 확보할 수 있다고 판단했다. 또 설치 비용에 관한 문제는 자전거나 대여소마다 설치하는 것이 아니라, 주행 중인 킥보드를 감시하면 어느 정도 해소할 것으로 예상했다.

 

- 322~ 43

 

1. 딥러닝을 위한 환경 구축

 

학교에서 서버를 발급받기는 했으나 학교 Wifi 환경에서만 이용할 수 있었다. 따라서 집에서 딥러닝을 수행할 수 있도록 관련 프로그램을 설치하였다. 현재 집에서 사용하고 있는 환경은 아래와 같다.

 

Windows 10 64-bit

Python 3.7.10

conda 4.9.2

TensorFlow GPU 1.15

CUDA Toolkit 11.2

NVIDIA Geforce RTX 2080

NVIDIA® GPU drivers 461.33

cuDNN 8.1.1

 

2. 모델 선정 및 오픈소스 탐색

 

YOLO v3를 사용하기 위해 keras로 구현이 된 오픈 소스를 찾았고, 이를 활용하여 프로젝트를 수행한다.

해당 github 주소는 https://github.com/qqwweee/keras-yolo3 이다.

 

3. Dataset 구하기

 

Dataset을 구하는 방법은 크게 두 가지가 있다. 직접 수집하는 방법과 오픈 데이터 셋을 이용하는 방법이다. 우선 YOLO 모델이 정상적으로 돌아가는지 확인을 할 필요가 있어서 오픈 데이터셋을 이용하기로 했다. 그리고 그것으로 부족하다고 판단이 되면 직접 데이터를 수집할 계획이다.

사용한 DatasetGoogleOpen Image Dataset v4이다. 기존의 유명한 DatasetPascal VOCMS COCO같은 곳에는 helmet에 대한 class가 없었다. Open Image dataset은 구글에서 detectionsegmentation을 위해 만든 dataset으로 총 175만여 장의 이미지가 있고, 클래스가 600개 정도 있다. 그리고 기존의 데이터셋과 다르게 이미지 평균 8.4개의 개체가 있을 정도로 복잡한 이미지가 많다.

 

이 중 필요한 클래스를 일부만 추출하여 사용하기로 했다. 추출할 때는 OID를 추출할 수 있도록 만든 open source()를 찾아서 일부만 추출하였다. Person, Bicycle_helmet, Bicycle을 각각 700장 정도 추출하였다.

 

4. 모델 구축 작업

 

jupyter Notebook 상에서 그동안 구한 datasetmodel을 이용하여 작동할 수 있도록 파이프라인을 만들었다. 처음에 OID toolkit으로 데이터를 받으면 그걸 바로 적용할 수 없다. 규정 형식이 다르기 때문이다.

원래 Open Image DatasetBounding Box의 정보가 XMIN, XMAX, YMIN, YMAX의 순으로 normalized된 형태로 저장되어 있다. 즉 범위가 0에서 1 사이의 값으로 되어 있어서 절대 좌표를 알고 싶다면 이미지의 사이즈를 곱해 주어야 한다. OIDv4 toolkit은 이미지의 annotationdenormalized된 형태의 텍스트 파일로 뽑아낸다.

최종 목적지인 keras-YOLO v3에 넣으려면 csv파일이 필요하다. 이를 위해서 OID toolkit으로 추출한 특정 클래스들의 txt파일을 oid_to_pascal_voc_xml.py를 이용하여 xml 파일로 바꾸고, xml파일을 다시 csv 파일로 바꾸어주었다. csv 파일로 바꾸는 과정은 jupyter notebook 상에서 Element tree를 이용하여 파싱하였다.

 

이후 모델 관련 파라미터들을 설정하였다. epoch50회씩 2번 학습을 시키며, batch size4로 하였고 모델에 필요한 클래스 파일을 만들어 알맞은 위치에 위치시켰다.

 

5. 학습 결과

 

학습이 완료된 후에 몇 가지 이미지를 넣어서 테스트해보았다. 그 결과는 아래와 같다.

 

몇 가지 테스트 결과를 출력해보면서 특이사항을 발견했다. 그것을 요약하자면 아래와 같다.

자전거 헬멧은 인식률이 아주 높다. 사람이 착용하든, 착용하지 않든 인식이 잘 된다.

자전거도 비교적 인식이 잘 된다.

사람은 자전거 또는 자전거 헬멧과 같이 있으면 인식이 되지 않는다. 사진 내에 사람 클래스 1개만 존재해야 인식이 된다.

 

- 43~ 416

 

조금 더 실질적으로 접근은 해보고자 이번에는 앞에서 했던 과정에서 Person 대신 Human face로 바꾸어서 진행해보았다.

학습한 후 30여 장 넘게 테스트를 해보면서 발견한 경향은 아래와 같다.

 

1. 이전 학습에서 person이 잘 인식이 안 됐던 것처럼, Helmet을 쓰고 있으면 Face가 인식되지 않는다.

 

2. 헬멧의 인식 영역이 머리통 전체로 될 때도 있고, 헬멧 뚜껑 부분만 될 때도 있다. 상당히 불규칙적이다.

 

3. Face의 경우 Face 클래스 자체에 문제가 있는 것은 아니다. 동일한 사진이라도 헬멧을 감추면 Face가 잘 인식된다.

 

 

HelmetFace가 동시에 인식하는 것에 집착했던 이유는 헬멧을 쓴 상황을 helmet+face로 보고 헬멧을 쓰지 않은 상황을 face로 봤기 때문이다. helmet vs face의 구도로 보지 않은 이유는 앞서 2번에서 다뤘듯이 헬멧 자체가 인식되는 경우가 불규칙했기 때문이다. 그래서 이에 관한 멘토링을 한 번 더 받았다. 그 과정에서 아무래도 Bounding Box가 겹치기 때문에 헬멧과 얼굴이 동시에 인식이 안되고, 또 데이터 셋 자체가 단일 클래스로 이루어져 있는 경우가 많기 때문에 여러 클래스가 같이 있는 이미지에 대한 정확도가 떨어지는 것 같다는 결론을 내렸다.

 

사실 이렇게 실험적으로 모델을 여러 번 돌려본 이유는 하나의 대전제를 가지고 있기 때문이다. 바로 데이터를 일일이 크롤링하지 않고 오픈 이미지 데이터를 쓰는 방식을 고수하는 것이다. 데이터를 일일이 수집하고 라벨링하는 것 자체가 시간을 많이 필요로 하는 작업이라서 계속 피해왔다. 그 과정이 오픈 이미지 데이터셋을 쓰고, 클래스를 쪼개서 구하는 것이었다. 만약 헬멧과 얼굴에 대한 인식이 일관성 있게 진행되었다면 모델을 이중으로 만들어서 자전거나 킥보드를 한 번 걸러내고 헬멧을 썼는지 안 썼는지를 판단하려고 했을 것이다. 그런데 그렇지 못했고, 전동킥보드는 오픈 이미지 셋이 없어서 어차피 크롤링과 라벨링을 해야 했다. 이런 문제점들이 발견되면서 차라리 라벨링을 하는 것이 손이 덜 가는 일일 것 같다는 판단을 내렸다. 그리고 주제도 좀 더 fit하게 전동킥보드로 한정시켰고, 헬멧 쓰고 전동킥보드를 타는 사람과 헬멧을 쓰지 않고 전동킥보드를 쓰는 사람들의 사진을 모아서 라벨링 작업을 진행하였다.

 

이미지 라벨링은 labelImg라는 도구를 사용하였다. 그리고 실제 주행 중 감시라는 타겟에 맞추어, 구글에서 이미지뿐만 아니라 유튜브에서 관련 영상을 찾고 일시정지 상태의 모습을 데이터로 쓰기도 하였다.

 

그리고 클래스를 helmet nonhelmet으로 나누어 다시 학습을 시켰다.

 

Train set에 대한 결과는 아래와 같다.

 

trainset이라고 무조건 잘 나오는 것은 아니다. 아래와 같은 결과도 있다.

같은  object 에  bounding box 를 여러 번 치는 모습
헬멧을 쓰지 않았다고 판단하는 모습

 

 

Test set에 대한 결과는 아래와 같다.

 

라벨링이 중복됨
bounding area가 중심으로 좁혀짐
실폐 사례. 정반대로 예측

과정을 진행해보면서 느낀 것은 아래와 같다.

 

Trainset이나 testset 모두 전동킥보드가 있으면 위치 자체는 잘 잡는다. 전동킥보드 자체를 인지하지 못하는 경우는 거의 없다.

trainsettestset보다 확실히 안정적이다. 오차가 더 적다.

오류가 생기는 유형은 다음과 같다.

1) 클래스 자체를 반대로 예측한 경우(helmetnonhelmet으로 또는 nonhelmethelmet으로)

2) 이미 인식한 개체에 한 번 더 Bounding Box를 두르는 경우

3) Bounding Box 영역이 Ground truth에 비해 좁은 경우(머리나 킥보드 바퀴 부분은 빼고 중심 위주로 잡는 경우)

 

1)번의 오류는 정말 치명적이고, 2) 3)의 오류는 개선한다면 좋을 것이다. 사실 위에서 생긴 오차 모두 train dataset을 증가시키면 어느 정도 해소될 것으로 보인다. 지금 당장은 라벨링을 해서 인식이 잘 되는지 시험차 해봤기 때문에, train dataset에 쓰인 전동킥보드 이미지가 60여 장 정도 밖에 안된다. 아마도 200장 이상 trainset을 만든다면 정확도가 훨씬 올라가고 오류들도 개선될 것이라고 생각한다.

 

추후 계획 및 진행단계

전체 과정 중 현재까지 진행된 내용과 앞으로 진행될 내용은 다음과 같다.

 

주제 명확하게 정하기 (문제를 구체적으로 잡기)

문제를 위한 dataset 구하기

해결할 수 있는 딥러닝 모델 찾기

해결 방안을 구상하고 시도해보기

Labeling을 통해 충분한 데이터 셋 확보하기(진행 중)

모델 성능 끌어올리기

동영상에 적용하기

헬멧 미착용 탐지 시 해당 위치와 시간을 출력하는 알고리즘 만들기

프로토타입 시연 영상 제작 및 발표