'객체 인식'이란 무엇일까요?
객체 인식은 이미지상의 객체를 식별하는 컴퓨터 비전 기술입니다.
이미지에 특정한 물체가 있는지 머신러닝&딥러닝 알고리즘을 이용하여 판단하게 되죠.
이러한 객체 인식 알고리즘의 오픈소스로는 대표적으로 두 가지가 있는데요,
바로 YOLO와 MegaDetector 입니다.
우선 YOLO는 You Only Look Once의 약자입니다.
이미지를 한번만 탐색하여 판단합니다.
때문에 정확도는 약간 떨어진다는 단점을 가지고 있습니다.
다음으로 메가디텍터는 상당히 높은 객체 인식 정확도를 가지고 있습니다.
때문에 메가디텍터를 사용한다면 사람과 비슷한 수준으로 객체를 인식할 수 있다고 합니다.
그러나 대부분의 사람들은 주로 YOLO를 사용합니다.
어째서일까요?
바로 속도입니다.
YOLO는 이미지 한 장을 처리하는데 평균적으로 0.02초정도 걸립니다.
이에 비해서 메가디텍터는 이미지 한 장을 처리하는데 무려 2초가 걸립니다.
60fps인 30초짜리 동영상이 있다면 이 동영상은 1800장의 이미지를 가지고 있습니다.
YOLO는 이 영상을 일반적으로 30초 안으로 처리가 가능합니다.
반면에 메가디텍터는 무려 3600초 즉 1시간이 걸리게 됩니다.
아무리 정확도가 높다고 한들 속도가 너무 떨어지게 되면
실용성에서 아무래도 떨어지게 됩니다.
때문에 실제 서비스에 응용하기 위해서는 주로 YOLO를 사용하게 됩니다.
YOLO도 버전이 여러가지가 있지만
현재 제일 활발하게 사용되고 있는 YOLOv5에 대해서 알아보려고 합니다.
우선 YOLOv5 깃허브 주소입니다,
ultralytics/yolov5: YOLOv5 🚀 in PyTorch > ONNX > CoreML > TFLite (github.com)
GitHub - ultralytics/yolov5: YOLOv5 🚀 in PyTorch > ONNX > CoreML > TFLite
YOLOv5 🚀 in PyTorch > ONNX > CoreML > TFLite. Contribute to ultralytics/yolov5 development by creating an account on GitHub.
github.com
깃허브를 통해서 소스를 로컬에 내려받아 직접 돌려볼 수도 있고,
본인이 GPU를 사용할 수 없는 환경이라면 구글코랩 또는 캐글노트북을 통해서도 사용이 가능합니다.
training은 다음과 같은 명령어로 사용할 수 있다고 하네요
python train.py --data coco.yaml --cfg yolov5n.yaml --weights '' --batch-size 128
yolov5s 64
yolov5m 40
yolov5l 24
yolov5x 16
이건 정말 기본중의 기본인 명령어로 실제로 내가 어떤 자료를 어떤 하이퍼파라미터값으로 얼만큼 훈련할 것인지
좀 더 자세하게 알아봅시다.
우선 train.py를 직접 읽어봐야겠죠?
전체를 뜯는거는 나중에 해보고 이번 포스팅에서는 중요한 핵심 옵션에 대해서만 알아봅시다.
import argparse
def parse_opt(known=False):
parser = argparse.ArgumentParser()
parser.add_argument('--weights', type=str, default=ROOT / 'yolov5s.pt', help='initial weights path')
parser.add_argument('--cfg', type=str, default='', help='model.yaml path')
parser.add_argument('--data', type=str, default=ROOT / 'data/coco128.yaml', help='dataset.yaml path')
parser.add_argument('--hyp', type=str, default=ROOT / 'data/hyps/hyp.scratch.yaml', help='hyperparameters path')
parser.add_argument('--epochs', type=int, default=300)
parser.add_argument('--batch-size', type=int, default=16, help='total batch size for all GPUs, -1 for autobatch')
parser.add_argument('--imgsz', '--img', '--img-size', type=int, default=640, help='train, val image size (pixels)')
parser.add_argument('--rect', action='store_true', help='rectangular training')
parser.add_argument('--resume', nargs='?', const=True, default=False, help='resume most recent training')
parser.add_argument('--nosave', action='store_true', help='only save final checkpoint')
parser.add_argument('--noval', action='store_true', help='only validate final epoch')
parser.add_argument('--noautoanchor', action='store_true', help='disable AutoAnchor')
parser.add_argument('--evolve', type=int, nargs='?', const=300, help='evolve hyperparameters for x generations')
parser.add_argument('--bucket', type=str, default='', help='gsutil bucket')
parser.add_argument('--cache', type=str, nargs='?', const='ram', help='--cache images in "ram" (default) or "disk"')
parser.add_argument('--image-weights', action='store_true', help='use weighted image selection for training')
parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
parser.add_argument('--multi-scale', action='store_true', help='vary img-size +/- 50%%')
parser.add_argument('--single-cls', action='store_true', help='train multi-class data as single-class')
parser.add_argument('--optimizer', type=str, choices=['SGD', 'Adam', 'AdamW'], default='SGD', help='optimizer')
parser.add_argument('--sync-bn', action='store_true', help='use SyncBatchNorm, only available in DDP mode')
parser.add_argument('--workers', type=int, default=8, help='max dataloader workers (per RANK in DDP mode)')
parser.add_argument('--project', default=ROOT / 'runs/train', help='save to project/name')
parser.add_argument('--name', default='exp', help='save to project/name')
parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
parser.add_argument('--quad', action='store_true', help='quad dataloader')
parser.add_argument('--linear-lr', action='store_true', help='linear LR')
parser.add_argument('--label-smoothing', type=float, default=0.0, help='Label smoothing epsilon')
parser.add_argument('--patience', type=int, default=100, help='EarlyStopping patience (epochs without improvement)')
parser.add_argument('--freeze', nargs='+', type=int, default=[0], help='Freeze layers: backbone=10, first3=0 1 2')
parser.add_argument('--save-period', type=int, default=-1, help='Save checkpoint every x epochs (disabled if < 1)')
parser.add_argument('--local_rank', type=int, default=-1, help='DDP parameter, do not modify')
# Weights & Biases arguments
parser.add_argument('--entity', default=None, help='W&B: Entity')
parser.add_argument('--upload_dataset', nargs='?', const=True, default=False, help='W&B: Upload data, "val" option')
parser.add_argument('--bbox_interval', type=int, default=-1, help='W&B: Set bounding-box image logging interval')
parser.add_argument('--artifact_alias', type=str, default='latest', help='W&B: Version of dataset artifact to use')
opt = parser.parse_known_args()[0] if known else parser.parse_args()
return opt
if __name__ == "__main__":
opt = parse_opt()
main(opt)
argparse 라이브러리는 명령어를 통해서 직접 .py 파일에 인자를 집어넣을 수 있도록 도와줍니다.
weights : 딥러닝 모델 파일입니다.
weights 파일의 경로를 적으면 됩니다.
만약 적지 않으면 ultralytics에서 제공하는 yolov5s.pt 파일을 자동으로 지정합니다.
기본적으로 .pt 포맷을 지원하고, tensorflow의 .pb파일이나 onnx형식의 모델도 가능합니다.
ex) --weights D:\project\yolov5-master\custom.pt
data : 데이터셋의 정보가 담긴 파일입니다.
dataset.yaml 파일의 경로를 적으면 됩니다.
커스텀 데이터를 훈련할 때에는 이 yaml 파일을 직접 작성 or 수정해서 지정해 주어야 합니다.
이 부분은 실제 훈련을 하는 포스팅에서 좀 더 자세히 다루겠습니다.
ex) --data D:\project\yolov5-master\custom_data.yaml
hyp : 훈련에 사용될 하이퍼 파라미터들의 정보가 담긴 파일입니다.
hyp.yaml 파일의 경로를 적으면 됩니다.
커스텀 데이터를 훈련할 때에는 이 yaml 파일을 직접 작성 or 수정해서 지정해 주어야 합니다.
이 부분은 실제 훈련을 하는 포스팅에서 좀 더 자세히 다루겠습니다.
ex) --hyp D:\project\yolov5-master\custom_hyp.yaml
epoch : 훈련을 반복할 횟수입니다.
기본값은 300 입니다.
몇 번을 훈련할지 적어주면 됩니다.
ex) --epochs 300
batch size : 배치 크기입니다.
기본값은 16 입니다.
배치 크기에 관련해서는 작은게 좋다 큰게 좋다 의견이 분분한데
yolov5 개발자는 작은 배치 크기는 잘못된 통계를 산출할 가능성이 높아서 피해야 하니
장비가 지원하는 최대의 값을 넣어주라고 하네요.
일반적으로 후술할 workers의 배수값으로 넣어주는 것이 원칙입니다.
ex) --batch-size 16
imgsz : 이미지 크기(픽셀값)입니다.
기본값은 640 입니다.
object detection의 경우 일반적으로 여러 크기의 사진들을 하나의 크기로 고정시켜 학습 및 추론을 진행합니다.
따라서 고정시킬 크기의 값을 지정을 해 줄 수 있습니다.
오브젝트 디텍션에서 기본적으로 쓰이는 데이터셋인 COCO데이터셋 보다 오브젝트 크기가 작은 데이터를 학습시킬 필요가 있는 경우 640보다 큰 값을 주면 학습 및 추론에 유리하다고 합니다.
다만, 제 경험상 주려는 픽셀값보다 학습하려는 사진의 크기가 더 작은 경우에는 성능이 좀 떨어집니다.
예를 들어 1280으로 학습하라고 했지만 내가 가지고 있는 데이터셋은 320 * 240 픽셀일 경우
1280 * 960으로 사진을 변환할 때 사진이 깨져서 그러지 않을까 싶네요
이런 경우에는 오히려 320으로 지정해주는게 더 나은 정확도를 보였습니다.
ex) --imgsz 640 또는 --img 640 또는 --img-size 640
cache : 데이터셋의 캐싱 여부입니다.
별도로 설정하지 않으면 캐싱하지 않습니다.
구글코랩같이 로컬에서 돌리는 것이 아니라 온라인 드라이브를 연결해 사용하는 경우
매번 드라이브의 데이터에 접근하려면 굉장한 시간낭비로 이어지기 때문에 데이터셋을 렘에 캐싱하여
한 번만 데이터를 불러온 뒤에 더 이상 로컬 데이터에 접근하지 않습니다.
다만 이 경우 고용량의 렘을 필요로 합니다.
또한 로컬에서 돌릴경우에는 굳이 사용하지 않아도 되는 옵션입니다.
ex) --cache
workers : 사용할 cpu의 코어 개수입니다.
기본값은 8입니다.
ctrl+shift+esc로 확인한 제 노트북은 6코어로 6개까지 사용 가능합니다.
이 값을 가능한 최대로 주셔야 CPU가 GPU에게 각각 일을 분배시켜 빠른 학습 및 추론이 가능해집니다.
ex) --workers 16
if __name__ == "__main__": 문에 의해서
프롬프트에 python train.py로 실행하면
main()함수를 실행하고, main함수 내부에서 train함수를 호출하여 훈련이 진행됨을 알 수 있습니다.
다음 포스팅에서는 간단하게 훈련을 직접 진행해 보겠습니다.
'YOLOv5' 카테고리의 다른 글
YOLOv5 하이퍼파라미터 (0) | 2022.01.31 |
---|---|
YOLOv5를 이용하여 Object Detection해보기(2) (0) | 2022.01.26 |
YOLOv5를 이용하여 Object Detection해보기(1) (0) | 2022.01.25 |
댓글