마스크 쓴 얼굴 분류 모델 개발기

Photo by Yoav Aziz on Unsplash

이번에 2021 군장병 공개 SW 온라인 해커톤에 AI부문으로 참여했습니다. 본선에서 개발한 프로젝트는 사진/영상에서 사람 얼굴을 찾고 마스크를 착용했는지 여부를 판단하는 AI 모델을 개발하는 프로젝트입니다. 인터넷에 예제가 많아서 난이도가 그리 높지 않았습니다. 결과를 기다리기 전에 개발과정에서 데이터를 모으고 학습하면서 배웠던 점들을 후기로 남겨보려고 합니다.

위 깃허브 링크에서 확인해보실 수 있습니다

먼저 전체 프로세스는 아래와 같습니다.

  1. 사진에서 사람 얼굴을 찾는다.
  2. 얼굴 영역을 떼어내서 마스크를 썼는지 분류한다.

사진에서 사람 얼굴을 찾기

먼저 얼굴을 찾는 모델은 직접 개발하지 않고 다른 오픈소스를 사용했습니다. Facenet-Pytorch와 OpenCV 두가지를 상황에 따라 선택해서 사용할 수 있게 구현했습니다.

마스크를 썼는지 분류하기

학습 데이터 확보

먼저 학습에 필요한 데이터를 구해야 했습니다. 스크를 쓰지않은 얼굴과 마스크를 쓴 얼굴 사진이 필요했습니다. 마스크를 쓰지않은 얼굴 데이터는 많은데 마스크를 쓴 얼굴 사진은 RMFD(https://github.com/X-zhangyang/Real-World-Masked-Face-Dataset) 저장소에 있는 사진들을 사용했습니다.

일부 툴을 이용해서 마스크 쓴 얼굴을 임의로 생성할 수도 있습니다(Simulated Masked Face). 이런 데이터도 섞어서 마스크 쓴 얼굴 데이터를 추가로 확보할 수 있었습니다.

https://github.com/aqeelanwar/MaskTheFace
https://www.kaggle.com/muhammeddalkran/lfw-simulated-masked-face-dataset

모델 학습

간단한 CNN 모델로도 충분히 좋은 성능을 보였습니다. 전이학습도 해본 결과 오히려 오버피팅되는 경향을 보였습니다. 마스크 착용 여부를 판단하는건 전이학습을 써야할 정도로 어려운 작업은 아닌 것 같습니다. 생각해보면 얼굴 아래부분이 마스크 색상(흰색이나 검정색 등)으로 덮여있는지만 확인하면 되기 때문입니다.

학습 데이터를 Train Set과 Validation Set으로 나눴는데 둘 다 좋은 정확도를 보였습니다. 근데 문제는 내 얼굴이나 인터넷에서 다른 사진을 구해서 Test Set을 만든 결과 정확도가 처참했습니다.

원인 분석

프로젝트 기간 대부분을 모델 성능이 안좋은 원인을 찾고 이를 해결할 방법을 고민하는데 투자했습니다. 모델의 특성을 확인할 수 있는 여러 Test 데이터를 만들어서 문제의 원인을 알아낼 수 있었습니다.

검은 마스크를 인식 못하는 문제

첫째로 검은 마스크를 인식 못했습니다. 위 사진의 검은 마스크를 흰색으로 칠해보니 모델이 마스크를 착용했다고 판단한 것을 알 수 있었습니다. 학습 데이터를 확인해보니 검은 마스크 데이터가 거의 없고 대부분 흰 마스크 혹은 푸른 수술마스크인걸 확인했습니다. 인터넷에서 검은 마스크 데이터를 찾아서 추가로 확보해서 이 문제를 해결했습니다.

얼굴을 확대하니 제대로 인식

둘째로 사진에 배경, 옷 등이 포함되고 얼굴이 일부일 경우 마스크를 썼다고 잘못 인식되는 경우가 잦았고 얼굴 부분만 확대할 경우 위처럼 마스크를 안썼다는 것을 올바르게 인식하는 것을 알 수 있었습니다.

저희 학습 데이터는 위처럼 얼굴에 배경+옷까지 나와있는 상태였는데, 모든 학습 데이터에서 얼굴 부분만을 추출해내서 학습 데이터를 전부 오른쪽처럼 변경했습니다.

귀찮고 지루한 작업이다보니 학습데이터를 확보해놓고 데이터가 올바른지 전부 확인해보지 않았던 것이 모델 성능문제의 요인이었습니다. 시간을 들여서 약 6천개의 사진을 일일이 확인하고 잘못된 데이터는 전부 제거했습니다. 학습 데이터 중에 너무 흐려서 분간이 안되거나 잘못 라벨링된 이미지들이 정말 많았었습니다. 그리고 다시 모델을 학습하니 Test Set에서도 정확한 성능을 보여주게 되었습니다. 그렇게 만들어진 결과물이 아래와 같습니다.

cottonbro님의 동영상, 출처: Pexels
George Morina님의 동영상, 출처: Pexels

아쉬운점

MLOps를 적용해보고 싶었는데 시간이 충분하지 않아서 시도해보지 못했습니다. 또 마스크를 쓴 얼굴에서 Face Verification 기능도 구현해보고 싶었는데 마찬가지로 본선 대회기간이 1달 남짓이고 군대에서 개발시간이 넉넉하지는 않은지라 마스크 썼는지에만 집중하다보니 못했습니다. 또 pip로도 배포해보고 싶네요.

또 위 사진처럼 Face Detection 모델이 얼굴 옆면은 인식 못하거나 잘못된 부분을 인식해버리면 어찌 방법이 없던 것도 문제였습니다. 얼굴을 잡아내면 인식은 잘 하는데 얼굴을 잡아내는게 더 어려운 문제인 것 같습니다.

실제 프로젝트를 하니까 모델을 만지는 시간보다 모델을 디버깅하고 문제점을 찾아서 데이터를 추가확보하는데 드는 시간이 압도적으로 많았습니다. 모델을 더 유명하고 좋은 걸 쓴다고 성능이 항상 좋아지는게 아니라 먼저 데이터에 의해 결정된다는 걸 깨닫게 되는 경험이었습니다.

2020.12.8 ~ 2022.6.7 육군복무중 Serving in the South Korean Military Service

2020.12.8 ~ 2022.6.7 육군복무중 Serving in the South Korean Military Service