[Dev] YOLOv5 Custom Training : 모델 성능 끌어올리기 + Flask backend 연동 #2

2025. 4. 30. 16:39·Project

AI 모델의 성능(인식률)을 높이는 방법에는 여러 방법이 있지만 나는 가장 간단한 방법 2가지를 사용했다

그전에 모델 성능 지표를 간단하게 확인할 수 있는 F1 Score Curve를 알아보자

  • 의미: 재현율(Precision)과 정밀도(Recall)의 조화 평균을 나타낸 곡선
  • 높을수록 좋은 성능을 의미하며, 일반적으로 1에 가까울수록 좋다
  • 사용자의 그래프 분석:점수가 낮거나 들쭉날쭉하면 Precision과 Recall 사이에 균형이 맞지 않음
  • 보통 0.8 정도의 수치가 나오면 좋은 성능을 가진 모델이라고 할 수 있음
  • F1 점수가 일정하게 높으면 모델의 균형이 잘 잡힌 것

데이터셋 품질 및 수량 향상

 

Flower Classification Object Detection Dataset (v5, 2024-12-14 11:43pm) by viskom

274 open source Flowers images and annotations in multiple formats for training computer vision models. Flower Classification (v5, 2024-12-14 11:43pm), created by viskom

universe.roboflow.com

기존 200-300 장 정도의 데이터셋 사진 수를 4000장 정도로 늘려주었다! 물론 그만큼 모델학습 시간은 길어지겠지만
공부량이 많으면 성적의 저점이 낮아지듯, 무식하지만 가장 좋은 방법 중 하나임

v0.1_flower_yolov5_640..? #1
맨 처음 모델학습할 때는 데이터셋 라벨링,  하이퍼파라미터, 이런 거 모르고 무작정 오 학습된다! 하고 좋아했는데
정작 학습이 된다고 모델의 성능까지 좋은 건 아니었다. 성적이 안 나와도 날 격려해 주던 울 엄마의 마음이 이랬을까

v 0.1 (2025.04.02) 맨처음 학습했던 모델

이후 같은 데이터셋으로 하이퍼 파라미터를 좀 만지면서 이렇게 저렇게 학습을 해봤는데 생각보다 성적이 잘 나오지 않았다

v0.3_flower_yolov5_640_b32_ep100 #3

v0.3 (2025.04.17) 200장 데이터셋으로 학습

이때부터 모델 구분하려고 모델 폴더 이름에 하이퍼 파라미터값을 같이 써뒀다. 

이제 roboflow에서 같은 classes들을 가진 데이터셋 이미지를 대량으로 받아와 약 3000장 정도 되는 이미지들과 라벨링 파일을 기존 학습이미지와 합쳐서 학습을 진행해 봤다.


하이퍼 파라미터 조정

v0.4_ flower_yolov5_640_b16_ep100 #4

python train.py --img 640 --batch 16 --epochs 100 --data flowerDataset_2\data.yaml --weights yolov5s.pt --name flower2_yolov5_b16_ep100

batch (배치 크기) : 한 번의 학습 단계에서 처리되는 데이터 샘플의 수
작게 설정: 메모리 사용량 감소, 더 자주 가중치 업데이트. 하지만 학습이 불안정할 수 있음.
크게 설정: 학습이 안정적이지만, 더 많은 메모리가 필요하고 학습 속도가 느려질 수 있음.

 

GPU 메모리 용량에 따라 설정하고 너무 크게 하면 학습하다가 중간에 꺼져버린다.
일반적으로 16, 32, 64 등 2의 배수로 설정한다고 한다.

 

epochs (에포크 수) : 전체 데이터셋을 한 번 모두 학습하는 횟수
작게 설정: 학습이 충분하지 않아 과소적합 가능성.
크게 설정: 학습이 과도해 과적합 가능성.

데이터셋 크기와 복잡도에 따라 설정하고 일반적으로 50~300 사이에서 테스트하며 최적 값을 찾는다고 함

 

학습 파라미터를 여러 개 조정해 본 결과 이렇게 학습한 게 제일 결과도 나름 잘 나왔고 여기서 더 높은 파라미터를 설정하면 너무 오래 걸림 + 그래픽카드가 견디지를 못해서 이 버전을 최종적으로 사용하기로 함!

데이터셋 이미지를 대폭 확대하니 Epoch 하나를 학습하는데 30초 이상 소요됨
30초 * 100 Epoch = 3000초 = 50분 정도로 학습시간이 대폭 길어짐

집 앞에 버거킹 가서 햄버거 세트하나 먹고 왔는데도 학습하고 있어서 놀랐음

v0.4 (2025.04.17) 4000장 데이터셋으로 학습

약 한 시간 정도 4000개의 이미지 데이터셋을 기반으로 100 Epoch 학습을 돌린 결과
전체적으로 70-80% 적중률의 준수한 성능의 모델이 뽑힘!

 

mAP@0.5: 80.8%로, IoU 0.5 기준에서 모델의 평균 정확도
mAP@0.5:0.95: 66.3%로, 더 엄격한 IoU 기준에서의 평균 정확도
Precision(P): 77.3%로, 모델의 예측 중 올바른 비율
Recall(R): 74.1%로, 실제 객체를 얼마나 잘 탐지


테스트해봅시다

학습이 잘됐다면, runs/train/ 경로에 본인이 학습했던 모델폴더가 있을 텐데 그럼 이제 테스트를 해볼 수 있다

test_images/라는 경로를 만들어, 테스트하고 싶은 이미지들을 여러 개 넣어주자

yolov5 폴더경로에 있는 detect.py 를 사용한다!

python detect.py --weights runs/train/flower2_yolov5_b16_ep100/weights/best.pt --img 640 --conf 0.4 --source test_images/

-img : 학습할 때 쓴 이미지 크기 -> 640으로 학습했으니 640으로 test

-conf : 신뢰도 threshold (0.25~0.5 사이 )

-source : 테스트할 이미지 폴더

이 정도 인식률이면 훌륭한 듯하다, 내가 할 프로젝트는 엄청나게 정확한 인식률이 요구되는 게 아니기 때문에
이 정도에서 모델학습을 마무리하고, 이제 이 모델파일을 백엔드랑 연동하는 방법을 공부해야 함


flask 서버 + yolov5 모델연동

그래도 첫 AI모델까지 만들었는데 웹개발자로서 테스트를 안 해볼 수 없었음, 얼른 연동하고 싶어서 막 신이 나더라고요

그전에 flask와 yolo모델의 호환성을 위해 파이썬 가상환경 위치를 파일 최상단으로 옮겨주고 같이 사용하기로 함!

전체 폴더구조

간단하게 backend아래에 app.py 만들어주고 파일경로만 잘 맞춰주면 기본 구조 만들기는 간단합니다

모델 이미지 분석 요청

  • Method: POST
  • URL: http://localhost:5000/predict
  • Content-Type: multipart/form-data
  • Body:
    - image: 업로드할 이미지 파일 (File 타입)
from flask import Flask, request, jsonify, send_file
import os
import torch
from pathlib import Path
from yolov5.detect import run  # YOLOv5 내부 detect->run 호출

app = Flask(__name__)

# 모델 경로
MODEL_PATH = 'yolov5/runs/train/flower2_yolov5_b16_ep100/weights/best.pt'

@app.route('/')
def index():
    return 'YOLOv5 꽃다발 인식 서버가 실행 중입니다!'

@app.route('/predict', methods=['POST'])
def predict():
    if 'image' not in request.files:
        return jsonify({'error': '이미지가 필요합니다.'}), 400

    file = request.files['image']
    filename = 'input.jpg'
    filepath = os.path.join('static', filename)
    file.save(filepath)

    # YOLOv5 예측 실행
    run(weights=MODEL_PATH, source=filepath, imgsz=(640,640), conf_thres=0.4, save_txt=False, save_conf=False, project='static', name='detect', exist_ok=True)

    result_path = Path('static/detect/input.jpg')
    if result_path.exists():
        return send_file(result_path, mimetype='image/jpeg')
    else:
        return jsonify({'error': '예측 실패'}), 500

if __name__ == '__main__':
    os.makedirs('static', exist_ok=True)
    app.run(debug=True)
python app.py

해서 실행해 주면

서버 on
postman - POST 요청

postman으로 request 해도 200OK로 잘 작동되는 걸 확인!


로컬 테스트는 끝났고 이제 이거를 어떻게 서비스하냐가 문제인데 Docker를 사용해서 한 번에 묶어서 배포해 버릴까 생각 중
근데 문제는 Docker를 사용해 본 적이 없어서 공부와 동시에 웹서핑+삽질을 열심히 해봐야 할 듯함 ㅠㅠ 

'Project' 카테고리의 다른 글
  • [Project] gitHub Personal access tokens (classic) 재발급, gitHub Action 업데이트
  • [Project] Gabia에서 구매한 도메인을 Vercel과 연결해보자
  • [Project] 멋쟁이사자처럼 아기사자 모집 사이트 Frontend
  • [Project] 개발시 유용한 사이트 모음집
너굴먹
너굴먹
해랑사 을신당는 나
  • 너굴먹
    햄스터가 갱스터가 될때까지
    너굴먹
  • 전체
    오늘
    어제
    • 분류 전체보기 (36)
      • Dev (17)
      • Computer (6)
      • Project (7)
      • CodingTest (2)
      • 일상 (4)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    코딩테스트
    trunk-based
    숫 자료형
    roboflow
    아이패드 m4
    오답노트
    실수 변환
    R-S래치
    필기
    정보처리기사
    actions secrets and variables
    정처기 필기
    경기도갭이어프로그램
    소수 변환
    GithubAction
    python
    플립플롭
    10진수
    c라이브러리
    AWS
    YOLOv5
    cbt
    래치
    RS래치
    python #max #min #최댓값 #최솟값
    숫자 자료형
    vercel
    2진수
    파이썬
    Lightsail
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
너굴먹
[Dev] YOLOv5 Custom Training : 모델 성능 끌어올리기 + Flask backend 연동 #2
상단으로

티스토리툴바