KISTI 과학기술 빅데이터 분석가 양성과정 중 진행한 프로젝트를 바탕으로 작성되었습니다.
2편은 데이터셋 구축부터 구현까지의 내용을 담았습니다.
1편을 작성한 지 2달 만에 2편을 작성하게 되었습니다. 그동안 다른 프로젝트를 진행하다 2편 쓰기를 미뤄오게 되었네요. 그 사이에 스타트업이라는 드라마에서 시각장애인을 위한 '눈길'이라는 애플리케이션이 나오는 것을 보면서 제가 했던 프로젝트가 생각났습니다. 어서 마무리해야 할 때가 된 것 같습니다.
1. 데이터셋 구축
-
이미지 모으기
지난 편에 이미지 크롤링으로 1200장 데이터를 모아서 1차 데이터셋을 만들었습니다. 하지만, 데이터 불균형의 문제로 데이터가 많은 클래스에 대해서만 인식을 잘하는 경향을 보였습니다. 그래서 저희 팀은 더 많은 데이터를 모으기 위해 다음과 네이버에서 크롤링을 시도했습니다. 크롤링은 beautifulSoup4와 Selenium 라이브러리를 활용해서 3300장을 모았습니다. 하지만, 중복 사진과 로고 사진이 너무 많아서 정제가 필요했습니다.
-
이미지 정제
중복 사진을 손쉽게 제거할 수 있는 방법이 있는지 찾아보다가 VisiPics라는 프로그램을 활용해서 정제했습니다. VisiPics 프로그램 사용법이 궁금하시다면 여기를 클릭하세요. VisiPics 프로그램을 활용해서 1차적으로 중복을 제거하고 정제를 시작했습니다.
정제의 기준
1. 다른 사물이 포함된 사진 제거
2. 광고 문구가 포함된 사진 제거
3. 식별 클래스가 작은 사진 제거
위의 사진처럼 정제를 실시하였습니다. 총 2500장까지 정제했습니다. 정제한 이미지를 살펴보면 배경이 흰색이고, 정면 사진이 많이 존재했습니다. 이 부분을 보완하기 위해 직접 촬영한 사진을 추가하기로 했습니다.
-
이미지 추가
새롭게 추가한 이미지
1. 다양한 배경에서 직접 촬영한 이미지
2. 캔을 다각도에서 촬영한 이미지
3. 캔의 상표 부분을 잘라낸 이미지
흰 배경의 이미지를 보완하기 위해 아래와 같이 다양한 배경과 각도에서 촬영한 사진을 총 2000장 추가했습니다.
또 다른 이미지를 추가하기 위해 사람은 어떻게 물건을 분류하는 가에 대해 생각해봤습니다. 만약, 사람한테도 상표가 없는 캔을 줬다면, 원하는 음료수를 고르지 못할 겁니다. 그래서 아래와 같이 캔을 360도로 촬영한 상표 이미지를 잘라서 추가했습니다.
아래의 사진처럼 상표의 이미지 일부를 잘라낸 것을 추가해서 데이터를 보강했습니다. Cropped image를 추가한 이유는 이미지가 정확하게 사진에 찍힐 수도 있지만 일부가 찍혀도 인식해야 된다고 생각했기 때문입니다.
-
최종 데이터셋
최종 데이터셋은 아래의 보시는 것처럼 구성했습니다. 비록 원본사진의 이미지 개수는 적었지만 충분하게 데이터를 늘리기 위해 Augmentation을 통해 데이터 수를 증가시켰습니다.
2. 모델링
모델링을 위해 라이브러리를 ImageAI, Keras를 활용했습니다. 저희는 라즈베리파이를 활용해서 제품을 만든다고 생각했기 때문에 가벼운 모델을 활용해야 했습니다. 그래서 저희는 MobilenetV2 모델을 선정했습니다. 저희는 weight는 불러오지 않고 처음부터 학습하는 방법을 선택했습니다. 시간이 지난 지금 생각해보면, Transfer learning을 사용했으면 더 빠르게 모델을 구성할 수 있었을 것 같습니다(다음에 동일한 데이터 셋으로 Transfer learning 모델로 학습시켜보겠습니다)
-
ImageAI 라이브러리는 모델링이 편리한 장점이 있습니다. 하지만, 구현되어 있는 것이 한정적이었으며, 무엇보다 Tensorflow 1.X 버전을 활용해야 했습니다. 그래서 처음에 이미지 분류에 대해 익히는 용도로 활용했습니다.
-
Keras 라이브러리는 사용하기 편하게 되어 있었고, 저희는 코랩환경에서 구성을 했기 때문에 런타임이 끊어지는 현상이 발생하면 재학습을 시켜줘야 했습니다. 이를 위해 Keras를 활용해서 최종 모델을 구성했습니다.
Augmentation을 5배 해준 것과 10배 해준 것을 비교해보니 아래와 같은 결과가 나왔습니다.
위의 결과처럼 Train 데이터가 약 2만장일 때, Val_acc와 Test_acc가 높았다는 것을 확인할 수 있었습니다.
3. 구현
최종 구현 모습은 아래와 같이 구성했습니다. 구성하면서 문제가 있었던 것은 반복된 구간에서 모델을 불러오니 캡처할 때마다 모델을 불러오는 데 시간이 걸렸습니다. 이를 방지하기 위해 모델은 맨 처음에 불러오는 것으로 변경했습니다.
구현 순서 설명
1. 미리 학습된 모델을 불러옵니다.
2. OpenCV를 활용해 비디오 캡처를 시작합니다.
3. 입력 대기상태에서 입력(Space bar)을 넣어주면 해당 프레임 사진을 촬영하고 해당 이미지를 저장합니다.
4. 저장된 이미지를 저장하고 예측한 결과와 음성을 반환합니다.
5. 3~4의 과정을 반복하고 종료는 ESC키를 눌러서 종료합니다.
-
구현 영상
4. 느낀점 & 배운 점
-
컴퓨터는 내가 넣어준 이미지에 따라 다르게 학습한다는 것입니다. 내가 좋은 것을 넣어주면 좋은 것을 뱉어준다는 것을 알게 되었습니다. 그래서 GIGO(Garbage In, Garbage Out)라는 말이 있는 것 같습니다. 수차례 데이터셋을 변경하는 과정을 통해서 데이터셋을 구성하는 것이 굉장히 중요하고 어려운 작업이라는 것을 알게 되었습니다. 그 과정에서 과적합의 문제, 올바르게 Train/validation set 나누기, Augmenation 등을 공부할 수 있었습니다.
-
Java 언어에 대해 잘 알고 있었다면, Tensorflow lite 라이브러리를 활용해서 애플리케이션을 만들어 볼 수 있었을 텐데 라는 아쉬움이 있습니다. 그래도 공부하는 것보다 Keras, ImageAI와 같은 라이브러리를 직접 구현을 하는 것이 많은 것들을 배울 수 있었습니다. 비록, 팀이 몇 개 되지는 않았지만 그중에 대상을 받아 기분 좋게 교육을 마무리할 수 있었습니다.
이것으로 KISTI 팀 프로젝트 진행기를 마치도록 하겠습니다. 긴 글 읽어주셔서 감사합니다.