Blog Content

    티스토리 뷰

    CNN으로 이미지 분류하기 [머신러닝, 딥러닝 실전 개발 입문]

    파이썬을 이용한 머신러닝, 딥러닝 실전 개발 입문 도서를 스터디하여 정리한 내용입니다.

    코드는 http://wikibook.co.kr/python-machine-learning/ 에서 다운 가능합니다.

    [이미지와 딥러닝 - CNN으로 이미지 분류하기]

    CNN(합성곱 신경망) 사용

    색상이 있는 이미지 분류하기

    TensorFlow + Keras 사용


    1. 이미지 데이터를 파이썬 데이터로 변환하기

    먼저, Caltech 101 이미지 데이터 세트를 처리해서 image/5obj.npy라는 파일로 저장!

    src/ch7/caltech101_makedata.py 실행


    1) 이미지 세트가 들어있는 폴더 이름, 분류 대상 카데고리를 지정한다.

    2) 이미지 크기를 지정한다. 색상 데이터를 나타내기 위해 각 픽셀마다 RGB값을 나타내는 3개의 데이터가 필요하다.  1개의 이미지는 3 * 64 * 64 로 나타낸다.

    3) 이미지 데이터를 읽는다.

      X : 실제 이미지 데이터

      Y : 이미지가 어떤것을 나타내는지 설명하는 레이블 데이터

    4) 레이블을 생성한다. 카테고리의 수만큼 요소를 갖게 한다.

    카테고리 이름
    레이블 데이터
    chair(0)

    [1, 0, 0, 0, 0]

    camera(1)[0, 1, 0, 0, 0]
    butterfly(2)[0, 0, 1, 0, 0]
    elephant(3)[0, 0, 0, 1, 0]
    flamingo(4)[0, 0, 0, 0, 1]

    5) 이미지 파일을 찾는다.

    6) 이미지 파일을 읽고 색상 모드를 RGB로 변환하고, 64*64 픽셀로 리사이즈한다.

       그리고 Numpy의 asarray()메서드를 사용해 PIL의 Image데이터를 Numpy 배열 데이터로 변환한다.

    7) 무작위로 데이터를 학습 전용과 테스트 전용으로 구분한 뒤 Numpy의 save() 메서드로 파일을 저장한다.

    2. CNN으로 분류해보기

    tensorflow구동 환경에서 keras 설치 필요


    src/ch7/caltech101_keras.py 실행

    [출력 결과]

    ...

    ...

    Epoch 44/50
    250/250 [==============================] - 6s 25ms/step - loss: 1.8932e-04 - acc: 1.0000
    Epoch 45/50
    250/250 [==============================] - 6s 26ms/step - loss: 0.0054 - acc: 0.9992
    Epoch 46/50
    250/250 [==============================] - 7s 27ms/step - loss: 2.7914e-04 - acc: 1.0000
    Epoch 47/50
    250/250 [==============================] - 7s 27ms/step - loss: 7.1504e-05 - acc: 1.0000
    Epoch 48/50
    250/250 [==============================] - 6s 25ms/step - loss: 8.8772e-05 - acc: 1.0000
    Epoch 49/50
    250/250 [==============================] - 6s 24ms/step - loss: 1.6881e-05 - acc: 1.0000
    Epoch 50/50
    250/250 [==============================] - 6s 23ms/step - loss: 2.9167e-05 - acc: 1.0000
    84/84 [==============================] - 1s 7ms/step
    loss= 0.57535016252881
    accuracy= 0.8904761757169452


    1) 이미지 데이터 읽기. 읽은 후에는 데이터 정규화하기

    2,3) CNN 모델 구축하기. (이 부분은 이미 있는 모델 가져다 쓰는거임. 모델 만드는 일은 연구소에 근무하거나 박사분들이 대부분 하는 일.. 엔지니어는 구축된 모델을 가져다 씀). 모델을 살펴보려면 논문을 보면 된다.

    4) 데이터를 넣어 모델을 학습함

    5) 최종적으로 테스트 데이터로 모델을 평가함


    근데, 89% 적중률은 만족스러운 결과가 아님. 그래서 정밀도를 높여보고자 한다.


    3. 정밀도를 높이는 방법

    정밀도를 높이기 위해서는 데이터가 많아야 한다. 앞서서 사용한 데이터는 꼴랑 각 카테고리별 60개씩 해서 약 360개 이미지 데이터다.

    샘플을 늘리기 위한 방법으로는

    이미지의 각도를 바꾸거나, 반전하건, 확대 축소 하거나, 평균화하거나, 노이즈를 넣거나, 명암 대비와 감마값을 바꾼 이미지를 만들어 사용하는 방법이 있다.

    이미지의 수를 늘릴 때 활용할 수 있는 PIL(Image)매서드는

    Image.transpose(v) : 90도 단위로 이미지를 회전하거나 반전

    Image.rotate(angle): 이미지를 angle도 만큼 회전

    과같이 있다.


    caltech101_makedata2.py 실행


    코드를 실행해보면 

    반전된 데이터, 각도가 틀어진 데이터, 등등이 추가됨을 알 수 있다.


    이제 어떤 이미지를 잘못 분류했는지 확인해보자.

    predict()메서드를 호출해서 예측에 실패한 이미지를 image/error폴더에 저장할 수 있다.


    caltech101_predict.py


    위 코드를 실행하여 분류에 실패한 이미지를 뽑아보니 약 151개정도 되었다.

    이미지를 더 늘린 후 모델을 훈련하고 다시 예측해보자!

    이미지를 늘리는 데 사용한 코드는 (실제 png 뽑아보지 않고 그냥 .npy 파일 내에 데이터 입력함)


    caltech101_makedata2.py


    [출력 결과]

    ...

    ...

    Epoch 44/50
    3995/3995 [==============================] - 84s 21ms/step - loss: 0.0720 - acc: 0.9944
    Epoch 45/50
    3995/3995 [==============================] - 84s 21ms/step - loss: 0.0479 - acc: 0.9958
    Epoch 46/50
    3995/3995 [==============================] - 85s 21ms/step - loss: 0.0252 - acc: 0.9972
    Epoch 47/50
    3995/3995 [==============================] - 86s 22ms/step - loss: 0.0304 - acc: 0.9972
    Epoch 48/50
    3995/3995 [==============================] - 86s 22ms/step - loss: 0.0326 - acc: 0.9974
    Epoch 49/50
    3995/3995 [==============================] - 86s 21ms/step - loss: 0.0472 - acc: 0.9960
    Epoch 50/50
    3995/3995 [==============================] - 86s 21ms/step - loss: 0.0440 - acc: 0.9964
    99/99 [==============================] - 1s 6ms/step
    loss= 1.3939824778624255
    accuracy= 0.9030302883398653


    이 모델을 학습하는 데 걸린 시간은 1시간 30분이었다...

    아무튼 아주 미묘하지만 정확도가 0.01정도 올랐다;;;;

    결론은 이정도 데이터로는 택도 없다는 것

    더 많은 데이터로 훈련하여 정확도를 높일 필요가 있다.


    다시 분류에 얼마나 성공/실패하는지를 확인하고자 caltech101_predict.py 코드를 돌려보면

    분류에 실패한 개수는 약 79개로 줄어들었다!

    151개 → 79개로 그래도 많은 발전을 보임을 확인하였다.


    4. 학습 완료한 모델 저장하기

    keras로 모델을 저장할 때는 HDF5형식의 데이터를 다루는 h5py 모듈을 사용함.

    pip install h5py


    # 모델 훈련하기 --- (※4)
    hdf5_file = "./image_deeplearning/image/5obj-model.hdf5"
    if os.path.exists(hdf5_file):
        # 기존에 학습된 모델 읽어들이기
        model.load_weights(hdf5_file)
    else:
        # 학습한 모델을 파일로 저장하기
        model.fit(X_train, y_train, batch_size=32, nb_epoch=50)
        model.save_weights(hdf5_file)


    다음 코드를 삽입한다.

    모델을 저장할 때는 model.save_weights()

    모델을 읽어 들일 때는 model.load_weights() 메서드를 사용한다.

    5. 결론

    1. 학습기에 어떤 데이터를 전달하느냐가 중요하다
    2. 데이터를 미리 가공(전처리)해두는 것이 좋다
    3. 입력할 이미지가 부족할 때는 이미지를 회전하거나 해서 수를 늘리면 된다


    Comments