파이썬/AI

객체인식 Yolo7(Yolov7) 파인튜닝하는 방법

코데방 2024. 6. 20.
728x90

깃(Git) 클론하기

 

Yolov7은 ultralytics에서 만든 모델(5,8,10등)과 달리 import 라이브러리가 존재하지 않는 듯합니다. 따라서 먼저 공식 깃허브에서 파일을 다운받아 저장해줍니다.

 

아래 깃 클론 명령어로 바로 받을 수 있습니다.

윈도우 환경의 VSCode 등에서는 git을 pip install로 설치해주고 느낌표를 제외하고 cmd 터미널에서 명령어를 실행해주면 됩니다. 

# 깃 클론
!git clone https://github.com/WongKinYiu/yolov7.git

 

 

깃 클론을 할 상황이 아니라면 아래 공식 깃허브 링크에 들어가 초록색 "Code"버튼을 눌러 파일을 다운받은 뒤 압축을 해제해주면 됩니다. 

 

https://github.com/WongKinYiu/yolov7

 

GitHub - WongKinYiu/yolov7: Implementation of paper - YOLOv7: Trainable bag-of-freebies sets new state-of-the-art for real-time

Implementation of paper - YOLOv7: Trainable bag-of-freebies sets new state-of-the-art for real-time object detectors - WongKinYiu/yolov7

github.com

 

 

 

 

필수 패키지 설치

 

가장 상위 폴더의 requirements.txt 파일을 이용해 필수 패키지를 모두 설치해줍니다.

웬만하면 파이썬 또는 아나콘다 가장환경을 사용해 프로젝트별 환경을 구분해주는 것이 좋습니다. 

가상환경 설정 방법은 아래 링크를 참조하시면 됩니다. 

참고로 코랩의 파이썬 버전은 3.10.13버전이기 때문에 코랩의 GPU를 사용할 일이 있다면 맞춰주면 예상치 못한 에러를 피할 가능성이 높아집니다.

 

https://codevang.tistory.com/354

 

아나콘다 가상 환경 설정 방법

아나콘다 가상 환경 설정 이유 프로젝트를 하다보면 다양한 패키지를 사용하게 되는데, 시점에 따라 패키지 버전이 달라질 수 있습니다. 만약 아나콘다의 기본 환경인 Base에서 여러 프로젝트를

codevang.tistory.com

 

 

VSCode의 경우 cmd 터미널에서"cd 욜로폴더경로"로 들어가서 실행해주거나, 또는 아래 파일명이 있는 위치에 경로까지 포함해 적어주면 됩니다. 당연히 윈도우 환경에서는 느낌표는 빼줍니다. 

# 필요한 패키지 설치
%cd yolov7
!pip install -r requirements.txt

 

 

 

데이터 경로 파일 생성

 

데이터는 준비가 돼있다는 가정하에 진행하고 있습니다.

 

참고로 욜로 데이터 폴더는 이미지와 라벨의 주소 쌍을 똑같이 맞춰주면 라벨을 알아서 찾아줍니다. 이미지와 라벨 파일 이름은 같아야 합니다.

 

제 경우에는 아래와 같은 폴더 구조로 사용했습니다. 

 

- train_resized/images

- train_resized/labels

- valid_resized/images

- valid_resized/labels

 

편집기로 직접 만들어줘도 되는데 파인튜닝을 여러 번 할 가능성이 높으므로 아래와 같이 경로만 잘 지정해서 그냥 코드로 만들어두면 편합니다. 

 

"nc"항목에는 클래스 갯수를, "names"항목에는 클래스 이름을 적어줍니다. 나중에 욜로에서 바운딩박스를 쳐줄 때 해당 이름을 같이 출력해줍니다. 

# 데이터 경로 설정 파일 생성
%cd /content/yolov7/data
cont = """train: /content/train_resized/images
val: /content/valid_resized/images
test: /content/test_resized/images

# Classes
nc: 1
names: ['head']"""

with open("head.yaml", "w") as f:
    f.write(cont)

 

 

 

 

 

초기화 가중치 파일 다운로드

 

웬만하면 이미 COCO 데이터셋으로 학습된 가중치 파일에다가 파인튜닝을 진행하는게 효율적입니다.

 

깃허브에 들어가면 각 경우마다 파인튜닝하는 방법이 자세히 나와있습니다. 욜로는 정말 "딸깍"만으로 웬만한 것들이 동작되도록 잘 만들어놨기 때문에 완전 쉽습니다.(좋은건지 나쁜건지..)

 

물론 나중에 결과값들로 알고리즘을 작성할 때는 딸깍버전을 사용하기 힘든데 이부분은 다음 포스팅에서 다루도록 하겠습니다.

 

학습에 필요한  초기 가중치 파일은 "Transfer learning"에서 받으면 됩니다.

 

 

직접 받아도 되고 아래 코드로 받아오면 더 편합니다. 마지막 pt파일명만 적절히 바꿔주면 됩니다. 

# 초기화 가중치 다운로드
%cd /content/yolov7
!wget https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7-tiny.pt

 

 

 

 

yaml 설정 파일 클래스 수 바꿔주기

 

가장 기본적으로 아키텍쳐 변경 없이 진행한다면 아키텍쳐 yaml 파일 가장 위의 클래스 수만 바꿔주면 됩니다.

 

아키테쳐 yaml 파일은 "cfg/training" 폴더 안에 있습니다. 각자 모델에 맞는 파일을 선택해서 복사해준 뒤 내용을 바꿔주면 됩니다.

 

아래 코드는 파일을 복사해주는 코드고 수정 자체는 파일로 들어가서 직접 해줘야합니다. 

 

# yolov7/cgf/training/custom-yolov7-tiny.yaml --> 가장 윗 줄 클레스 수 바꿔줌
import shutil

shutil.copy("/content/yolov7/cfg/training/yolov7-tiny.yaml", "/content/yolov7/cfg/training/custom-yolov7-tiny.yaml")

 

 

 

파일의 가장 윗줄에 있는 "nc" 값만 클래스 수로 바꿔주면 됩니다.

 

 

 

Yolov7 파인튜닝 진행하기

 

위 과정이 모두 진행됐다면 이제 train.py 파일의 "딸깍"기능을 통해 파인튜닝을 진행해주면 됩니다.

 

아래 코드를 실행해줍니다. 물론 폴더명과 위에서 생성한 파일들의 이름은 바꿔줘야합니다.

 

-- epochs : 에포크 횟수

-- workers : 훈련에 사용한 cpu 프로세서 갯수

-- device : 쿠다 사용 시 0 (또는 쿠다 넘버)

-- batch-size : 배치 사이즈

-- data : 데이터가 들어있는 yaml 파일(위에서 만든 파일)

-- cfg : 아키텍쳐가 들어있는 yaml 파일(위에서 복사해서 클래스 수정한 파일)

-- weights : 초기화에 사용할 가중치 파일(위에서 받은 pt 파일)

-- name : 결과가 저장될 폴더 이름

-- hyp : 파이퍼파라미터가 저장된 yaml 파일 (수정할게 아니라면 그냥 기본을 사용해도 됨)

%cd /content/yolov7

!python train.py --epochs 30 --workers 4 --device 0 --batch-size 64 \
--data data/head.yaml --img 640 640 --cfg cfg/training/custom-yolov7-tiny.yaml \
--weights 'yolov7-tiny.pt' --name yolov7_tiny_haed_finetuned --hyp hyp.scratch.custom.yaml

 

 

 

 

실행하면 아래와 같이 정보들을 자동으로 출력하면서 알아서 잘 돌아갑니다.

 

 

 

 

파인튜닝 최종 결과 파일 구글 드라이브에 저장

 

혹시 코랩으로 돌렸는데 깜박하고 있다가 런타임이라도 끊기면 저장된 파일이 모두 날아가기 때문에 아래 코드를 같이 실행시켜두면 좋을 듯합니다.

 

코랩의 경우 미리 구글 드라이브 마운트를 시켜둬야합니다. 

 

가중치 파일 및 모든 결과는 위에서 설정한 폴더 밑에 저장됩니다. 코랩의 경우

"/content/yolov7/runs/train/" 폴더 하위에 있습니다.

훈련 종료 후 바로 압축해서 파일로 만든 뒤 구글 드라이브에 옮겨두면 자면서 돌려도 안심입니다. 

# 최종 결과 파일 압축 및 드라이브 저장
!zip /content/yolov7_tiny_head_finetuned_64_30.zip -r /content/yolov7/runs/train/yolov7_tiny_haed_finetuned
shutil.copy("/content/yolov7_tiny_head_finetuned_64_30.zip", "/content/drive/MyDrive")

 

 

 

파인튜닝 결과 테스트하기

 

테스트도 역시 딸깍으로 진행할 수 있습니다. 

아래 코드로 test.py 파일을 실행하면 되고 가중치 파일 경로만 설정해주면 됩니다. 

데이터 경로를 만들어준 yaml 파일은 위의 파일을 그대로 사용하면 test에 대한 경로만 인식해서 알아서 해줍니다.

 

# 테스트
%cd /content/yolov7
!python test.py --weights /content/yolov7/runs/train/yolov7_tiny_haed_finetuned/weights/best.pt --task test --data data/head.yaml

 

 

잘 나오네요!

 

 

 

Yolov7 가중치 파일 로딩해서 모델(model) 객체 생성하기

 

완성된 모델로 알고리즘을 짜기 위해서는 그냥 파일만 실행해서는 안됩니다.

직접 이미지를 통과시킬 수 있는 모델 객체를 생성해 결과(result)를 받아서 알고리즘을 짜야합니다.

 

욜로 버전마다 로딩하는 방법들이 다른데, 일단 7버전 로딩하는 방법입니다. 5, 8, 10은 다음 포스팅을 참조 부탁드립니다. 

 

"torch.hub.load()"를 사용해 로드하는게 가장 편한데, 아래 코드는 온라인이 연결돼 있어서 다운받을 수 있습니다. 

# yolov7 tiny 모델 이미지 테스트 (64 - 30)
import torch
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
path = r'.\yolov7\save_model\yolov7_tiny_haed_finetuned_64_30\train_result\weights\best.pt'
model = torch.hub.load("WongKinYiu/yolov7","custom",path,trust_repo=True)
model = model.to(device)

 

 

 

만약 온라인 연결 없이 로컬에서만 처리하고 싶다면 아래와 같이 작성해주면 됩니다. 물론 위에서 깃클론한 욜로의 전체 코드 폴더가 있어야합니다. 

model = torch.hub.load('욜로폴더경로', 'custom',  '가중치파일.pt 경로', source='local')

 

 

로딩한 model객체에다가 numpy 어레이로 변환된 이미지 파일을 넣어주면 결과 객체를 리턴합니다.

 

주의할 점은 yolo v7까지는 입력 이미지가 "RGB" 타입이어야한다는 것입니다. 만약 cv2에서 바로 연대로 "BGR" 타입의 이미지를 넣는다면 인식률이 현격하게 떨어집니다!!! 이것 때문에 꽤 고생함..

 

import cv2

img_path = "이미지 경로"
img = cv2.imread(img_path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

result = model(img)

 

 

결과 객체는 역시 ultralytics의 v8 이후 버전에서 뱉어내는 형식과 약간 다릅니다.

 

보통 사용되는 xywh 좌표정보와 xyxy 좌표 정보는 아래와 같이 얻을 수 있습니다. 나머지도 이리저리 찍어보면 뭐가 있는지 알 수 있습니다. 

 

또는 models 폴더에 있는 "commons.py" 파일에 "Detections" 클래스를 읽어보면 어떤 값들이 있는지 알 수 있습니다. yolo7의 모델 객체는 Detections 클래스입니다. 

 

 

 

 

아래 코드에서 불러오는 좌표값은 비율이 아닌 실제 좌표값이기 때문에 int형으로 미리 변환해주는게 편합니다. 

result.xywh[0].type(torch.int) # 모든 객체 좌표정보 (중심값, 가로, 세로)
result.xyxy[0].type(torch.int) # 모든 객체 좌표정보 (xmin, ymin, xmax, ymax)

 

 

 

 

만약 특정 클래스 넘버만 불러오고 싶다면 아래와 같이 작성해주면 됩니다. 저는 바로 리스트로 변환해서 사용했습니다. 

p_class = 0
p_xyxy[p_xyxy[:, 5] == p_class].tolist() # 원하는 클래스 좌표정보

 

 

 

이제 받아온 좌표 정보를 이리저리 요리해서 알고리즘을 전개하면 됩니다.

 

참고로 yolov7 에서 Confidence Threshold 값을 변경하고 싶으면 모델 로딩 후 아래와 같이 설정해주면 됩니다. 

yolo 8, 10버전은 방법이 달라서 다음 포스팅을 참조해주세요. 

model.conf = 0.7
728x90

댓글

💲 추천 글