데보션앱 소개페이지 바로가기
로그인 선택

신고하기

CLOSE
신고사유 (대표 사유 1개)
상세내용 (선택)
0/200
  • 신고한 게시글은 더 이상 보이지 않습니다.
  • 이용약관과 운영정책에 따라 신고사유에 해당하는지 검토 후 조치됩니다.
  • 허위 신고인 경우, 신고자의 서비스 이용이 제한될 수 있으니 유의하시어 신중하게 신고해 주세요.
(이 회원이 작성한 모든 댓글과 커뮤니티 게시물이 보이지 않고, 알림도 오지 않습니다.)

미리보기

커뮤니티

      1,234

      badge 23.06.15

      글 등록

      카테고리를 선택해주세요.

      DEVOTEE를 활성화 시키면
      지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.

      버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.

      임시저장함에 저장되었습니다. 저장일시 : 2022.5.17 14:29:08

      임시저장함

      제목을 선택하시면 이어서 작성이 가능하며,
      최대 20건까지 저장합니다.
      컨텐츠 유형, 제목, 저장일시, 삭제로 이뤄진 임시저장 목록
      컨텐츠 유형 제목 저장일 삭제

      데보션 블로그 게재 요청

      CLOSE
      • *
      • *

      본인인증

      효율적인 데보션 서비스 이용 및
      고객님의 소중한 개인정보보호를 위해
      본인인증을 진행해주세요. 본인인증 미 진행 시 로그인이 제한됩니다.
      본인인증 실패

      본인인증 로그인에 실패하였습니다.
      회원이 아니시거나 본인인증 등록이
      완료되지 않은 사용자입니다.

      회원정보 연결

      통상적이지 않은 이미지 분류에 대한 고찰

      chem 23.09.19
      2,051 16 0
      DEVOTEE 요약
      일반적으로 Object Detection은 원하는 물체를 찾고 분류하는 과정을 말하는데, 이 과정에는 충분한 이미지 데이터셋이 필요합니다. 하지만 이미지 데이터셋을 보유하지 않는 경우에는 Detection된 물체를 Crop하여 딥러닝으로 학습시키는 전이학습을 활용할 수 있습니다. 본 블로그에서는 명품 시계 이미지 분류를 예시로 설명하며, tensorflow hub에서 coco2017 데이터셋을 활용하여 Detection 모델을 선택한 후, 해당 모델을 기반으로 딥러닝을 통해 Classification을 진행합니다. 결과적으로 약 98%의 Detection 성능과 좋은 분류 결과를 얻을 수 있었습니다.

      object_detection.jpeg


      Introduction

      일반적으로 말하는 Object Detection은 물체를 1.탐지 하고 2.구분 해주는 것을 의미합니다. 한 장의 사진에서 원하는 물체를 찾아서 분류까지 해주는 강력한 방법이지만 실제로 실무에 활용하려면 전제조건이 있어야합니다.

      1. 많은 이미지 데이터 셋을 보유하고 있거나

      2. 통상적으로 학습된 이미지 데이터 셋에 포함되어있다.

      개인적으로 프로젝트를 진행하는 경우에 1번과 2번 모두 포함되지 않는 경우가 있습니다. 이러한 경우에 어떻게 내가 원하는 물체를 구분할 수 있을까 고찰했습니다.

      고민 결과를 먼저 말씀 드리면, 분류를 원하는 물체를 Detection & Crop하고, Crop된 이미지를 딥러닝으로 학습시켜 모델링 하는 것입니다.

      제가 진행중인 명품 시계 이미지 분류 Project를 예시로 설명 하겠습니다. (Project관련 자세한 내용은 따로 업로드 할 예정입니다.)


      Detection & Crop

      한 장의 이미지에서 제가 원하는 이미지를 Detection하기 위한 학습을 진행하는 것은 매우 어려운 일이고, 충분한 이미지 데이터 셋도 가지고 있어야 가능합니다.

      명품 시계 이미지 분류도 마찬가지 입니다. 이전에 포스팅 했던 crawling을 활용하더라도, 대량의 이미지 데이터 셋을 모으기에는 턱없이 부족합니다.

      따라서 제가 분류하고자 하는 물체의 상위 카테고리를 활용하면 어떨까 하는 생각이 들었습니다.


      [STEP1] 잘 알려진 이미지 데이터 셋 확인

      tensorflow hub나 pytorch에 있는 detection model을 확인해보면, 일반적으로 잘 알려진 이미지 데이터 셋을 활용하여 detection을 진행하고 있습니다.

      저는 그 중에서 coco2017 데티터 셋을 활용한 detection model을 채택 했습니다. 채택 기준은 해당 모델이 시계를 Detection 해 주기 때문입니다.

      coco2017 데이터 셋

      논문이나 대회에서 많이 사용되는 이미지 셋이고 다음과 같이 이루어져 있습니다. (https://cocodataset.org/)


      ▶ 학습(training) 데이터셋: 118,000장의 이미지▶ 검증(validation) 데이터셋: 5,000장의 이미지▶ 테스트(test) 데이터셋: 41,000장의 이미지


      [STEP2] 모델 선택 및 detection & Crop

      coco2017 데이터 셋이 "clock"을 분류해 주기 때문에 해당 데이터 셋으로 학습된 detection model을 찾다 서버를 따로 가지고 있지 않기 때문에

      비교적 간단한 Faster R-CNN with Resnet-50 V1 모델을 선택했습니다.

      저는 tessorflow를 통해 딥러닝을 진행하고 있기 때문에 tensorflow hub로 detection 모델을 불러왔고, 해상도는 1024*1024를 사용했습니다.

      명품 시계를 분류하기 위해서는 해상도가 꽤 커야 디테일한 부분을 구분할 수 있을 거라고 생각했기 때문입니다.


      해당 모델을 통해 시계를 Detection한 결과는 만족스러웠습니다. (약 98% 디텍션 성능) 다음은 제가 수집한 이미지에서 명품 시계를 분류해주는 예시입니다.

      detection model을 통해 object를 분류하고, Crop한 이미지를 통해 이미지셋을 만들어줍니다.

      detection.png

      detection_rst.png


      Classification

      새로운 시계 이미지 데이터 셋을 통해 어떤 명품 시계인지 분류하는 작업이 남았습니다.제가 수집한 이미지 데이터 셋이 많이 않았기 때문에, 전이 학습을 활용해야 겠다고 생각했습니다.

      전이학습(Transfer Learning)

      vgg16_original.png


      기존에 학습된 모델의 fully-connected-layer(최상위층)만 학습 시키는 방법입니다.

      학습 속도가 빠르면서 정교한 분류가 가능하기 때문에 이미지 데이터 셋이 적을 때 널리 사용되고 있는 방식입니다.

      [STEP1] Image classification 모델 결정

      전이학습에 사용할 모델을 결정하기 위해서 두가지를 고려 했습니다.

      1. 내 컴퓨터에서 학습할 수 있을 만큼 가벼운가

      2. 성능이 잘 나오는가

      두가지를 고려하여 제가 선택한 모델은 MobileNetV2와 DenseNet121 모델입니다.

      MobileNetV2는 매우 가볍다는 것이 장점이고, DesneNet121 모델은 정확도가 높은것이 장점입니다.


      [STEP2] 모델 학습 및 결과

      전이 학습을 위해서는 기존 모델을 불러오고, 가장 최상위 층만 수정하여 모델을 구성해야 합니다.

      # base model
      base_model = DenseNet121(weights="imagenet", include_top=False)
      
      # Add custom classification layers on top
      x = base_model.output
      x = GlobalAveragePooling2D()(x)
      x = Dense(128, activation="relu")(x)
      predictions = Dense(len(train_data.class_indices), activation="softmax")(x)
      
      # Create the model
      model = Model(inputs=base_model.input, outputs=predictions)
      
      # Freeze layers in the base model
      for layer in base_model.layers:
          layer.trainable = False
      
      # Compile the model
      model.compile(
          optimizer=Adam(0.005), loss="categorical_crossentropy", metrics=["accuracy"]
      )

      최상위 층을 제외하고 나머지는 학습이 되지 않아야 하므로, 다른 층을 모두 동결 시켜주는 것이 매우 중요합니다.이후 모델 학습을 진행하시면 됩니다.


      모델 학습 결과

      Epoch 1/50
      2023-09-09 21:39:18.600254: W tensorflow/core/platform/profile_utils/cpu_utils.cc:128] Failed to get CPU frequency: 0 Hz
      2023-09-09 21:39:20.846062: I tensorflow/core/grappler/optimizers/custom_graph_optimizer_registry.cc:113] Plugin optimizer for device_type GPU is enabled.
      98/98 [==============================] - ETA: 0s - loss: 1.9716 - accuracy: 0.44372023-09-09 21:39:44.809292: I tensorflow/core/grappler/optimizers/custom_graph_optimizer_registry.cc:113] Plugin optimizer for device_type GPU is enabled.
      
      Epoch 1: val_accuracy improved from -inf to 0.61769, saving model to ./epic_models/DN_TL_230909.h5
      98/98 [==============================] - 34s 314ms/step - loss: 1.9716 - accuracy: 0.4437 - val_loss: 1.2182 - val_accuracy: 0.6177 - lr: 0.0010
      Epoch 2/50
      98/98 [==============================] - ETA: 0s - loss: 0.8980 - accuracy: 0.7374
      Epoch 2: val_accuracy improved from 0.61769 to 0.78153, saving model to ./epic_models/DN_TL_230909.h5
      98/98 [==============================] - 28s 282ms/step - loss: 0.8980 - accuracy: 0.7374 - val_loss: 0.7872 - val_accuracy: 0.7815 - lr: 0.0010
      Epoch 3/50
      98/98 [==============================] - ETA: 0s - loss: 0.5997 - accuracy: 0.8254
      Epoch 3: val_accuracy improved from 0.78153 to 0.80624, saving model to ./epic_models/DN_TL_230909.h5
      98/98 [==============================] - 27s 280ms/step - loss: 0.5997 - accuracy: 0.8254 - val_loss: 0.5976 - val_accuracy: 0.8062 - lr: 0.0010
      Epoch 4/50
      98/98 [==============================] - ETA: 0s - loss: 0.4694 - accuracy: 0.8507
      Epoch 4: val_accuracy improved from 0.80624 to 0.84655, saving model to ./epic_models/DN_TL_230909.h5
      98/98 [==============================] - 27s 280ms/step - loss: 0.4694 - accuracy: 0.8507 - val_loss: 0.5066 - val_accuracy: 0.8466 - lr: 0.0010
      Epoch 5/50
      98/98 [==============================] - ETA: 0s - loss: 0.3835 - accuracy: 0.8777
      Epoch 5: val_accuracy did not improve from 0.84655
      98/98 [==============================] - 27s 275ms/step - loss: 0.3835 - accuracy: 0.8777 - val_loss: 0.4445 - val_accuracy: 0.8466 - lr: 0.0010
      Epoch 6/50
      98/98 [==============================] - ETA: 0s - loss: 0.3204 - accuracy: 0.9024
      Epoch 6: val_accuracy improved from 0.84655 to 0.86086, saving model to ./epic_models/DN_TL_230909.h5
      98/98 [==============================] - 29s 296ms/step - loss: 0.3204 - accuracy: 0.9024 - val_loss: 0.4280 - val_accuracy: 0.8609 - lr: 0.0010
      Epoch 7/50
      98/98 [==============================] - ETA: 0s - loss: 0.3155 - accuracy: 0.8925
      Epoch 7: val_accuracy improved from 0.86086 to 0.86736, saving model to ./epic_models/DN_TL_230909.h5
      98/98 [==============================] - 34s 348ms/step - loss: 0.3155 - accuracy: 0.8925 - val_loss: 0.3817 - val_accuracy: 0.8674 - lr: 0.0010
      Epoch 8/50
      98/98 [==============================] - ETA: 0s - loss: 0.2488 - accuracy: 0.9220
      Epoch 8: val_accuracy improved from 0.86736 to 0.87906, saving model to ./epic_models/DN_TL_230909.h5
      98/98 [==============================] - 36s 369ms/step - loss: 0.2488 - accuracy: 0.9220 - val_loss: 0.3691 - val_accuracy: 0.8791 - lr: 0.0010
      Epoch 9/50
      98/98 [==============================] - ETA: 0s - loss: 0.2311 - accuracy: 0.9220
      Epoch 9: val_accuracy did not improve from 0.87906
      98/98 [==============================] - 35s 361ms/step - loss: 0.2311 - accuracy: 0.9220 - val_loss: 0.3567 - val_accuracy: 0.8778 - lr: 0.0010
      Epoch 10/50
      98/98 [==============================] - ETA: 0s - loss: 0.2048 - accuracy: 0.9345
      Epoch 10: val_accuracy did not improve from 0.87906
      98/98 [==============================] - 37s 377ms/step - loss: 0.2048 - accuracy: 0.9345 - val_loss: 0.3584 - val_accuracy: 0.8726 - lr: 0.0010
      Epoch 11/50
      98/98 [==============================] - ETA: 0s - loss: 0.1992 - accuracy: 0.9262
      Epoch 11: val_accuracy did not improve from 0.87906
      98/98 [==============================] - 38s 392ms/step - loss: 0.1992 - accuracy: 0.9262 - val_loss: 0.3665 - val_accuracy: 0.8752 - lr: 0.0010
      Epoch 12/50
      98/98 [==============================] - ETA: 0s - loss: 0.1740 - accuracy: 0.9454
      Epoch 12: val_accuracy improved from 0.87906 to 0.88687, saving model to ./epic_models/DN_TL_230909.h5
      98/98 [==============================] - 39s 399ms/step - loss: 0.1740 - accuracy: 0.9454 - val_loss: 0.3238 - val_accuracy: 0.8869 - lr: 0.0010
      Epoch 13/50
      98/98 [==============================] - ETA: 0s - loss: 0.1618 - accuracy: 0.9470
      Epoch 13: val_accuracy improved from 0.88687 to 0.88817, saving model to ./epic_models/DN_TL_230909.h5
      98/98 [==============================] - 39s 398ms/step - loss: 0.1618 - accuracy: 0.9470 - val_loss: 0.3310 - val_accuracy: 0.8882 - lr: 0.0010
      Epoch 14/50
      98/98 [==============================] - ETA: 0s - loss: 0.1627 - accuracy: 0.9467
      Epoch 14: val_accuracy did not improve from 0.88817
      98/98 [==============================] - 38s 392ms/step - loss: 0.1627 - accuracy: 0.9467 - val_loss: 0.3146 - val_accuracy: 0.8856 - lr: 0.0010
      Epoch 15/50
      98/98 [==============================] - ETA: 0s - loss: 0.1385 - accuracy: 0.9557
      Epoch 15: val_accuracy did not improve from 0.88817
      98/98 [==============================] - 40s 407ms/step - loss: 0.1385 - accuracy: 0.9557 - val_loss: 0.3460 - val_accuracy: 0.8817 - lr: 0.0010
      Epoch 16/50
      98/98 [==============================] - ETA: 0s - loss: 0.1364 - accuracy: 0.9560
      Epoch 16: val_accuracy did not improve from 0.88817
      98/98 [==============================] - 40s 408ms/step - loss: 0.1364 - accuracy: 0.9560 - val_loss: 0.3473 - val_accuracy: 0.8752 - lr: 0.0010
      Epoch 17/50
      98/98 [==============================] - ETA: 0s - loss: 0.1397 - accuracy: 0.9538
      Epoch 17: val_accuracy did not improve from 0.88817
      98/98 [==============================] - 40s 411ms/step - loss: 0.1397 - accuracy: 0.9538 - val_loss: 0.3221 - val_accuracy: 0.8856 - lr: 0.0010
      Epoch 18/50
      98/98 [==============================] - ETA: 0s - loss: 0.1196 - accuracy: 0.9650
      Epoch 18: val_accuracy improved from 0.88817 to 0.89337, saving model to ./epic_models/DN_TL_230909.h5
      98/98 [==============================] - 42s 429ms/step - loss: 0.1196 - accuracy: 0.9650 - val_loss: 0.2946 - val_accuracy: 0.8934 - lr: 0.0010
      Epoch 19/50
      98/98 [==============================] - ETA: 0s - loss: 0.1047 - accuracy: 0.9666
      Epoch 19: val_accuracy improved from 0.89337 to 0.89857, saving model to ./epic_models/DN_TL_230909.h5
      98/98 [==============================] - 43s 438ms/step - loss: 0.1047 - accuracy: 0.9666 - val_loss: 0.3140 - val_accuracy: 0.8986 - lr: 0.0010
      Epoch 20/50
      98/98 [==============================] - ETA: 0s - loss: 0.0964 - accuracy: 0.9717
      Epoch 20: val_accuracy improved from 0.89857 to 0.91027, saving model to ./epic_models/DN_TL_230909.h5
      98/98 [==============================] - 44s 448ms/step - loss: 0.0964 - accuracy: 0.9717 - val_loss: 0.2822 - val_accuracy: 0.9103 - lr: 0.0010
      Epoch 21/50
      98/98 [==============================] - ETA: 0s - loss: 0.0746 - accuracy: 0.9839
      Epoch 21: val_accuracy did not improve from 0.91027
      98/98 [==============================] - 45s 456ms/step - loss: 0.0746 - accuracy: 0.9839 - val_loss: 0.2864 - val_accuracy: 0.9012 - lr: 1.0000e-04
      Epoch 22/50
      98/98 [==============================] - ETA: 0s - loss: 0.0717 - accuracy: 0.9878
      Epoch 22: val_accuracy did not improve from 0.91027
      98/98 [==============================] - 46s 468ms/step - loss: 0.0717 - accuracy: 0.9878 - val_loss: 0.2854 - val_accuracy: 0.9038 - lr: 1.0000e-05
      Epoch 23/50
      98/98 [==============================] - ETA: 0s - loss: 0.0715 - accuracy: 0.9881
      Epoch 23: val_accuracy did not improve from 0.91027
      98/98 [==============================] - 47s 478ms/step - loss: 0.0715 - accuracy: 0.9881 - val_loss: 0.2853 - val_accuracy: 0.9038 - lr: 1.0000e-06
      Epoch 24/50
      98/98 [==============================] - ETA: 0s - loss: 0.0714 - accuracy: 0.9878
      Epoch 24: val_accuracy did not improve from 0.91027
      98/98 [==============================] - 50s 512ms/step - loss: 0.0714 - accuracy: 0.9878 - val_loss: 0.2853 - val_accuracy: 0.9038 - lr: 1.0000e-07
      Epoch 25/50
      98/98 [==============================] - ETA: 0s - loss: 0.0714 - accuracy: 0.9878
      Epoch 25: val_accuracy did not improve from 0.91027
      98/98 [==============================] - 48s 489ms/step - loss: 0.0714 - accuracy: 0.9878 - val_loss: 0.2853 - val_accuracy: 0.9038 - lr: 1.0000e-08

      모델 학습 결과는 제 예상보다 매우 만족스러웠습니다. (F1-score 0.91 달성)


      Conclusions

      기존에 잘 학습된 detection 모델과 Classification 모델을 활용하여 아주 정확도 높은 이미지 분류 모델을 만들어 낼 수 있었습니다.

      자신이 분류하고자 하는 이미지 데이터 셋이 적고, 통상적이지 않다면 해당 방법을 고려하는 것도 좋을 것 같습니다..!

      추가로 Augmentation과 Fine-tuning을 사용하여 정확도를 더 높혀 볼 예정입니다.


      참고

      댓글 0

      DEVOTEE를 활성화 시키면
      지금 작성한 댓글에 AI가 댓글을 달아줍니다.

      chem 님의 최신 블로그

      더보기