주제
목표
- Object Detection을 위한 Data Preprocessing(1일차)
- Implement YOLO(2일차)
개인 목표
1. 데이터 전처리
- zip파일로 주어진 데이터 -> 압축 풀기
- 데이터 구성: 이미지 파일 + Json 파일
- 이미지 파일 전처리
- Json파일로 label 데이터 만들기
데이터셋 불러오기
zipfile 모듈
- 파이썬 제공 표준 라이브러리
- zipfile을 처리하는 데 사용하는 모듈
- 파일 경로 등이 많이 사용되므로 주로 'os 모듈'과 함께 사용
import zipfile
zipfile.ZipFile(file, mode='r', compression=ZIP_STORED, allowZip64=True, compresslevel=None, *, strict_timestamps=True)
- file : Zip 파일 이름 또는 경로
- mode : Zip 파일 열기 모드 (r - 읽기모드, w - 쓰기모드)
- compression : 압축 방법 (ZIP_STORED - 압축하지 않음, ZIP_DEFLATED - Deflate 알고리즘 사용)
- allowZip64 : True로 설정하면 4GB 이상의 큰 파일도 처리 가능
- compresslevel : 압축 레벨 (0~9)
압축 풀기
zip_ref = zipfile.ZipFile('/dataset.zip')
zip_ref.extractall('압축 해제할 디렉토리')
with zipfile.ZipFile('/dataset.zip') as zip_ref:
zip_ref.extractall('압축 해제할 디렉토리')
데이터 이동
- 폴더 구조를 만들고 그에 맞게 데이터를 이동
- 모델(yolo)에서 요구하는 구조: Image, Label를 구분하여 저장
- Image: 이미지 데이터
- Label: Json 데이터
- 각 디렉토리에 Train, Validation를 구분하여 저장
- Train : Validation = 8 : 2
def split_files(file_list, src_path, val_data_num, dst_path):
for i, file_name in enumerate(file_list):
src_file = os.path.join(src_path, file_name)
if i < val_data_num:
shutil.move(src_file, dst_path + '/val')
else:
src_file = os.path.join(src_path, file_name)
shutil.move(src_file, dst_path + '/train')
- 전체 중 20%를 'val'에 옮긴 후 나머지는 'train'에 이동
Json 데이터 정보 추출
class 추출
- class는 zero-indexed(0부터 시작)
- Json의 'label'데이터에는 화폐의 앞, 뒤가 구분되어 있음 -> 구분을 없애고 class로 만들기 -> 8개 클래스(0~7)
class = {'Ten':0, 'Fifty':1,
'Hundred':2, 'Five_Hundred':3,
'Thousand':4, 'Five_Thousand':5,
'Ten_Thousand':6, 'Fifty_Thousand':7}
x_center, y_center, width_norm, height_norm
- Bounding Box에 대한 정보
- 모든 정보는 normalized 가 필요(0-1사이의 값)
- 주어진 이미지는 Json에서와 달리 1/5 축소된 상태임을 주의
.txt 저장
with open(dst_file, 'w') as f:
f.write(f'{class[label]} {x_center} {y_center} {width_norm} {height_norm}')
yaml 파일 만들기
path: ../datasets/coco128
train: images/train2017
val: images/train2017
test:
names:
0: person
1: bicycle
2: car
...
77: teddy bear
78: hair drier
79: toothbrush
data = {
'path': '/content/drive/MyDrive/Datasets',
'train': 'images/train',
'val': 'images/val',
'nc': 8,
'names': won_dict
}
yaml_file = os.path.join(dataset_path, 'money.yaml')
with open(yaml_file, 'w') as f:
yaml.dump(data, f)
path: /content/drive/MyDrive/Datasets
train: images/train
val: images/val
nc: 8
names:
0: '10'
1: '50'
2: '100'
3: '500'
4: '1000'
5: '5000'
6: '10000'
7: '50000'
어려웠던 부분
- 학습과정에서 cpu와 gpu의 차이는 매우 크다
마무리
- 전처리를 끝내고 남은 시간에 'yolov5n'을 약 1시간에 걸쳐 학습시킨 후, detect 해본 결과
- 10원을 50원으로 라벨링
- 100원을 500원으로 라벨링
- 학습 시 좋은 성능을 보였더라도 실제에서는 다르게 탐지하는 결과를 보임: 원인이 무엇인지 확인해보기(모델 복잡도, 전처리 과정 등)
- 더 간단한 모델(v5s 등) 혹은 더 복잡한 모델(v5x 등), 최신 버전의 모델(v8)을 시도해볼 예정