반응형

 

Car detection

 

데이터 확인

  • 이미지에 대한 xmin, ymin, xmax, ymax 로 이루어진 데이터셋

  • cv2 rectangle 을 통해서 시각화 했을때 labeling이 잘된 모습을 확인할수 있음

 

format 변환

  • 현재 데이터는 xmin, ymin, xmax, ymax로 이루어진 데이터
  • 사용할 모델인 Yolov3 format은 x_center, y_center, w, h 와 같은 정보가 필요함으로 데이터 가공 수행
img_h, img_w, num_channels = h, w, c # h, w, c 는 위에서 얻은 이미지 크기


# x_center 생성
data_df['x_center'] = (data_df['xmin'] + data_df['xmax'])/2
data_df['x_center'] = data_df['x_center']/img_w

# y_center 생성
data_df['y_center'] = (data_df['ymin'] + data_df['ymax'])/2
data_df['y_center'] = data_df['y_center']/img_h

# width 생성
data_df['w'] = data_df['xmax'] - data_df['xmin']
data_df['w'] = data_df['w']/img_w

# height 생성
data_df['h'] = data_df['ymax'] - data_df['ymin']
data_df['h'] = data_df['h']/img_h

# class 생성
data_df['classes'] = 0

data_df.head()
  • 기본적으로 검출할 class가 모두 'car' 하나의 단일 클래스 임으로 0으로 통일
  • 이미지의 높이, 너비, 채널에 대한 정보는 image.size 를 통해서 얻을수 있고 해당 데이터는 모두 이미지 w,h 가 동일함

 

Yolov3 폴더 형식 및 데이터 분할

  • 사용할 모델인 Yolov3는 format 이외에도 파일에 대한 조건이 존재
  • 알맞는 형식으로 파일을 작성해줘야 문제없이 작동
# yolov3 파일 형식

───────────────────────────────────────────────  
 📁 yolov3_car_data 
   ├────📃 data.yaml : 데이터의 경로 및 class 내용이 담긴 yaml 파일
   ├──📁 images : tarin,val,test 이미지가 들어있는 폴더
   │    ├──📁 train     
   │    ├──📁 val
   │    └──📁 test
   │    
   ├──📁 labels : tarin,val label이 들어있는 폴더
   │    ├──📁 train      
   │    └──📁 val 
───────────────────────────────────────────────

 

  • 해당 형식의 폴더를 손으로 작성할수 있지만 그렇게 되면 번거롭기 때문에 os.makedirs를 통해서 생성
# 위의 폴더 형식을 만드는 함수
def make_dir():
    if not os.path.exists('./yolov3_car_data'):
        os.makedirs('./yolov3_car_data')

    if not os.path.exists('./yolov3_car_data/images/'):
        os.makedirs('./yolov3_car_data/images/')

    if not os.path.exists('./yolov3_car_data/labels/'):
        os.makedirs('./yolov3_car_data/labels/')

    for i in ['train','val']:
        if not os.path.exists(f'./yolov3_car_data/images/{i}/'):
            os.makedirs(f'./yolov3_car_data/images/{i}/')
        if not os.path.exists(f'./yolov3_car_data/labels/{i}/'):
            os.makedirs(f'./yolov3_car_data/labels/{i}/')

# 경로 생성
make_dir()

 

이미지 및 라벨 파일 분리

  • 현재 dataframe 안에 이미지별 해당 이미지에 대한 x_center, y_center, width, height 존재
  • 이를 .txt 파일 안에 'classes','x_center','y_center','w','h' 순으로 작성해야 함 (이미지 별로)
# data_df image 중 train : valid 분리
split_data = list(set(list(data_df['image'])))
train_valid_split = random.sample(split_data, k= 210) # 210개는 train : 90개는 val

# 실제 yolo format에 사용되는 class, x_center, y_center, width, height 만 남기기
for name,sep in tqdm(data_df.groupby('image')):
    if name in train_valid_split:
        folder = 'train'
    else:
        folder = 'val'

    with open(f'./yolov3_car_data/labels/{folder}/{name.split(".")[0]}.txt', 'w+') as f:
        row = sep[['classes','x_center','y_center','w','h']].astype(float).values
        row = row.astype(str)
        for j in range(len(row)):
            text = ' '.join(row[j])
            f.write(text)
            f.write("\n")

    sh.copy(f"./car_detection/train/{name}",f'./yolov3_car_data/images/{folder}/{name}')
  • groupby로 image를 하는 이유는 한 이미지안에 객체가 2개 이상일 경우 annotions 모두를 label에 작성하기 위함

 

yaml 파일 생성

  • 모든 과정이 끝나고 최종적으로 model에게 train,val,test 데이터 위치와 class 이름 및 개수를 알려주는 yaml 파일 작성
  • python의 open() write()를 통해서도 작성할수 있지만 가장 편한 방법으로 작성
%%writefile ./yolov3_car_data/data.yaml
train : ../yolov3_car_data/images/train
val : ../yolov3_car_data/images/val
test: ../yolov3_car_data/images/test

nc : 1
names: [car]

 

모델 훈련

  • 기본적으로 학습이 잘된 상태를 보여주기 위해서 개인컴으로 1000 epoch 수행한 가중치로 재학습
  • batch : 한번에 훈련시킬 이미지 수
  • epochs : 훈련 횟수
  • weight : 사용할 모델 가중치 (여기서는 이미 1000번 돌린 가중치 사용), 안적으면 알아서 yolov3.pth 다운
  • exist-ok : 결과물 폴더 하나로 통일
  • device : 사용할 gpu 넘버
os.chdir('./yolov3') # yolov3 폴더로 이동

!python train.py  --batch 16 --epochs 5 --data ../yolov3_car_data/data.yaml --exist-ok --weights ../car_detection/best.pt --cache --device 0
  • 모델 추론
    • ./runs/train/exp/weights/best.pt 에 위에서 5 epoch 돌린 모델이 저장됨
!python ./detect.py --weights ./runs/train/exp/weights/best.pt --conf 0.25 --line-thickness 1 --exist-ok --device 0 --source  ../yolov3_car_data/images/test

 

모델 결과 시각화

  • 확실하게 ultralytics yolov3는 기존 yolov3 보다 성능면에서 좋은 경향을 보임
  • format의 형태가 ultralytics yolov5와 같아서 사실상 yolov3 나 yolov5 아무거나 사용해도 문제 없지만 yolov5는 자체적으로 모자이크를 넣어서 데이터를 학습시키는 부분 때문에 적은 데이터셋으로 수행하는 건 부적절 하다고 판단

 

끝으로

  • Kaggle 데이터 셋을 통해서 yolov3 를 해보는 실습을 올려보고 싶었는데 마침 좋은 기회가 있어서 작성했습니다.
  • 모든 과정은 위에 colab에서 수행해보실수 있습니다. 감사합니다.

 

전체 내용 한번에 보기

 

반응형

'DeepLearning > Yolo' 카테고리의 다른 글

YOLOV3 - Ship detection 실습  (2) 2024.07.23
YOLO V3 example  (1) 2024.07.22