Blog Content

    티스토리 뷰

    라멘 메뉴 이미지 판별하기 [머신러닝, 딥러닝 실전 개발 입문]

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

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


    [이미지와 딥러닝 - 라멘 메뉴 이미지 판별하기]

    책의 예제는 규동 메뉴로 가지고 했지만, 나는 라멘 메뉴를 선택하여 실습해보았다.

    1. 스크레이핑으로 이미지 수집하기
    2. 데이터를 전처리/가공하기
    3. 머신러닝으로 분석하기


    CNN 알고리즘 사용

    목표 : 라멘 사진을 던져주면 무슨 규라멘인지 알려주고 칼로리도 예측해보장


    1.스크레이핑부터 시작하기

    플리커, 인스타그램과 같은 이미지 공유 사이트에서 수집할 수 있으나 가입을 해야함...가입하고 token얻고 귀찬

    포도주(Photozou)라는 사이트는 가입 없이 사용 가능

    포도주 검색 API를 사용해보자


    ramen_downloader.py

    프로그램을 실행 후 각각 라멘 이미지를 100~500개 정도 다운받았다.


    2. 교사 데이터 만들기 - 수작업으로 라멘 분류하기

    일일히 라멘을 분류하기엔 너무 힘들기 때문에 애초에 돈코츠라멘, 미소라멘..이런식으로 특정 이름을 검색해서 각 폴더에 이미지를 내려받았고

    그 후 내려받은 데이터를 살펴보면서 해당 이미지에 맞지 않는 것은

    others라는 폴더에 따로 옮겨 두었다.


    3. 이미지 데이터를 숫자 데이터로 변환하기

    다운받은 이미지를 학습 데이터로 읽어 들일 수 있도록 Numpy로 변환한다.

    ramen_makedate.py

    [출력 결과]

    --- cupramen 처리 중
    --- misoramen 처리 중
    --- shoyuramen 처리 중
    --- tonkotsuramen 처리 중
    --- others 처리 중
    ok, 1185


    4. 일단 CNN으로 학습해보기

    ramen_keras.py

    [출력결과]

    ...

    ..

    ..

    Epoch 29/30
    888/888 [==============================] - 11s 13ms/step - loss: 0.0182 - acc: 0.9950
    Epoch 30/30
    888/888 [==============================] - 11s 13ms/step - loss: 0.0203 - acc: 0.9941
    297/297 [==============================] - 1s 3ms/step
    loss= 1.007739837924238
    accuracy= 0.8080808096863203


    정답률이 0.80(80%)로 나왔다.

    정밀도를 올리기 위해 데이터 수를 늘려보자


    5. 판정 정밀도 올리기

    이미지의 각도를 변경 or 반전하여 데이터 수를 늘리자

    ramen_makedata2.py


    [출력결과]

    ok, 12087

    1295개였던 데이터를 12087개로 늘렸다.


    다시 ramen_keras.py 를 수행해보자! 시간이 꽤 걸림

    ramen_makedata2.py를 살펴보면

    (1) 이미지 데이터를 읽어 들이고, Numpy 형식으로 데이터를 변환하는 함수다.

    훈련 전용 데이터를 조금 회전하거나 수평 반전한 뒤 이미지 데이터로 등록하는 것이다.

    이 부분이 바로 인식의 정밀도를 높이기 위한 데이터 가공 처리의 포인트!

    (2) 폴더마다 구분돼 있는 파일을 수집한다. 

    (3) 파일 목록을 섞고, 훈련 전용 데이터와 테스트 전용 데이터로 구분한다.

    그리고 훈련 데이터는 정밀도를 높일 수 있도록 회전 처리 등으로 데이터 수를 늘려준다.

    테스트 데이터는 회전시켜도 의미 없으므로 따로 회전하거나 수평 반전하는 처리는 하지 않아도 된다.

    ※주의점

    잘못된 처리의 예:

    (1) 이미지 파일을 모두 읽는다.

    (2) 수평 반전 등을 해서 이미지 데이터 수를 늘린다.

    (3) 섞은 뒤에 훈련 데이터와 테스트 데이터를 구분한다.

    위와 같이 하면, 훈련 전용 데이터와 비슷한 이미지가 테스트 데이터와 섞여 버리기 때문에, 테스트할 때 정답률이 높게 나온다.


    따라서 이렇게 해야함.

    (1) 이미지 파일을 모두 읽는다.

    (2) 섞은 뒤에 훈련 데이터와 테스트 데이터를 구분한다.

    (3) 훈련 데이터를 가지고 수평 반전 등을 해서 학습 정밀도를 높인다.


    ramen_keras.py를 수행한 결과를 보면

    '[출력결과]

    ....

    Epoch 29/30
    12087/12087 [==============================] - 159s 13ms/step - loss: 0.0456 - acc: 0.9944
    Epoch 30/30
    12087/12087 [==============================] - 159s 13ms/step - loss: 0.0342 - acc: 0.9951
    474/474 [==============================] - 1s 3ms/step
    loss= 2.2953658003344315
    accuracy= 0.8253164562997939


    1시간 30분 훈련해서 예측 한 결과 정확도가 2%가 올랐다..;


    6. 명령줄로 이미지 판정할 수 있게 하기

    훈련한 모델을 기반으로 명령줄에서 이미지 데이터를 전달하면,

    라멘의 종류를 판별하고, 라멘 메뉴이름과 칼로리를 출력해보자!

    ramen-checker.py

    명령줄에 python3 ramen-checker.py <이미지> ...

    를 입력하여 테스트한 결과는 다음과 같다.

    & C:/ProgramData/Anaconda3/envs/tensorflow/python.exe d:/workspace_my/my-machine-learning/image_deeplearning/ramen-checker.py D:\workspace_my\my-machine-learning\image_deeplearning\image\ramen\cupramen\221271503_thumb.jpg D:\workspace_my\my-machine-learning\image_deeplearning\image\ramen\misoramen\249769493_thumb.jpg D:\workspace_my\my-machine-learning\image_deeplearning\image\ramen\shoyuramen\244353109_thumb.jpg D:\workspace_my\my-machine-learning\image_deeplearning\image\ramen\tonkotsuramen\8733252_thumb.jpg D:\workspace_my\my-machine-learning\image_deeplearning\image\ramen\others\2693604_thumb.jpg

    '[출력 결과]

    +입력: D:\workspace_my\my-machine-learning\image_deeplearning\image\ramen\cupramen\221271503_thumb.jpg
    |라멘 이름: 미소 라멘
    |칼로리: 658
    +입력: D:\workspace_my\my-machine-learning\image_deeplearning\image\ramen\misoramen\249769493_thumb.jpg
    |라멘 이름: 미소 라멘
    |칼로리: 658
    +입력: D:\workspace_my\my-machine-learning\image_deeplearning\image\ramen\shoyuramen\244353109_thumb.jpg
    |라멘 이름: 소유 라멘
    |칼로리: 768
    +입력: D:\workspace_my\my-machine-learning\image_deeplearning\image\ramen\tonkotsuramen\8733252_thumb.jpg
    |라멘 이름: 돈꼬츠 라멘
    |칼로리: 836
    +입력: D:\workspace_my\my-machine-learning\image_deeplearning\image\ramen\others\2693604_thumb.jpg
    |라멘 이름: 기타
    |칼로리: 0


    컵라멘은 잘 못찾는 듯 하고,

    다른 것들은 그래도 잘 찾는 편인 것 같다.


    정리

    1. CNN을 이용하면 이미지 분류를 할 수 있다.
    2. 머신러닝은 데이터를 모으고 가공하는 것이 중요하다
    3. 이미지를 회전,반전하면 부족한 입력 데이터를 보완할 수 있다.


    Comments