YOLOv5를 사용한 우산 인식

나 안해·2023년 3월 7일
0

MyProject

목록 보기
2/5
post-thumbnail

1. 경로

parent 
  ├── yolov5
        └── dataset

2. 전처리

2.1 train.py에서 실행하기 위해 사용할 데이터를 가져올 yaml 파일을 생성

path: C:\Users\AIA\PycharmProjects\yolov5\dataset
train: train\images
val: valid\images

nc: 1
names:
  0: 'umbrella'

2.2 기본 Dataset에서 학습 시킬 대상을 가진 데이터만 남기고 나머지 데이터 삭제

train_label_list = glob('C:/Users/AIA/PycharmProjects/datasets/umb/train/labels/*.txt')
    for path in train_label_list:
      print(path)
      f = open(path, "rt")
      umbrella = []
      for line in f:
        if line.startswith("76"): #76은 name class에서 'umbrella'를 갖는 인덱스값
          umbrella.append(line)
      f.close()
      if len(umbrella) == 0 : #우산이 없으면 삭제한다
        os.remove(path)
        os.remove(path.replace(".txt", ".jpg").replace("labels","images"))
      else :
        f2 = open(path, 'wt')
        for p in umbrella:
          f2.write(p.replace("76","0",1))
        f2.close()
실행 전실행 후
images : 116,408 / labels : 116,408images : 3,904/ labels : 3,904

3. 전체 사물 중 우산만 인식

  • 학습한 .pt 파일을 실행한 결과

목적인 우산 자체는 인식을 했으나 우산이 아닌 것까지 우산으로 인식하는 문제 발생

  • 원인?
    - Confidence Threshold가 0.25로 낮아서 발생한 문제
    - 아래 설명에서 알 수 있듯이 이 값이 너무 낮으면 자신감 넘치는 상대의 말은 무조건 믿는 것처럼 정확도가 낮은 결과를 받게된다.

    Confidence Threshold?

    • 말 그대로 Confidence에 대한 신뢰도로 Confidence가 일정 수준에 미달이면 버리게 하는 수준이다 .
    • 단, 이 값이 너무 높으면 작은 차이로도 인식에 문제가 생기기 때문에 중간점을 잘 잡아야 한다.
  • 해결
    - Confidence Threshold의 값을 0.4정도로 설정해서 정확도가 낮은 박스를 사용하지 않게 했다.

4. 우산의 파손 여부 인식

4.1 이미지 크롤링

  • 우산 파손여부 인식을 위해 기본 데이터셋에 없는 파손된 우산 이미지와 라벨이 필요
  • 크롤링 결과로 나온 이미지들에 라벨링 작업 시행

4.2 1차 시도

  • 파손 데이터의 양이 너무 적고 각 파손된 형태가 제각각이기 때문에 정사 우산과 파손 우산을 구분하지 못함

-파손 데이터를 추가하고 epoch 50으로 실행한 결과

이제는 우산과 파손을 잘 잡지만 아직도 이상한 곳에서 우산을 인식한다… 이건 우산관련 데이터를 늘리는 방법이 최선이라고 생각한다.

4.3 2차 시도

  • 2차 학습에서 사용한 데이터셋에서 데이터량을 늘려서 학습
  • 구글 이미지 크롤링으로 검색된 파손된 우산 이미지를 모두 모아서 크롤링으로는 우리가 원하는 데이터를 더 구할 수 없으니 다음 단계에서는 직접 데이터셋을 늘리는 방식을 찾아야 한다

    이전 시도보다는 높은 정확도를 가지게 됐다.


0. 트러블

0.1 학습 중 KeyError: 'path'

원인

아래 코드를 추가해서 yaml 파일의 내용을 변경하는 과정에서 원래 있던 path:가 사라져서 발생한 문제

import yaml 
path = '/content/yolov5/data.yaml'
with open(path, 'r') as f : 
  data = yaml.load(f, Loader=yaml.FullLoader) 
  data['train'] = '/content/yolov5/train/images'
  data['val'] = '/content/yolov5/valid/images'
  data['nc'] = 1 
  data['names'] = ['umbrella']

  with open(path, 'w')  as f: 
    yaml.dump(data, f)
    print(data)

해결

경로를 다시 잡아주면 바로 해결된다

0.2 전처리 과정에서 한 개의 파일만 제거하고 다음 파일은 찾지 못하는 문제 발생

train_label_list = glob('C:/Users/AIA/PycharmProjects/datasets/umb/train/labels/*.txt')
for path in train_label_list:
  print(path)
  f = open(path, "rt")
  umbrella = []
  for line in f:
    if line.startswith("76"):
      umbrella.append(line)
  f.close()
  if len(umbrella) == 0 : # person 이 없으면 삭제한다
    os.remove(path)
    os.remove(path.replace(".txt", ".jpg").replace("/labels/","/images/"))
  else :
    f2 = open(path, 'wt')
    for p in umbrella:
      f2.write(p.replace("76","0",1))
    f2.close()

해결

12번 라인의 replace("/labels/","/images/")replace("labels","images")로 바꿔서 다시 실행

0.3 전처리 후 학습시 nc 이외의 범위에서 키에러 발생

원인

전처리 과정 후 학습하는 과정에서 바뀐 라벨 리스트가 제대로 반영되지 않아서 생긴 문제라고 생각된다

  • 에러발생 직전
  • 에러 지점에서 self.class_names만 출력한 결과
    • 문제가 발생한 파일에서 cls를 출력
      - 0.0으로만 들어가던 값이 에러 발생 직전에 7.0으로 들어가면서 문제 발생

해결 :

에러 발생 지점에서 변경한 클래스 네임이 적용되지 않아 발생한 문제로 utils/logger/comet/init.py의 267번, 276번 라인을 아래처럼 바꿔준다

임시방편이므로 여유가 생기는대로 좀 더 원인을 찾아봐야된다

# 에러 발생 
  for cls, *xyxy in filtered_labels.tolist():
      metadata.append({
          'label': f'{self.class_names[int(cls)]}-gt',
# 변경
for cls, *xyxy in filtered_labels.tolist():
      metadata.append({
          'label': f'{self.class_names}-gt',

참고

0개의 댓글