AI Research Topic/Dataset

[Dataset] MS COCO 데이터를 쉽게 이용할 수 있는 FiftyOne 사용하기

꾸준희 2021. 8. 10. 19:02
728x90
반응형

 

 

MS COCO Dataset 홈페이지에 오랜만에 들어가봤는데, 새로운 것을 발견해서 포스팅하기로 했다.

 

FiftyOne 공식 문서 : https://voxel51.com/docs/fiftyone/#

 

FiftyOne — FiftyOne 0.11.2 documentation

Contents

voxel51.com

 

FiftyOne Github : https://github.com/voxel51/fiftyone

 

GitHub - voxel51/fiftyone: The open-source tool for building high-quality datasets and computer vision models

The open-source tool for building high-quality datasets and computer vision models - GitHub - voxel51/fiftyone: The open-source tool for building high-quality datasets and computer vision models

github.com

 

 

 

 

바로 FiftyOne 이라는 도구인데, COCO 데이터 리소스에 대한 시각화 및 액세스를 용이하게 하는 오픈 소스 도구이며 COCO 데이터를 이용하여 모델 분석 및 평가까지 쉽게 할 수 있다. 개인적으로 생각하기에 제일 좋은 기능은 잘못 라벨링 된 주석을 확인하고 수정할 수 있는 기능 아닐까 싶다. 

 

FiftyOne 에서 제공하고 있는 튜토리얼들은 다음과 같다. 

  • Evaluating object detections
  • Evaluating a classifier
  • Using image embeddings
  • Working with Open Images
  • Exploring image uniqueness
  • Finding class mistakes
  • Finding detection mistakes

 

 


사용법은 간단하다. pip install 이 가능하다.

pip install fiftyone

 

자세한 사용법은 아래 colab 을 참고하도록 하자. 

 

https://colab.research.google.com/github/voxel51/fiftyone-examples/blob/master/examples/quickstart.ipynb#scrollTo=F5lmzP-eptKG

 

quickstart.ipynb

Run, share, and edit Python notebooks

colab.research.google.com

 

 

 

 

 

 

일단 object detection 분야에서 잘못 레이블링 된 주석들을 수정하기 위한 튜토리얼을 실행해보았다. 

import fiftyone as fo
import fiftyone.zoo as foz

dataset = foz.load_zoo_dataset("quickstart")
print(dataset)

# Print a sample ground truth detection
sample = dataset.first()
print(sample.predictions.detections[0])

# Open the dataset in the App
session = fo.launch_app(dataset)

 

웹을 통해 아래와 같은 화면이 제공되고, quickstart 프로젝트를 통해 약 200개의 샘플 데이터들을 확인 할 수 있다. 모든 데이터들의 주석은 json 으로 이루어져있다. COCO 형식 말고도 VOC, YOLO 형식 등을 지원한다. 그리고 아래 화면은 prediction 된 박스(갈색)와 ground thruth의 박스(주황색)을 제공한다. 

 

GT 의 분포도 나타내준다. 싱기싱기..

 

 

 

 

그 다음 mistakenness of annotations 을 계산해보았다. (위 코드에 이어 사용해야함)

import fiftyone.brain as fob
from fiftyone import ViewField as F

# Compute mistakenness of annotations in `ground_truth` field using
# predictions from `predictions` field as point of reference
fob.compute_mistakenness(dataset, "predictions", label_field="ground_truth")

# Sort by likelihood of mistake (most likely first)
mistake_view = dataset.sort_by("mistakenness", reverse=True)

# Print some information about the view
print(mistake_view)

# Inspect some samples and detections
# This is the first detection of the first sample
print(mistake_view.first().ground_truth.detections[0])

# Open new App window
session.show()

# Show the samples we processed in rank order by the mistakenness
session.view = mistake_view

 

 

그러면 mistake 된 데이터들만 추출해서 볼 수 있다. 그리고 여기서 쿼리를 사용하여 mistakenness 의 threshold 를 설정해서 실행한다면 아래와 같이 0.95 값 이상으로 잘못 레이블링된 데이터들을 볼 수 있다. 

from fiftyone import ViewField as F

session.view = dataset.filter_labels("ground_truth", F("mistakenness") > 0.95)

 

 

나는 더 많은 데이터들을 보기 위해 0.8 로 설정하여 아래와 같은 결과를 얻었다. 

 

이 데이터의 mistakenness 값은 0.933 이며 GT 는 "TRUCK" 으로 되어있다. (원래는 "CAR" 로 되어있어야 한다.)

 

하지만 FiftyOne 에서 prediction 한 결과는 아래와 같이 "CAR" 로 추론되었다.

 

 

 

 

위와 같이 mistakenness 값을 이용하여 데이터를 조회해 볼 수 있고, 또한 잘못 localization 되어있는 데이터들도 조회 해볼 수 있다. mistakenness_loc 값을 이용하면 된다. 

session.view = dataset.filter_labels("ground_truth", F("mistakenness_loc") > 0.9)

 

나는 또 더 많은 데이터들을 보기위해서 0.8 값을 썼다. 아래와 같이 데이터가 로드 된다. 근데 predictions 수치가 너무 낮아서 뭐가 맞는 localization 인지 모르겠어서 confidence 를 조절해보았다. 

 

아래와 같이 뜬다. 근데 여기서 ... 이 브로콜리가 담긴 접시에서 브로콜리는... 브로콜리 하나를 클래스로 간주해야할까, 아니면 브로콜리 여러개를 클래스 하나로 간주해야할까? 라는 생각이...들었다... 이건 과연 잘못된 라벨링일까?... 데이터의 클래스를 어떻게 정의하느냐에 따라 달린 것 같다. 만일 브로콜리 여러개를 클래스 하나로 두고싶다면 이건 잘못된 localization 의 경우가 아닐테고, 만일 브로콜리 한개(사실 브로콜리가 여러 갈래로 나뉘어지게끔 생겨서...애매..)라면 잘못된 localization의 경우가 맞는 것 같다.. ㅋㅋㅋ (뭔가 예시를 잘못 든 것 같은...)

 

그래서 다른 사진도 가져와봤다... GT 가 파란색 박스고, Pred 은 갈색 박스이다. 근데 이런 경우에도 Prediction 된 결과를 보면, 사람의 영역이 맞다. 심지어 pose estimation 을 추출하기에 충분한 영역이다. (데이터 입력 전 margin 을 둔다는 가정 하에.)

뭔가 mistakenness_loc 은 클래스의 localization 을 어디까지 볼 것인지 정의함에 따라 결과가 달라질 것 같기 때문에 이런 점을 고려하면 좋을 것 같다. 

 

 

 

그 다음으로 possible_missing 기능은 놓친 클래스가 있음을 알려주는 기능이다. 

session.view = dataset.match(F("possible_missing") > 0)

 

정말 좋은 예시는 아래와 같다. 사과 클래스를 놓쳐서 annotation 한 경우이다.

 

 

 

 

위 기능들로 잘못된 데이터들을 확인하고나서 데이터를 수정할 수도 있다. 당연한 얘기지만 정확도가 좋은 모델을 사용할 수록 데이터의 품질이 좋아진다. 이 예제에서는 detector 를 Faster-RCNN 을 사용했다고 한다. 도큐먼트에서 말하길 EfficientDet D7 을 사용하면 더 좋은 결과를 얻을 수 있다고 한다. 

 

라벨링 수정 참고 : https://voxel51.com/docs/fiftyone/api/fiftyone.core.collections.html?highlight=select_labels#fiftyone.core.collections.SampleCollection.select_labels 

 

fiftyone.core.collections — FiftyOne 0.11.2 documentation

fiftyone.core.collections Interface for sample collections. Classes: Functions: aggregation(func) get_frame_labels_fields(sample_collection[, …]) Gets the frame label field(s) of the sample collection matching the specified arguments. get_label_fields(s

voxel51.com

# A dataset can be filtered to only contain labels with certain tags
# Helpful for isolating labels with issues and sending off to an annotation provider
missing_ground_truth = dataset.select_labels(tags="missing")

session.freeze() # screenshot the active App for sharing

 

728x90
반응형