Link
01-28 13:27
«   2021/01   »
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            
Archives
Today
1,065
Total
1,307,089
관리 메뉴

꿈 많은 사람의 이야기

파이썬 케라스(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 컨볼루션 레이어를 구축해서 이미지를 분류할 수 있습니다~

독학하기 참 힘드네요 ㅠ

반응형
160 Comments
  • 이전 댓글 더보기
  • 프로필사진 안녕하세요 2020.06.05 22:25 ith K.tf_ops.device('/device:GPU:0'):
    model = Sequential()
    model.add(Conv2D(32, (3,3), padding="same", input_shape=X_train.shape[1:], activation='relu'))
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Dropout(0.25))부분에서 RuntimeError: /job:localhost/replica:0/task:0/device:GPU:0 unknown device.의 오류가 뜨는데 이 경우에는 어떻게 해야하는지 아시나요ㅜㅜ?
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.06.06 13:13 신고 안녕하세요.
    해당 코드는 keras에서 gpu가 있음을 인식할 때 동작되는 코드입니다.
    님의 PC 환경에서는 gpu가 인식이 안되서 그런것 같아요.
    해당 with문 없애시고 동작시키시면 될 것 같습니다 ~
  • 프로필사진 keras 2020.06.06 04:34 좋은 글 감사드리며 하나 여쭙겠습니다.
    callback 함수 파트에서 NameError: name 'checkpoint' is not defined 이렇게 에러가 뜨는데 어찌해야하는지 아십니까?
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.06.06 13:14 신고 안녕하세요.
    해당 오류는 callback 함수에 사용되는 Callback 객체를 생성하지 않아서 나는 오류입니다.
    checkpoint를 담당하는 callback 객체를 생성하는 부분이 코드에 있을겁니다. 그 부분을 확인해주세요~
  • 프로필사진 kjw 2020.06.06 14:37 caltech_dir = "./multi_img_data/imgs_others/train" 이 부분이 약간 이해가 안되는데 무슨 의미 인가요??
    그리고 사진이 충분히 있으면 imagedatagenerate를 안해도 되는건가요?
    만약 카테고리 사진이 충분히 있다면 어디서부터 코드를 실행하는게 좋을까요..?
    캐글에서 이미지를 다운 받았습니다!
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.06.07 13:24 신고 안녕하세요.
    해당 부분의 의미는 train 데이터가 있는 디렉토리 경로입니다.
    사진이 충분히 있다면 imagedatagenerate 부분을 생략하고 하시면 됩니다 ~
  • 프로필사진 하라곤 2020.06.06 22:08 안녕하세요. CNN 과제를 하는데 수진님의 포스터가 굉장히 큰 도움이 되고 있습니다! 감사합니다!
    다름이 아니라, 중간에 validation 과정을 수행하는 코드를 진행 중인데 ( history = model.fit(X_train, y_train, epochs = 50, batch_size = 32, validation_split = 0.125, callbacks = [checkpoint, early_stopping]) )

    여기서 이러한 에러가 발생을 하더라고요. ValueError: Error when checking target: expected dense_53 to have 2 dimensions, but got array with shape (837, 64, 64, 3)

    이보다 앞선 코드인 summary 파트에서는 결과가 ( Layer - dense_53 (Dense) / Output Shape - (None, 25) / Param # - 6425 ) 으로 떠서 2 dimensions인 것 같은데, 왜 저런 error가 발생하는지를 잘 모르겠습니다. 혹시 어떠한 이유로 이러한 error가 뜨는지 알려주실 수 있으신가요?

    다시 한 번 좋은 글 감사합니다!!
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.06.07 13:28 신고 안녕하세요~ 도움이 되고 있으시다면 다행입니다 ㅎㅎ

    음.. 일단은 중간에 validation 과정을 수행한다는 것이 어떤 의미인 줄 모르겠습니다.
    코드를 보니 training 과정을 말씀하시는 것 같은데 맞을까요?

    에러를 보아하니 shape 문제인 것 같습니다. model을 통과 시킬 때 image의 shape가 어떻게 변화할 지 잘 구성해야합니다.

    그래서 저도 코드상에 input_size와 output size를 고민하면서 넣었었구요.
    Dense에서 받을 때 앞선 layer에서 output 형상이 잘 맞아떨어지도록 해야합니다 ~
  • 프로필사진 여쭤봅니다.. 2020.06.07 13:55 prediction = model.predict(X) 이부분에서
    ValueError: Error when checking input: expected conv2d_1_input to have 4 dimensions, but got array with shape (0, 1) 일케 오류가 뜨는데 X에 데이터를 어떤식으로 넣야할까요ㅜㅜ? X="폴더경로" 이런식으로 넣는걸까요ㅜㅜ?
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.06.07 19:25 신고 안녕하세요~
    일단, 해당 오류가 뜨신 대부분의 사용자분들은 폴더 경로를 잘못 설정하셨던 경험이 대부분입니다.

    X가 들어가는 데이터가 있는 폴더 경로를 정확히 지정하셔서 데이터 입력이 잘 들어가도록 해주세요~
  • 프로필사진 Yong 2020.06.07 14:59 혹시 제가 버섯종류로 하려고 하는데 4가지 버섯과 그 외의 버섯들은 다른 문구들을 뜨게 하고 싶습니다.
    정확률이 몇 퍼센트 이하면 등록되지 않은 버섯입니다. 이런 식으로 값을 나오게 하고 싶은데 방법이 있을까요..? 지금 4가지 버섯에 대해서는 값이 잘 나오고 있습니다. 4가지 버섯은 종류를 잘 분별하고 있는데 그 외 다른 버섯을 넣었을 때 4가지 버섯과 어떻게든 비슷한 부분은 찾아서 그 버섯으로 인식하는게 같더군요..
    블로그 글은 몇번은 봤을 정도로 많이 봤습니다. 좋은 글 감사합니다.
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.06.07 19:26 신고 안녕하세요.
    등록되지 않는 버섯에 대해서 나오는 것은 안될겁니다.
    왜냐하면 모델 자체가 4가지 버섯에 대해 훈련을 진행했고, 모델 입장에선 등록되지 않은 버섯이 나와도 그 4가지 버섯 중 가장 높은 확률을 가진 output 값을 내기 때문입니다.
  • 프로필사진 안녕하세요! 2020.06.07 16:25 if i[0] >= 0.8 : print("해당 "+filenames[cnt].split("\\")[1]+"이미지는 "+pre_ans_str+"로 추정됩니다.")
    해당 (파일이름) 이미지는 네모으로 추정됩니다.
    이런식으로 이부분을 출력하는데 이미지의 이름과 확장자명이 아니라 폴더명만 출력되는데 왜그런지 아실까요ㅜㅜ?
    caltech_dir = "파일이름"
    files = glob.glob(caltech_dir+"/*.*")
    이런식으로 똑같이 한건데 모르겠어서요ㅜ
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.06.07 19:27 신고 안녕하세요.
    아마 저와 폴더 경로가 달라서 그럴겁니다.
    split 메소드는 문자열을 /를 기반으로 잘라주니까요. 안녕하세요 님의 환경에 맞추어서 split으로 나온 list에 대한 index 값을 다르게 해주세요~
  • 프로필사진 이미지 2020.06.12 03:25 안녕하세요! 게시물 잘 봤습니다. imagegenerator를 활용하고싶은데 쉽지않네요. 사용한 코드에서 앞부분에 추가로 뭔가 더있는건가요? fname같은 경우 위 사진은 하나의 이미지에 대해서만 실행되는 것 같아서요!
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.06.12 11:36 신고 안녕하세요~
    imagegenerator 활용 예제는 김태영님의 케라스 블로그를 보시면 금방 이해가 되실겁니다!
    https://tykimos.github.io/2017/06/10/CNN_Data_Augmentation/
    확인해보셔요~
  • 프로필사진 이미지 2020.06.12 20:20 답변감사합니다! 저 하나 더 궁금한점은 처음에 imagegenerator이용해서 여러가지 이미지를 만든 후 그 생성된 이미지들 까지 포함해서 train,validation,test 데이터로 활용하셨나요?
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.06.13 11:07 신고 아뇨~ train과 validation set에서만 사용했습니다.
    test data는 따로 만들어놨었어요~
    그 당시에 이렇게 하는 방법을 권장 받았기도 했습니다. 왜냐하면, imageGen으로 생성한 이미지는 test set으로 쓰기가 애매해서(실 데이터가 아니므로) 그렇게 했었던 기억이 있습니다.
  • 프로필사진 독학생 2020.06.15 08:24 매우 알기쉽게 잘 설명된글 너무너무 감사합니다. 덕분에 CNN을 직접 해보는데 많은 도움이 되었습니다.
    evaluation을 위한 이미지가 따로 폴더로 카테고리에 나눠져있는데 폴더로 evaluation하기위해 수정해볼려했더니 몇일째 잘 안되더라고요. 그래서 참고하고 싶은데 github에서 evaluation하는 부분에
    #이 비교는 그냥 파일들이 있으면 해당 파일과 비교. 카테고리와 함께 비교해서 진행하는 것은 _4 파일
    라고 되있는 부분이있는데 _4.py가 어디에 있는파일인가요?
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.06.15 11:58 신고 안녕하세요. 도움이 되셨다니 다행입니다.

    아 해당 코드에서 _4.py에 있다는 내용은 제가 실수로 달아 놓은거에요 ㅠㅠ 죄송합니다.
    _4 파일이라고 쓰여져 있는 부분이 해당 코드로 옮겨 온 것입니다.
    저대로 그냥 하시면 됩니다.
    말씀하신대로 경로만 잘 맞춰주시면 됩니다!
  • 프로필사진 감사합니다다 2020.06.16 00:08 좋은 글 감사합니다! 저는 npy파일로 저장하는거에 대해 여쭤보고 싶은게 있습니다! 저는 현재 train 데이터 약 6천개, test 데이터 약 천오백개로 미리 구분을 해놓고 모델을 만드려고 하는데 이런 상황에
    X_train, X_test, y_train, y_test = train_test_split(X, y)
    xy = (X_train, X_test, y_train, y_test)
    np.save("./numpy_data/multi_image_data.npy", xy) => 이 학습/테스트 전용 데이터로 구분하는 코드를 사용하는 대신 학습데이터/테스트데이터를 따로따로 npy파일로 저장하는 코드를 사용해야 할 것 같습니다! 이 때 어떤 식으로 수정하면 좋을지 조언 부탁드립니다 ㅠㅠ 감사합니다!
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.06.16 10:22 신고 안녕하세요.
    이미 데이터가 그렇게 구축이 되어 있으시다면

    따로 저렇게 저장하실 필요가 없습니다.
    그냥 있는 것을 numpy로 변환한 뒤에 사용하시면 될 것 같아요.
    그리고 따로따로 데이터를 저장 및 load 하시면 됩니다 ~
    굳이 저 코드에 얽매이실 필요가 없으실 것 같아요!
  • 프로필사진 감사합니다다 2020.06.16 11:59 아 아닙니다 감사합니다!!!
  • 프로필사진 2020.06.17 23:28 안녕하세요 ~ 딥러닝 입문자입니다~! 알기 쉽게 설명해주신 글을 읽으며 공부 중인데 넘파이 파일로 바꾸는 코드에서 궁금한게 생겼습니다!
    pixels = image_h * image_w * 3 여기서 마지막에 *3 한건 이미지가 컬러이기 때문인가요 아니면 다른 의미가 있나요~?
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.06.18 09:42 신고 안녕하세요.
    넵 맞습니다. 3인 이유는 RGB 3채널이기 때문에 그렇습니다~
  • 프로필사진 감사합니다 2020.06.18 21:27 코딩의 제일 마지막에
    for i in prediction:
    pre_ans = i.argmax() # 예측 레이블 / 최대값에 해당되는 인덱스 반환
    print(i) # '게' 이면 [0.000, 0.000, 1.000, 0.000 ]
    print(pre_ans) # '게' 이면 3
    pre_ans_str = ''
    if pre_ans == 0: pre_ans_str = "비행기"
    elif pre_ans == 1: pre_ans_str = "불상"
    elif pre_ans == 2: pre_ans_str = "나비"
    else: pre_ans_str = "게"
    if i[0] >= 0.8 : print("해당 "+filenames[cnt].split("\\")[1]+"이미지는 "+pre_ans_str+"로 추정됩니다.") #어차피 1 이상 아니야?
    if i[1] >= 0.8: print("해당 "+filenames[cnt].split("\\")[1]+"이미지는 "+pre_ans_str+"으로 추정됩니다.")
    if i[2] >= 0.8: print("해당 "+filenames[cnt].split("\\")[1]+"이미지는 "+pre_ans_str+"로 추정됩니다.")
    if i[3] >= 0.8: print("해당 "+filenames[cnt].split("\\")[1]+"이미지는 "+pre_ans_str+"로 추정됩니다.")
    cnt += 1
    # print(i.argmax()) #얘가 레이블 [1. 0. 0.] 이런식으로 되어 있는 것을 숫자로 바꿔주는 것. ex) --> 0
    # 즉 얘랑, 나중에 카테고리 데이터 불러와서 카테고리랑 비교를 해서 같으면 맞는거고, 아니면 틀린거로 취급하면 된다.
    # 이걸 한 것은 _4.py에.

    1. 본 코딩의 print(i) 를 하신 걸 봤는데
    i 가 [1, 0, 0, 0] 이런식으로 전부 1로 출력이 되어 0.8보다 크게 나오는데 왜 굳이 0.8을 적어주신건가요???

    정말 도움많이 받았습니다. 감사합니다 ㅠㅠ!!
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.06.19 11:26 신고 안녕하세요.
    저 코드가 원래는 threshold를 표현하려고 했습니다.
    말씀하신대로 argmax 결과로 무조건 1이 나오지만, 표현?만 그렇게 해둔거에요 ㅎㅎ
  • 프로필사진 도움이 많이 되었어요 2020.06.19 15:59 X_train, X_test, y_train, y_test = train_test_split(X, y)
    xy = (X_train, X_test, y_train, y_test)

    1. 이 부분에서 train과 test를 나누는 비율을 부여를 안해주었는데 뒷부분을 보니가 train이 2673개라고 나와있더라구요!! 나뉘는 기준이 무엇인가요??


    감사합니다ㅜㅜㅠ!!
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.06.20 15:56 신고 안녕하세요 ~
    네 따로 값을 넘겨주지 않았고, 그냥 default로 하도록 했습니다.
    보통은 0.2 정도 주면 됩니당
  • 프로필사진 감사합니다 2020.06.19 23:46 np.random.seed(5)
    iterations = 5

    path1 = 'C:/Users/park/Desktop/CNN Image _ test'
    result = 'C:/Users/park/Desktop/CNN Image _ result'
    file_list = os.listdir(path)
    file_list.sort()

    generator = ImageDataGenerator( rescale = 1. / 255,
    rotation_range = 15,
    width_shift_range = 0.1,
    height_shift_range = 0.1,
    shear_range=0.2,
    zoom_range=[0.8, 2.0],
    horizontal_flip=True,
    vertical_flip = True,
    fill_mode = 'nearest')

    for num in file_list:
    path2 = path1 + '/' + num
    for fname in glob.glob(path2 + "/*.png"):
    img = load_img(fname)
    x = img_to_array(img)
    x = x.reshape((1,) + x.shape)

    i=0
    for batch in generator.flow(x, batch_size=1, save_to_dir=result+'/'+num,
    save_prefix='plus_', save_format='png'):
    i += 1
    if i >5:
    break
    else:
    continue

    path1 = 'C:/Users/park/Desktop/CNN Image _ test'
    이 폴더 안에 cat 과 crab의 폴더가 각각 들어있고
    result = 'C:/Users/park/Desktop/CNN Image _ result'
    저장할 result 폴더 안에도 cat과 crab의 폴더가 생성되어있어서
    위와 같은 코딩으로 만들어보았는데 오류는 뜨지않지만 result 폴더안에 저장이 안되는데 이건
    어떻게 해결해야할까요..???
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.06.20 15:59 신고 안녕하세요~
    오류는 뜨지 않지만, 코드 자체가 동작이 제대로 안한 것일 수도 있습니다.
    중간에 for num in file_list 부분을 돌 때 결과 값이 제대로 나오고 있는지 print 등을 써보셔서 확인해주세요 ~

    의심되는 부분 한 줄 한 줄 입력해보시면서 잘 나오는지 확인하시면 금방 찾을 수 있을것 같아요!
  • 프로필사진 글 잘읽었습니다~ 2020.06.28 17:52 안녕하세요! 소중한 소스 올려주셔서 진심으로 감사드립니다.
    개발자님의 소스대로 코딩을 했습니다. 그런데 처음부터 막히내요ㅠㅠ 머신러닝은 처음이라 그냥 따라해보는중인데 여러가지로 많이 부족합니다.. 그래서 여쭙습니다!
    import os, re, glob
    import cv2
    import numpy as np
    from sklearn.model_selection import train_test_split

    caltech_dir = "../Users/USER20/tomato"
    categories = ["greentomato", "redtomato"]
    nb_classes = len(categories)

    imge_w = 64
    image_h = 64
    pixels = image_h * image_w * 3

    X = []
    Y = []

    for idx, cat in enumerate(categories):
    label = [0 for i in range(nb_classes)]
    label[idx] = 1
    image_dir = caltech_dir + "/" + cat
    files = glob.glob(image_dir + "/*.jpg")

    for i, f in enumerate(files):
    img = image.open(f)
    img = img.convert("RGB")
    img = img.resize((image_w, image_h))
    data = np.asarray(img)

    X.append(data)
    Y.append(label)
    np.save("./image_data.npy",X,Y)

    이렇게 저장하고,

    categories = ["greentomato", "redtomato"]
    nb_classes = len(categories)
    image_w = 64
    image_h = 64

    X_train, X_test, Y_train, Y_test = np.load("./image_data.npy")

    이렇게 했더니
    >> not enough values to unpack (expected 4, got 0) 이런 결과가 나왔습니다ㅠㅠ
    print(X.shape)
    print(Y.shape) 했더니
    (0,)
    (0,) 이렇게 출력이 됩니다.ㅠㅠ
    위의 댓글중에 대부분 경로 문제라고 하셔서 참고로 제 토마토 파일 경로는 C:\Users\USER20\tomato로, tomato 폴더 속에 "greenstomato"와 "redtomato" 폴더가 있습니다.
    caltech_dir을 잘못쓴것일까요..?ㅠㅠㅠ 도와주시면 진심으로 감사드리겠습니다.ㅠㅠㅠ (혹시 저장도 D드라이브에 저장되어야하나요..?)
  • 프로필사진 글 잘읽었습니다~ 2020.06.28 19:02 헐,, 저 여기에 있는 소스 다 성공했어요... 진짜 경로 문제였네요...
    caltech_dir 에서 폴더 위치를 (제 위치는 C:/Users/USER20/tomato/ 입니당) 이렇게 변경했더니 다 성공했어요ㅠㅠㅠ 세상에ㅠㅠㅠ 진짜 소스 공유해주셔서 진심으로 감사드려요ㅠㅠㅠ 복받으실거에요ㅠㅠㅠㅠㅠ
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.06.28 20:36 신고 안녕하세요~
    오 ㅎㅎㅎ 다행입니다. 성공하셨군요.
    축하드립니다! 열공하세요
  • 프로필사진 감사합니다 2020.11.11 15:36 안녕하세요! 블로그 보고 참고하며 도움 받고 있습니다 감사합니다^^
    공유해 주신 코드에 보면 블로그 게시물과 달리
    train, val에 대한 loss값에 대한 그래프가 출력됩니다.

    코드를 수정해서
    train, val에 대한 accuracy 그래프 따로
    train, val에 대한 loos 그래프 따로
    를 출력하고 싶은데 잘 안됩니다..

    하는 방법이나 코드 알려주시면 감사하겠습니다!
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.11.11 21:44 신고 안녕하세요.

    y_vloss = history.history['val_loss']
    y_loss = history.history['loss']

    에서 history.history[] 안에 accuracy가 있을겁니다.
    loss는 training에 대한, val_loss는 validation에 대한 것이니까, 아마 accuracy도 이렇게 나눠지지 않아있을까? 싶습니다. (정확하지는 않아요! 자세한 것은 history.history dictionary 결과 안 데이터를 봐야할 것 같은데 아마 있을겁니다.)
  • 프로필사진 좋은 설명 감사합니다 2020.11.13 12:48 안녕하세요 좋은 설명 잘 듣고 깃허브에 있는 소스를 가지고 이미지 분류기를 만들었습니다.

    5종류의 이미지를 분류하는 모델을 만들었고 데이터셋은 각 클래스 당 약 4500개로 학습을 진행하였습니다.

    블로그에서 설명하신 방식과 조금 다른점이 있다면 test셋을 따로 만들지 않고 train_test_split 에서 test_size=0.2 로 진행했고 validation set 은 깃허브에서 설명하신대로 test 셋을 쓰지 않고, validation_split=0.2 로 진행했습니다.

    모델 그래프는 loss 와 val_loss 둘다 0으로 수렴하는 모습과 acc와 val_acc도 1에 점점 수렴하는 모습을 보였습니다.
    그런데 이제 이 모델을 갖고 다른 이미지들을 테스트 해보는데 잘 못맞추는 현상이 있는데요

    모델을 최종적으로 complie 하는 과정에서 잘못된 부분이 있나 싶어 여러가지 optimizer로 바꿔가며 진행했음에도 모델 정확도 자체는 좋으나 다른 이미지 테스트에서 잘 맞추지를 못합니다.ㅜㅜ

    한가지 종류의 물체로만 인식하는 현상이 좀 심한거 같은데 이 부분 해결할 방법이 있나요?

    5개의 다른 이미지들을 맞추라고 했을때 predict 결과가 주로
    [[0.000, 0.000, 1.000, 0.000, 0.000],
    [0.000, 0.000, 1.000, 0.000, 0.000],
    [0.000, 0.000, 1.000, 0.000, 0.000],
    [0.000, 0.000, 1.000, 0.000, 0.000],
    [0.000, 0.000, 1.000, 0.000, 0.000]] 이런식으로 한가지 종류로만 예측을 해버립니다 ㅠㅠ

    정답은
    [[1.000, 0.000, 0.000, 0.000, 0.000],
    [0.000, 1.000, 0.000, 0.000, 0.000],
    [0.000, 0.000, 1.000, 0.000, 0.000],
    [0.000, 0.000, 0.000, 1.000, 0.000],
    [0.000, 0.000, 0.000, 0.000, 1.000]] 이건데요..

    제가 만든 모델은 주로 한가지 종류로만 예측하거나 아니면 예측을 하지 못하거나 이럽니다...ㅠㅠㅠ
    이런 현상을 혹시 어떻게 해결하시는지 알려주시면 감사하겠습니다...
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.11.13 13:00 신고 안녕하세요.
    일단 overfitting이 의심되네요.

    아마 이미지가 4500개 정도면 굉장히 부족한 이미지 개수일 것 같습니다. 제 기억이 맞다면 최소 1만 5천개 정도는 필요해야 어느정도 overfitting이 감소되는 것을 볼 수 있었습니다(개인적으로 했을 때는요!)

    그리고 아마 predict로 하면 확률로 나올탠데 이 확률 값의 threshold를 좀 낮춰주시는 것도 방법일 것 같습니다. 85% 이상일 때 맞다고 해놓건은 threshold가 0.85라고 말씀하시는게 맞을까요?

    argmax로 했을 때 결과는 어떠한지도 살펴보셔야 할 것 같습니다.

    아마도 오버피팅 같아서 저 데이터셋 점검부터하셔야 할 것 같아요!
  • 프로필사진 좋은 설명 감사합니다 2020.11.13 14:29 한 클래스당 15000개의 이미지가 필요하다는 말씀이신거죠? 그러면 제가 클래스당 데이터셋을 조금 더 늘려보는 식으로 진행해보겠습니다.
    threshold가 if문에서 i[0]>0.85 에서 0.85를 지칭하는 것인가요? 저는 이 85%를 말씀드렸던거에요
    답변 감사드립니다.
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.11.13 18:42 신고 네네 두 개다 맞습니다.
    데이터 늘려보시구, 그리고 데이터 퀄리티가 좋은지도 확인해보세요.

    네 그 threshold도 확인해보시면 도움이 될 것 같습니다!
  • 프로필사진 좋은 설명 감사합니다 2020.11.17 13:57 조언 주신대로 데이터셋을 늘리려고 Imagegenerator를 통해 5개 클래스 모두 이미지 증대를 시켰습니다. 각 클래스 당 15000개 이미지가 생성되었구요. 총 75000개 이미지로 학습을 진행했습니다.
    그러나 여전히 오버피팅이 해결되지 않았습니다 ㅠ 새로운 데이터들을 전에 말씀드린 것 처럼 그냥 한 종류로만 판단합니다..
    오버피팅이 해결이 안되는데 여러가지 방법들을 찾아보니까 해결하려면 1. 데이터 증대 2. validation_set 사용이라고 하더라구요. 1번은 이미지 증대를 통해 해결한 것 같고, 2번은 model .fit 에서 validation_split을 이용했는데 이렇게 validation_set을 갖추는것은 오버피팅을 해결하는데 큰 도움을 주지 못하나요?
    아 그리고 다중 카테고리 분류 모델은 softmax 함수를 사용하는것이 더 효율적인가요?
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.11.19 09:28 신고 안녕하세요.

    무조건적인 데이터 증식은 옳지 않습니다. 안에 있는 데이터 퀄리티가 만약 좋지 않은 상태에서 imagegenerator를 돌려봤자 안 좋은 데이터만 더 늘어나니까요.

    가장 좋은 방법은 더 다양한 image를 가지고 오는 것입니다. imagenerator 말구요!

    음 validation_split을 하셨을 때 validation loss는 어떻게 나오시나요? 이것도 오버피팅으로 나오실까요?
  • 프로필사진 좋은 설명 감사합니다 2020.12.02 18:05 validation_loss 값은 점점 0에 수렴해가는 모습이고, 딱히 오버피팅이 나는 것 같지 않은게 그래프가 울퉁불퉁하게 나오질 않아서요.. val_loss 나 다른 값들의 그래프들도 마찬가지로 울퉁불퉁한 모습이 아니라 오버피팅이 날 것 같지 않은데 나서 ㅠㅠ
    이제 떠오른 대처 방안으로 데이터셋을 다 엣지추출을 이용해서 진행하려고 하는데 이렇게 되면 기존보다 더 좋은 결과를 기대할 수 있을 까요?
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.12.02 19:51 신고 음 validation도 잘 떨어지는데 test를 했을 때 오버피팅이 나시는 것이죠?

    그러면 dataset 문제가 맞는 것 같습니다.
    1. 원본 training data / test data를 더 많이 수집하고
    2. 이 수집된 데이터가 정제가 잘 되어 있는지(이상한 이미지가 없는지 등) 노가다(?) 과정을 거친 후 다시 해본다

    위와 같은 방법을 해보는 것이 좋을 것 같아요!
    (제가 생각하기에는요!)
  • 프로필사진 감사합니다 2020.11.23 23:54 안녕하세요 CNN에 대해서 처음 배우고 있는 사람인데 덕분에 블로그 글을 보고 차근차근 나아가고 있습니다
    다만 지금 손실과 정확도가 loss: 1.1921e-07 - accuracy: 0.0000e+00 이렇게 뜨는 상황인데 어떻게 고쳐야하는지 아시나요??
    감사합니다!
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.11.25 11:18 신고 안녕하세요

    음.. 정확히 어떤 것을 고치고 싶으신걸까요???
    정확도가 안 나오시는게 문제일까요?
    loss가 안 나오시는게 문제일까요?
    아니면 옆에 e-07 이렇게 뜨는걸 고치고 싶으신걸까요?
  • 프로필사진 잘 봤습니다 2020.12.30 10:11 7. predict_multi_img_with_CNN.ipynb
    를 주피터 노트북에서 사용할 때 두번째 블록에서

    Kernel Restarting
    The kernel appears to have died. It will restart automatically.

    이런 문구가 뜨면서 계속 에러가 발생하네요ㅜ

    구글에 검색해서 conda update mkl, numpy 재설치 등 여러 방법을 써도 해결되지 않아서 질문드립니다
    어떻게 해결하면 좋을까요..
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.12.30 20:37 신고 안녕하세요.
    해당 에러는 코드상의 문제보단 커널이 죽는 문제인 것 같네요.
    혹시 메모리 등이 부족한 것 아닌가요?
    프로그램 상에서 메모리가 부족하면 그렇게 죽는 경우가 있습니다.
  • 프로필사진 잘 봤 2020.12.30 22:41 아 메모리 문제였군요.. 정말 많이 배워갑니다^^
    감사합니다
  • 프로필사진 잘 봤습니다 2020.12.30 22:50 또한

    prediction = model.predict(X)

    이 코드를 실행하면

    ValueError: Expect x to be a non-empty array or dataset.

    이런 에러가 뜨는데 구글에 검색해봐도 별다른 해결법을 주지 않더군요ㅜ

    ValueError Traceback (most recent call last)
    <ipython-input-37-e0e27905843c> in <module>()
    29 model = load_model('/content/model/dog_cat_classify.model')
    30
    ---> 31 prediction = model.predict(X)
    32 np.set_printoptions(formatter={'float': lambda x: "{0:0.3f}".format(x)})
    33 cnt = 0

    /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py in predict(self, x, batch_size, verbose, steps, callbacks, max_queue_size, workers, use_multiprocessing)
    1642 callbacks.on_predict_batch_end(end_step, {'outputs': batch_outputs})
    1643 if batch_outputs is None:
    -> 1644 raise ValueError('Expect x to be a non-empty array or dataset.')
    1645 callbacks.on_predict_end()
    1646 all_outputs = nest.map_structure_up_to(batch_outputs, concat, outputs)

    ValueError: Expect x to be a non-empty array or dataset.

    총 에러는 이렇게 떴어요
  • 프로필사진 이수진의 블로그 이수진의 블로그 2021.01.03 19:06 신고 해당 에러는 데이터가 들어가지 않아서 생기는 오류입니다. numpy에 데이터가 제대로 들어갔는지 확인해주세요!
  • 프로필사진 비전공코린이 2021.01.26 16:13 신고 구글코랩에서 체크포인트관련 오류가 계속떠서 CNN에서 계속 오류가떠서 공부하는 도중, 여기로왔네요 ㅎㅎ
    좋은 글 감사합니다! 부족한 부분을 더 알 수 있었지만 몇가지 질문이 생겼습니다.

    checkpoint를 .ckpt 파일로 저장을 해야하는건가요?
    또 체크포인트를 .h5 모델로 변환하는 방법도 알려주시면 감사하겠습니다!

    혹시 몰라서 제가 쓰는 코드도 첨부합니다.

    MODEL_DIR = './model'
    if not os.path.exists(MODEL_DIR):
    os.mkdir(MODEL_DIR)

    model_path = './model/check.ckpt'

    # early_stopping_callback
    checkpoint = ModelCheckpoint(filepath=model_path, monitor='val_loss', verbose=1, save_best_only=True)
    early_stopping = EarlyStopping(monitor='val_loss', patience=10)

    읽어주셔서 감사합니다!
  • 프로필사진 이수진의 블로그 이수진의 블로그 2021.01.26 20:01 신고 안녕하세요!
    음 일단 텐서플로 2.x로 넘어오면서 조금 바뀐 부분도 있던 것으로 기억합니다.
    이 블로그 글이 조금 시간이 지난 글이라, 현재와 맞지 않을 수도 있는점 참고 부탁드립니다.

    당시 기준으로는 checkpoint는 model_name을 기준으로 해당 model을 계속 바라보며, 모델의 성능이 좋아지면 저장하도록 설계되어 있었습니다.

    그리고 확장자를 .model(혹은 ckpt)대신에 h5로 하시면 되는 것으로 기억합니다.

    자세한 것은 텐서플로2.x 문서를 봐야알 것 같아요!!
  • 프로필사진 비전공코린이 2021.01.26 21:56 신고 답변 감사합니다!

    혹시 코드 한줄 한줄을 공부할 수 있는 사이트나 책이 있을까요?

    올려주신 코드들은 이제 전체적인 흐름은 이해를 하고있지만,
    알고있는 내용을 예를들면 binary_crossentropy를 언제쓸지, 그리고 이와 같은 상황이 아니면 어떤 함수를 써야하는지를 자세히 공부를 하고싶습니다!
    코드 한줄 한줄을 완벽하게 이해하고싶은데 쉽게 설명한 자료를 찾기가 힘드네요..

    계속 다른분들에게 질문을 하고 이수진님의 블로그를 보며 배워왔습니다!
    계속 너무 쉬운 것만을 질문하는 것같아서.... 제대로 배우고싶습니다!
    추천 부탁드려도 될까요?
  • 프로필사진 이수진의 블로그 이수진의 블로그 2021.01.27 17:19 신고 정말 기초적인 부분부터 시작하실꺼면
    밑바닥부터 시작하는 딥러닝 책이 정말 좋구요!
    (단, 이 책은 Keras 코드가 아닌 순수 Python으로 하나하나 코드를 짜면서 진행합니다)

    그 다음에 코드(Keras)를 보고 싶으시면 케라스 창시자에게 배우는 딥러닝 이라는 책과 모두의 딥러닝 책이 좋았던 것으로 기억이 납니다~

    아마 밑바닥 딥러닝 2권과, 케라스 창시자에게 배우는 딥러닝 책(또는 모두의 딥러닝)만 보셔도 자세히는 아니지만, 포괄적으로 이해를 하실 수 있으실겁니다!

    감사합니다
댓글쓰기 폼