들어가며
잠깐! 혹시 안전모를 쓰지 않고 킥보드를 타고 계시진 않은가요? 인도에서 탄 적도 있으시다고요? 2021년 5월 13일부터 강화된 안전운행 규제에 따르면 킥보드의 경우, 인도 주행 금지, 횡단보도 주행 금지, 안전모 필수 착용 등의 의무사항이 적용됩니다.
하지만 이러한 규제에도 불구하고 킥보드 사고는 매년마다 증가하고 있는데요, 도로교통공단에 따르면 최근 5년간(’19~’23) 전동킥보드 사고 건수는 매년 증가하고 있고 작년에는 무려 사고 건수 2,389건, 사망자 24명을 기록했습니다.
정부는 최고 속도 하향, 경찰력 배치로 안전수칙 위반 집중 단속 등 다양한 정책을 펼쳤지만 여전히 사고는 줄지 않고 있습니다. 또한 경찰력을 모든 곳에 배치할 수 없다보니 공권력이 낭비되고 있다는 지적도 나오고 있어요.
이러한 상황에서 저희 팀은 딥러닝을 통해 ‘킥보드 위법 상황을 자동으로 탐지할 수는 없을까?’라는 주제로 프로젝트를 진행했습니다. 프로젝트 목표는 다음과 같습니다.
- 인도 주행 킥보드 탐지
- 사고다발 지역 횡단보도 주행 킥보드 탐지
- 킥보드 사용자 헬멧 착용 여부 확인
데이터셋
저희는 AI-Hub의 개인형 이동장치 안전 데이터셋을 사용했습니다. 본 데이터셋은 총 300시간에 대응하는 60만장의 이미지로 구성되어 있습니다. 도로교통공단 교통사고분석시스템(TAAS)의 2020년 개인형 이동수단별 교통사고 통계를 참고하여 이동장치별 수집규모 비율을 참고하되 PM의 유의미한 데이터를 확보하기 위해 강제할당을 적용하여 오토바이(36.7), 자전거(41.6), PM(21.7) 수집 비율을 기준으로 하여 수집한 데이터입니다.
데이터 전처리
먼저, 사용할 데이터를 알아보는 작업이 필요합니다. AI-hub의 데이터셋을 살펴본 결과, 다음과 같은 특징들이 있었습니다.
- Differing Violation Sizes and Scenarios
동일한 위반 행위도 이미지마다 다른 형태로 나타날 수 있습니다. 예를 들어, 헬멧 미착용 위반은 가까운 거리에서 찍힌 이미지와 먼 거리에서 찍힌 이미지에서 다르게 보일 수 있으며, 헬멧 색상도 가지각색입니다. 횡단보도나 인도에서의 위반 행위도 서로 다른 양상으로 나타납니다. - Multiple Classes in a Single Image
한 장의 사진에 여러가지 위반 유형이 포함되어 있는 경우가 있습니다. 예를 들어, 킥보드 사용자가 헬멧 착용 규정을 위반하면서 동시에 동승자 탑승 규정을 위반할 수 있습니다. 이런 경우, 하나의 이미지가 여러 클래스로 분류됩니다. - Irrelevant Images
데이터셋에는 위반과 관련이 없는 이미지도 포함되어 있습니다. 예를 들어, 킥보드와 무관한 보행자가 찍힌 이미지나, 도로만 찍혀있는 이미지도 있었습니다.
저희는 킥보드 위험상황 중 보행자도로, 차선, 횡단보도는 기본적으로 인식하되 킥보드 탑승자의 안전모 착용 여부를 판단하는 detection 프로젝트를 진행하기에 데이터셋에서 선별하여 데이터를 사용하였습니다. 선별된 데이터의 양이 부족하다고 판단해 추가적으로 크롤링을 통해 헬멧 데이터셋(착용/미착용)을 확보하였습니다.
모델이 학습을 하기 위해선 먼저 데이터 전처리 과정을 거쳐야 합니다. 이번 프로젝트에서 사용한 모델은 YOLOv8으로, 실시간 처리에 강점을 갖고 있는 모델입니다. AI-Hub의 데이터셋이 json 형식으로 되어 있었고, 불필요한 정보도 있어 다음과 같은 과정을 거쳐 json 데이터를 txt 형식으로 변환했습니다.
- 원하는 정보만 추출(횡단보도, 인도, 킥보드 좌표 + 안전모 착용 여부)
- polygon 형식으로 저장된 횡단보도, 인도의 좌표를 bounding box 형식으로 수정하기
또한, 기존 데이터셋에는 저희 프로젝트의 목표와 거리가 있는 오토바이, 자전거 데이터도 포함되어 있었습니다. 다양한 데이터 중 안전모를 착용한 정상 데이터(pm = 28), 안전모 미착용(pm = 31), 그리고 크롤링을 통해 수집한 헬멧 데이터셋을 사용해 새로운 데이터셋을 구축했습니다.
모델
저희는 킥보드 위험 상황이라는 시나리오에서 가장 중요한 것은 실시간 처리라고 생각했습니다. 따라서 현재 공개된 모델 중 실시간 처리에 강점을 갖고 있는 YOLOv8 모델을 선택했습니다.
YOLO(You Only Look Once) 모델의 컨셉은 real time object detection! 즉 실시간 객체 검출입니다. two-stage 계열 같은 경우 객체를 검출하는데 시간이 조금 걸려요. 자율주행 자동차와 같은 실시간으로 사물이 어디에 위치하는지 파악되어야 하는 작업엔 사용할 수 없습니다. 2 stage detection의 느린 속도 때문에 이 둘을 한 번에 하는 one-stage detection 방식이 나오게 되며, 그 시초 모델이 YOLO입니다. 또한 YOLO는 classification과 Localization을 동시에 하여 실시간으로 객체 검출이 가능합니다.
YOLO는 GoogleNet의 구조로 영감을 받았다고 논문의 저자는 말합니다. GoogleNet의 Inception block 대신 단순한 convolution으로 다음과 같이 네트워크를 구성했다고 합니다.
- 총 24개의 conv layer
- 2개의 fc layer
- 앞 20개의 conv layer에 대해선 1000개 class의 ImageNet dataset으로 pretrained 된 부분이고 뒤에 4개의 conv layer와 2개의 fc layer를 더 붙여서 Pascal VOC 데이터로 Fine tuning 시킨 과정을 거쳤습니다.
- 중간에 노란색으로 표시된 부분에 1 X 1 reduction layer로 연산량을 감소시킵니다.
YOLO 모델을 학습시키기 전에 준비해야 할 것들이 몇 가지 있습니다. 가장 중요한 것은 이미지와 레이블을 각각 Images, labels라는 디렉토리로 분류해 놓고, train, val, test라는 하위 디렉토리로 나눠 놓는 것입니다. 이 과정이 모두 끝났다면 모델 학습 전 필요한 구성 파일인 yaml 파일로 학습할 데이터셋의 경로, 클래스 이름, 하이퍼파라미터 등의 정보를 설정해야 합니다. 이 파일은 모델이 어떻게 학습해야 하는지에 대한 가이드를 제공합니다.
train: /path/data_hel/images/train
val: /path/data_hel/images/val
test : /path/data_hel/images/test
nc: 4
names: ['helmet', 'ped_road', 'crosswalk', 'no_helmet']
hyp:
hsv_h: 0.015
hsv_s: 0.4
hsv_v: 0.4
degrees: 10.0
shear: 12.0
perspective: 0.001
fliplr: 0.5
mosaic: 0
위 코드는 저희가 사용한 yaml 파일의 내용입니다. 안전모 착용, 보행자 도로, 횡단보도, 안전모 미착용으로 총 4개의 클래스로 구분해 놓았으며, 데이터 수가 부족해 증강하는 방식을 선택했습니다.
🤔 어떤 증강 기법이 사용되었을까요?
- hsv_h
가시광선 스펙트럼을 고리 모양으로 배치한 색상환을 조정합니다. 이를 통해 다양한 조명 조건에 대한 일반화 성능을 향상시킬 수 있습니다. - hsv_s
이미지의 채도를 조정합니다. 다양한 환경 조건에 대한 일반화 성능을 향상시킬 수 있습니다. - hsv_v
이미지의 명도(밝기)를 조정합니다. 이를 통해 다양한 조명 조건에 대한 일반화 성능을 향상시킬 수 있습니다. - degrees
지정된 각도 범위 내에서 이미지를 무작위로 회전시켜, 모델이 다양한 방향에서 객체를 인식하는 능력을 향상시킵니다. - shear
지정된 각도로 이미지를 전단합니다. 즉, 이미지의 모양을 비스듬히 변하게 합니다. 이를 통해 다양한 각도에서 객체를 보는 효과를 모방합니다. - perspective
이미지에 무작위로 원근 변환을 적용하여, 모델이 3D 공간에서 객체를 이해하는 능력을 향상시킵니다. - fliplr
지정된 확률로 이미지를 좌우로 뒤집어 대칭 객체를 학습하고 데이터셋의 다양성을 증가시킵니다. - mosaic
네 개의 학습 이미지를 하나로 결합하여 다양한 장면 구성과 객체 상호작용을 시뮬레이션합니다. 복잡한 장면 이해에 매우 효과적입니다.

모델 학습
총 5779장(train: 4623, validation: 577, test: 579)의 이미지를 사용해 모델을 학습시켰습니다.
# 모델 학습
model.train(
data="path/data_hel/yolo_final.yaml",
epochs=100, # 학습 에폭 수
batch=16, # 배치 크기
imgsz=640, # 이미지 크기
workers=2 # 데이터 로드 시 사용할 CPU 워커 수
)
모델 평가
Class | Images | Instances | Precision | Recall | mAP@50 | mAP@50-95 |
all | 573 | 1286 | 0.955 | 0.856 | 0.912 | 0.802 |
helmet | 271 | 328 | 0.974 | 0.796 | 0.876 | 0.757 |
ped_road | 422 | 484 | 0.902 | 0.858 | 0.91 | 0.758 |
crosswalk | 85 | 108 | 0.955 | 0.778 | 0.868 | 0.782 |
no_helmet | 312 | 316 | 0.988 | 0.991 | 0.993 | 0.91 |
보행자 도로 통행 위반, 횡단보도 통행 위반 등 위반 사항을 검출하기 위해서 인도, 횡단보도, 킥보드 각각의 Bounding Box 영역의 겹침 여부를 계산하는 알고리즘을 설계해, 킥보드가 인도에 있는 경우 빨간색, 킥보드가 횡단보도에 있는 경우 노란색, 킥보드가 횡단보도를 벗어난 경우 파란색으로 표시하여 각각의 위반사항을 잡아낼 수 있도록 하였습니다.
결론
모델의 성능 지표는 좋았지만 보행자, 운전자 시점에서 인도를 잘 구분하지 못하거나 뒷모습만 나온 경우 헬멧 미착용에 대한 분류를 수행할 수 없다는 등의 문제점이 발생했습니다. 예를 들어, 아래 사진처럼 헬멧을 쓰고 있지 않는데도 헬멧을 쓰고 있다고 판별하는 경우가 있습니다.
또한, 학습에서 사용한 데이터셋이 영상 데이터를 프레임 단위로 자른 이미지이기 때문에 연속적인 데이터가 많습니다. 이 이미지가 학습과 테스팅에 모두 사용되면 과적합 문제가 발생해 킥보드의 크기가 작더라도 높은 정확도를 나타낼 수 있다고 판단했습니다.
문제를 보완하기 위해 추후 중복 데이터는 삭제하고 다양성을 늘릴 계획입니다. 그리고 언급한 문제점에 해당되는 데이터로 추가적으로 학습을 진행하고, 헬멧 데이터를 추가해 사이즈를 조절 후 학습 시키는 방법도 생각해 봤습니다.
문제가 모두 해결되면 중앙선, 신호등과 같은 교통 요소를 모두 학습 시켜 킥보드 사용량이 높은 지역에 경찰력 우선 배치, 킥보드 업체와 협력해 안전모 착용 강화 등 더 넓은 범위로 확장하는 것이 최종적인 계획입니다.
'프로젝트' 카테고리의 다른 글
[프로젝트] 나랑 키배 뜰 사람? 가상 피아노! (0) | 2025.02.01 |
---|---|
[프로젝트] 파리 올림픽 관중석에서 아시아인을 찾아보자! (1) | 2024.10.04 |