꿈 많은 사람의 이야기

파이썬 케라스(keras)로 딥러닝하자! CNN을 이용해 이미지 분류하기(image classification) 본문

deep learning(딥러닝)

파이썬 케라스(keras)로 딥러닝하자! CNN을 이용해 이미지 분류하기(image classification)

이수진의 블로그 이수진의 블로그 2018. 6. 29. 17:49


해당 코드는 https://github.com/lsjsj92

에 있습니다. 참고하시고 스타도 주시면 감사하겠습니다 :)


파이썬으로 케라스(keras)와 사이킷런(scikit-learn)을 독학한지 어느덧 1달이 조금 넘었습니다.

그 동안 카테고리 분류도 해보고, 감정 분석도 해보고(실패....) 여러가지 해보면서

일반적인 머신러닝 알고리즘(서포트 벡터 머신(SVM), 랜덤 포레스트(random forest) 등)이 아닌 케라스로 다층 퍼셉트론(MLP)을 구현해서 

해봤습니다.


뭐 아직 다음 단계로 넘어갈 실력은 아니었지만 일단은 여러가지 경험을 쌓고자 이젠 컨볼루션 뉴런 네트워크(convolutional neural networks)를 해보려고 합니다.

컨볼루션 신경망이라고도 불리는데요

케라스에선 컨볼루션 신경망 레이어가 있습니다!(Conv2D)


이것을 이용해 이미지를 인식해보려고 합니다.

컨볼루션은 특히 영상 처리에 특화되어 있어서 영상처리쪽에서 많이 쓰인다고 합니다


제가 한 것은

비행기, 불상, 나비, 게 

이렇게 4가지 카테고리를 분류하는 작업을 진행했습니다.



디렉토리는 위와 같이 되어 있습니다.

test와 train 디렉토리가 있구요 

그 안에 세부적으로



이렇게 되어 있습니다.

비행기, 불상, 나비, 게

이 순으로 디렉토리가 있네요




각 이미지는 대략 200개? 정도 있었습니다.

비행기 같은 경우엔 500개가 넘었네요

어떤건 300개 이러구요


근데 아무래도 데이터 셋이 조금 부족합니다.

예제로 많이 쓰는 MNIST는 6만개 이러는데..

고작 몇백개니까요!

그래서 데이터를 부풀려보려고 합니다




케라스에 있는 ImageDataGenerator를 통해서 이미지를 생성을 할 예정인데요

각도를 바꾸고, 옆으로 조금 이동시키고 뭐 이런식으로 하면서 이미지를 더 생성할 예정입니다.

그리고 파일을 바로 생성해서 저자하도록 save_to_dir을 통해서 저장 경로를 지정했구요

1개 사진마다 10개씩 더 추가하려고 합니다~



이렇게 각도가 바뀌고, 옆으로 이미지가 좀 움직이는 등으로 이미지를 더 생성했습니다

각 사진 하나당 10개씩 추가되었어요

데이터 셋이 천 단위로 넘어가게 되었습니다~


이제 다음은 이미지와 카테고리를 X, Y 값으로 나눠야 합니다.

그래야 케라스에서 학습을 진행하니까요



이미지 크기는 64 x 64로 진행합니다.

카테고리별로 돌면서 label을 먼저 0으로 전부 초기화 한 다음

첫번째 idx에 1을 놓아줍니다.

그러면 맨 처음인 비행기는 [1 0 0 0]이 될 것이구요(라벨이 4개라서 배열 크기도 4개입니다)

두번재 불상은 [0 1 0 0]의 형태를 가지고 있을 겁니다.

그리고 이미지를 RGB값으로 바꿔주면서 resize하고 그 값을 numpy 라이브러리를 이용해 가지고와 저장합니다.



이렇게 저장됩니다~

이제 훈련을 시켜야겠죠!



카테고리는 마찬가지로 4개, 그림 크기는 64 x 64입니다.

아까 저장한 npy 파일을 가지고와서 저장합니다.

이제 CNN 컨볼루션 신경망 모델을 만들어보죠


Conv2D를 이용해서 만들 수 있는데요



3 x 3 크기의 컨볼루션 레이어를 32개의 필터수를 처음에 생성합니다. 활성화 함수는 relu를 사용하구요

input_shape는 64 x 64 크기와 컬러 값이니 3

즉 (64, 64, 3)의 튜플 값을 가지게 됩니다.

그리고 maxpooling2D를 통해서 주요 값만 뽑아내어 작은 출력 값을 만들어 냅니다.

즉 사소한 변화를 무시하는 것이죠.


그리고 Flatten()은 CNN에서 컨볼루션 레이어나 맥스풀링을 거치면 주요 특징만 추출되고 전결합층에 전달되어 학습됩니다.

이때, 컨볼루션이나 맥스풀링은 2차원을 주로 다루는데요. 전결합층에 전달을 하기 위해서는 1차원으로 바꿔줘야합니다.

이때 Flatten()을 사용하는 것이죠!

그리고 loss 함수로 binary_crossentropy를 사용했는데요

왜 softmax인데 이걸 사용하는지 저도 의문이었습니다.

이 글 뒷 부분엔 categorycial을 사용합니다.

(결론부터 말하면 binary_crossentropy 이런 상황에서 사용하면 안좋다고 말합니다

조언 해주신 인스페이스 김태영 이사님 감사드립니다)




이렇게 훈련을 진행합니다~



callback 함수로 인해 modelcheckpoint와 earlystoppin을 진행합니다.

케라스에선 이게 정말 좋더군요



계속 val_loss가 떨어지는 것을 볼 수 있습니다.



그 결과 94%의 정확도가 나왔네요



val_acc와 val_loss값도 안정적이구요

이제 테스트를 해봐야죠!

샘플 이미지를 미리 빼놨습니다.




이 이미지들을 기준으로 테스트 해보면요!



이렇게 나옵니다.

그리고 실패한 이미지들은 img_missing디렉토리로 빠지도록 저장했습니다.



얘가 실패했네요


자 이제 위에선 loss를 binary_crossentropy로 했는데요

이제 정석대로 categorical_crossentropy로 해보죠!



이렇게 바꿔주고요 진행해봅니다



음 뭔가 그래프가 아까보단 안이쁘지만..

그래도 정확도는 90%가 나왔네요


이제 새로운 샘플로 테스트를 해볼까요?



구글에서 새로운 사진들을 가지고 왔습니다~

얘내를 가지고 테스트를 해보면요!




음 비행기를 잘 못맞추네요~

그래도 불상, 게, 나비는 다 맞추는군요 ㅎㅎ


이렇게 파이썬 케라스(keras)를 통해서 CNN 컨볼루션 레이어를 구축해서 이미지를 분류할 수 있습니다~

독학하기 참 힘드네요 ㅠ

82 Comments
댓글쓰기 폼