최근에 핸드폰을 보다 한 짤을 보곤 두 눈을 의심했습니다.
어…?
광수가 왜 저기서 나와…?
라는 생각이 절로 드는 이 사진 속 주인공은 중국판 프로듀스의 연습생 웡위칭(翁宇庆)인데요.
사실 광수가 아닌 걸 알고 봐도.. 두 눈을 씻고 다시 봐도.. 그냥 멋진 척하는 광수입니다.
이런 광수 아닌 광수님을 보고 있자니.. 문득 궁금증이 생겼는데요.
사람도 구분하기 힘든 이 둘을 AI는 구분할 수 있을까요?
딥러닝 분야에서는 이런 문제를 Image Classification이라고 부르는데요.
대표적으로 아이폰의 face id도 이를 활용한 방법이죠.
그래서 오늘은 광수님과 연습생님을 구분하는 AI를 만들기 위해
1. 광수님과 연습생분의 사진을 잔뜩 모아
2. 딥러닝 모델에게 사진들이 누군지 교육시킨 후
3. 해당 모델에게 테스트를 시켜볼 겁니다.
진행 환경은 구글 colab이었고요. 딥러닝을 시작한 지 얼마 안 된 초짜이다 보니 설명이 부정확하다면 미리 사과드립니다.
01
Image Crawling
목표: 광수, 위칭, 한기범 선수의 이미지 다운로드
출처: https://github.com/YoongiKim/AutoCrawler
딥러닝 모델을 교육시키기 위해선 “얘가 광수고 얘가 연습생이야!”를 말해줄 사진을 모아야 합니다.
저는 좀 더 엄밀한 검증을 위해 광수와 위칭 말고도 광수 닮은꼴로 유명한 한기범 선생님의 이미지도 가져오기로 했습니다.
이번엔 YoongiKim님의 크롤러를 사용했는데요. 깃 헙 링크에 접속해서 파일을 다운로드한 후 keyword.txt파일에 원하는 키워드를 넣은 뒤 (‘이광수’, ‘한기범’, ‘翁宇庆’ ) 터미널 창에서 main.py를 실행하면..
네이버와 구글에 해당 키워드를 검색했을 때 노출되는 사진들을 이렇게 자동으로 드르르륵 긁어와 저장해줍니다.
따란!
어? 그런데…
광수님 사진들을 보니 몇 가지 문제가 보이는데요.
1. 연인인 이선빈 씨나 런닝맨 멤버의 사진이 딸려오거나
2. 사람이 너무 멀어 모델을 트레이닝하기 부적절한
경우들이 눈에 밟힙니다.
이를 해결하기 위해 다음 장에선 이 사진들에서 얼굴 부분을 인식, 분리할 겁니다.
02
Face Crop
목표: 크롤 된 이미지에서 얼굴 부분 자르기
출처: https://github.com/bwcho75
이전의 크롤러는 ‘이광수’를 검색할 때 나오는 사진을 모두 받다 보니, 그 사진들을 그대로 사용했다간
제 순수한 딥러닝 모델이
“아! 사람이 두 명 있는 걸 이광수라고 부르는군!”
이라고 착각할 수도 있습니다. 따라서 모델이 사진을 알아보기 쉽게, 그리고 한 사진 파일에는 한 명만 들어가도록 얼굴을 잘라줄 건데요.
이번엔 흰고래의 꿈 블로그를 참고하여 google vision api와 bwcho75님의 코드를 활용했습니다.
코드를 실행하면, 사진 내의 얼굴을 자동으로 인식해서 광수님을 포함한 다른 얼굴들이 우르르 저장되는데요.
당사자가 아닌 얼굴들을 하나씩 지우는 작업을 반복한 끝에 광수(465), 기범(413), 워칭(64)개의 사진을 확보했네요.
드디어! 전처리가 끝났으니 image classification과정을 진행할 겁니다.
03
Image Classification
목표: 딥러닝 모델에 각 얼굴 교육시키기
출처: https://github.com/lukemelas/EfficientNet-PyTorch/
출처 2: https://keep-steady.tistory.com/35
이제 본격적으로 모델을 훈련시킬 건데요. 제가 딥러닝 모델을 구조부터 직접 만들어서 제일 처음부터 훈련시키기에는 데이터도.. 시간도.. 실력도 부족하다 보니 남이 만들어둔 모델에 숟가락만 얹으려 합니다.
이렇듯 부족한 데이터와 시간을 절약하기 위해 이미 학습된 모델에 목적에 맞는 데이터로 추가적인 학습을 진행해서 업무/연구에 활용하는 경우를 전이학습 혹은 transfer learning이라 부르는데요.
저는 2019년 구글에서 발표한 뒤 현재까지 image classification에서 최고의 성능을 보여주고 있는 “EfficientNet”이라는 모델로 전이학습을 할 겁니다. 즉 구글이 엄청난 데이터로 열심히 키워놓은 모델에게 광수/기범/연습생의 사진을 보여주며 추가적인 교육만 시켜주는 거죠.
우선 깃헙에 공개된 lukemelas님의 코드를 clone한 뒤 EfficientNet의 model중 가장 가벼운 b0을 불러왔습니다. (*b0~7로 높아질수록 정확하나 속도가 느림)
제 모델이 구분할 클래스는 이광수/한기범/연습생이니 num_classes를 3으로 설정해줬습니다.
이후 데이터셋을 train/valid/test로 구분했습니다. (다 복사한 거지만..)
이후 각 데이터셋이 잘 정리됐나 확인해보니 우측 사진처럼 오류 없이 잘 구분된 것을 확인할 수 있네요.
이제 training단계인데요. 학습의 횟수를 뜻하는 epoch를 20으로 설정한 뒤 training을 진행했더니 정확도가 약 97.9%까지 올라갔습니다.
자 이제 모델이 다 완성되었으니 테스트를 할 시간,
테스트를 위해 일부러 빼뒀던 광수님 / 한기범 선생님 / 연습생님의 사진과 셋 중 누구도 아닌 박보영 님의 사진을 넣어 분석을 돌렸더니..
연습생분의 사진을 광수님이라고 0.09%만큼 헷갈린 것 말고는 아주 정확하게 구분하는 데 성공했습니다!
셋 중 누구도 아닌 박보영 님의 사진에는 정확도가 낮게 나타나는 걸로 보아 확실히 잘 돌아가고 있네요! 결과적으로 AI는 광수와 연습생을 구분할 수 있었습니다.
이 외에도 여러 사진을 넣어 확인해보니 설마 AI주제에..라는 생각과는 달리 100%에 가까운 정확도를 보여주네요.
브런치가 코드 블록 기능을 제공하지 않아 본문에 코드를 포함시키진 못했는데요. 혹시나 제 Image classification 코드가 궁금하시다면 링크에서 확인하실 수 있습니다.
돌망님이 브런치에 게재한 글을 편집한 뒤 모비인사이드에서 한 번 더 소개합니다.