[15일 차] Dog breed classification project

※ Notification
본 포스팅은 작성자가 이해한 내용을 바탕으로 작성된 글이기 때문에 틀린 부분이 있을 수 있습니다.
잘못된 부분이 있다면 댓글로 알려주시면 수정하도록 하겠습니다 :)

Intro

오늘은 미리 준비된 데이터셋이 아닌 직접 데이터를 수집하여 프로젝트를 진행해보는 시간을 가졌다.
chihuahua, jindo dog, yorkshire terrier, shepherd 4가지 개의 품종을 구분하는 프로젝트를 진행했다.
역시나 데이터 수집에서 제일 어려움을 느꼈다.
ML/DL 할 때 모델 코드 짜는 것보다 데이터를 준비하는 게 더 중요하다고 항상 느껴왔지만, 최근 파이프라인 구축을 공부하고 진행하다보니 진짜로 모델 코드 짜는 것은 ML/DL 프로젝트의 일부분에 불과하다는 것을 느끼는 중이다.
출처 : Hidden Technical Debt in Machine Learning Systems 논문

Data prepare

일단 강아지 데이터의 수집을 위해 크롤링을 진행했다.
처음에는 또 셀레니움을 이용해서 코드를 짜야하나 생각했지만 Google에 검색해보니 google_images_download라는 검색어를 입력해주면 관련된 사진을 알아서 다운받아주는 신박한 물건을 찾을 수 있었다. 하지만 마지막 업데이트가 'May 22, 2019'으로 제대로 동작하지 않는다는 글이 있어서 bing-image-downloader를 이용했다.

from bing_image_downloader import downloader
downloader.download(query_string, limit=100,  output_dir='dataset', adult_filter_off=True, force_replace=False, timeout=60, verbose=True)

사용법은 다음과 같고, 나의 경우에는 품종 list를 만들고 for문으로 돌리면서 query_string에 4가지 품종을 넣어주는 식으로 코딩했다.
output_dir 안에 query_string 별로 디렉토리가 생성되어 이미지가 저장되기 때문에 ImageDataGenerator를 사용하기 편리한 형태로 자동으로 생성돼서 좋았다.
하지만 이것 역시 원활히 동작하지는 않았는데, limit를 1000으로 걸어줘도 중간에 오류가 나면서 멈춰버려서 예외처리를 통해 다운로드 된 부분까지만 데이터를 확보하는 것으로 진행했다.

Data preprocessing

이후에 다운로드 한 데이터들을 압축한 뒤 로컬 윈도우 환경에서 강아지 이미지가 아닌 이미지들을 삭제해주었다. 생각보다 이상 데이터가 많이 섞여있어서 거의 절반 가까이를 삭제하기도 했다.

이후 file name의 format을 통일시켜주고, 압축 파일을 만들었다.

Modeling

전처리가 완료된 데이터를 통해 모델링을 진행했는데, 모델링에 앞서 다음과 같은 프로세스를 진행했다.

Dataset tree copy

Dataset
├─Train
│ ├─ chihuahua
│ ├─ jindo_dog
│ ├─ yorkshire_terrier
│ └─ shepherd 
├─Test  
│ ├─ chihuahua
│ ├─ jindo_dog
│ ├─ yorkshire_terrier
│ └─ shepherd 

압축 파일을 통해 Train 디렉토리 안에 해당 파일들을 넣어주고, 10%의 비율로 test 디렉토리로 옮겨 ImageDataGenerator를 사용하기 위한 구조를 만들어줬다.

ImageDataGenerator

그 후 traintest에 대한 ImageDataGenerator를 만들어주고 이를 이용해 train_data, validation_data, test_data를 만들어줬다.

Modeling

이미지의 총 개수가 1000개도 되지 않았기 때문에 transfer learning을 진행했다.
우선 MobileNet을 통해 간단하게 모델링을 해봤는데 model.fit 과정에서 에러가 발생했다.

Google 선생님께 물어본 결과 이미지의 투명도나 아래와 같이 이미지의 일부분이 잘렸을 때 오류가 난다고 한다.

전처리를 진행하면서 모든 이미지 데이터들을 확인했는데 저런 데이터는 찾아볼 수 없었고, 투명화된 데이터가 문제인듯 싶었다.

몇몇 투명화된 데이터로 추측되는 데이터를 삭제하고 다시 모델링을 진행해봤지만 계속 동일한 오류가 발생하여 진행이 막히게 되었다.

다른 방법을 찾아보던 중 Stanford Dog Dataset(http://vision.stanford.edu/aditya86/ImageNetDogs/)을 발견해 오류가 발생하지 않을 것으로 보이는 일부 데이터에 해당 데이터를 추가하고 다시 모델링을 진행해봤다.

그 결과 모델이 정상적으로 돌아갔고, MobileNet에서 꽤나 준수한 성능을 보여줬다.

Latest Version

전이학습을 이용할 때 가장 최근에 나온 version이 항상 좋을까?
MobileNet, MobileNetV2, MobileNetV3Small, MobileNetV3Large를 비교해봤다.
MobileNet의 경우 약간의 lr 조절로도 준수한 성능을 보여줬다.
MobileNetV2의 경우에도 비교적 준수한 성능을 보여줬다. 오히려 MobileNet 보다 조금 더 좋아보인다. 역시 가장 최근의 버전을 사용하는 것이 좋은 것일까?
하지만 이 질문에 대한 대답은 아래 그래프를 보면 알 수 있다.
MobileNetV3Small의 경우 학습이 전혀 진행되지 않는다. 데이터셋이 잘못 나뉘었나 싶어서 데이터셋도 다시 나눠보고 lr도 조절해보고 했지만 변함이 없다.
그렇다면 역시 버전이 문제인가?

마지막으로 MobileNetV3Large를 돌려보았다.
기대했던대로 V3Small과 같이 학습이 전혀 되지 않는다.

이처럼 Model의 최신 버전을 사용하는 것이 항상 좋은 것은 아니다.
각자 데이터마다 알맞은 모델이 있고, 우리는 그 모델을 찾아서 사용해야 하는 것이다.

Graph Trends

  • Graph의 trend가 rough 하다는 것은 일반적이지 않은 어떤 데이터에 대해 잘 예측하지 못할 수도 있다.
  • 때문에 위 사진의 동그라미처럼 그래프가 튄다면 아웃라이어가 발생할 수 있는 확률이 있다고 해석해볼 수 있다.

Model Selection

다양한 모델을 만들었다고 해서 모든 모델을 사용할 수는 없다. 우리는 모델들을 비교해서 실질적으로 사용할 모델 하나를 선정해야 하는데, 그렇다면 가장 좋은 모델은 어떻게 고를까?

MobileNetXceptionVGG16
Acc97%98%95%
Time1hr2hr0.5hr
Overfitting
(GAP)
1%2%1%

다음과 같이 결과가 나왔다고 가정해보자. 그렇다면 우리는 어떤 모델을 선택해서 사용해야할까? Xception 모델이 정확도가 높으므로 Xception 모델을 채택했다고 해도 될까?

모델을 선택할 때는 근거가 무엇인지 설명할 수 있어야 하며, 그 근거를 가장 잘 보여줄 수 있는 것은 정량적으로 표현할 수 있는 수식을 만드는 것이다.

Y = w1 정확도 + w2 소요시간 + w3 overfitting + w4 데이터개수 + b 와 같이 각각의 항목에 가중치를 두어 의사결정에 있어 중요하게 생각하는 부분을 반영하고, 이를 통해 모델 별로 점수를 산출하여 사용할 모델을 결정한다.

이 과정에서 정확도, 소요시간과 같은 항목들을 만들어내고, 가중치를 정하는 방침이 정해져야 한다. 자신의 조직에서 정한 기준에 따라서 모델을 선정한다고 하면 반박할 거리가 없기 때문이다.

Review

데이터 수집 과정에서 이슈가 있어서 정해진 수업시간 안에는 완료하지 못했지만, 수업이 끝나고 결과를 확인해보니 그래도 나름 괜찮은 데이터셋이 만들어진 것 같아서 다행이었다.

Note

ML/DL - Python? JAVA?

수업 중간에 왜 ML/DL에서 Python을 사용하냐는 이야기가 나왔는데, JAVA나 다른 언어로는 딥러닝을 구현하지 못하는 것이냐고 질문을 하셨다.
한다고 하면 못할 것도 없겠지만, Python의 경우 numpy와 같이 행렬 기반의 라이브러리들이 잘 마련되어 있어서 ML/DL에서 주로 사용하는 것이라고 말씀해주셨다.

간단한 예로, python에서는 행렬에서 특정 원소를 얻기 위해 slicing과 같이 간단히 할 수 있는 작업을 JAVA로 구현한다면 2차원 배열 안에서 처리해야하기 때문에 이중 for문 등으로 복잡해진다고 하셨다.

Image Data == JPGE ?

이미지 데이터셋을 만들어서 공유할 때 JPG를 이용한다고 하셨는데, 이는 JPGE가 이미지가 국제 표준이기 때문이라고 하셨다. (설명해주실 때 JPG라고 하셨는데 찾아보니 JPGE가 표준이고 그 아래 흔히 많이 쓰이는 JPG가 있어서 그렇게 설명을 해주신 것 같았다.)

PNG와 같은 이미지가 안돌아가는 컴퓨터 환경이 있을 수 있기 때문에 데이터를 만들어서 공유할 때는 국제 표준을 따르는게 암묵적인 룰이라고 하셨다.

음성이나 동영상은 어떤 것이 국제 표준 형식인지 궁금해서 찾아봤다.

  • 음성 - mp3
  • 영상 - mp4

Outro

프로젝트만 진행해서 블로그 포스팅할 내용이 별로 없다고 생각했는데 전혀 아니었다.
배움에는 끝이 없는 것 같다.
이제 내일은 YOLO 모델을 배운다고 했다.

ICT에서 다음 기수를 모집한다는 문자를 받았는데, 시각지능 심화과정은 주중 저녁반 밖에 없어서 고민중이다.

좋은 웹페이지 즐겨찾기