paint-brush
MinIO 및 YOLO와 함께 사용자 정의 데이터 세트를 사용하여 객체 감지 모델을 훈련하는 방법~에 의해@minio
9,150 판독값
9,150 판독값

MinIO 및 YOLO와 함께 사용자 정의 데이터 세트를 사용하여 객체 감지 모델을 훈련하는 방법

~에 의해 MinIO13m2023/11/22
Read on Terminal Reader

너무 오래; 읽다

이 게시물에서는 사용자 정의 이미지 데이터 세트를 만든 다음 유비쿼터스 작업인 객체 감지 작업을 위해 YOLO(You-Only-Look-Once) 모델을 교육합니다. 그런 다음 새 이미지에 대해 자동으로 추론을 수행할 수 있는 MinIO 버킷 알림을 사용하는 시스템을 구현합니다.
featured image - MinIO 및 YOLO와 함께 사용자 정의 데이터 세트를 사용하여 객체 감지 모델을 훈련하는 방법
MinIO HackerNoon profile picture
0-item
1-item

컴퓨터 비전은 인공 지능의 매우 매력적인 응용 분야로 남아 있습니다. 전장의 요소를 인식하든, 작물 수확량을 예측하든, 컴퓨터 비전은 틀림없이 가장 상업적으로 가치 있고 사회적으로 중요한 AI 영역 중 하나입니다.


그러나 최고의 컴퓨터 비전 기능을 채택하는 속도를 제한하는 요인은 종종 데이터세트를 구성하고 새 이미지에 대해 컴퓨터 비전 작업을 수행할 간단한 엔드투엔드 시스템을 설계하는 것과 관련된 복잡성입니다.


이 블로그 게시물에서는 CVAT 및 MinIO 버킷 알림과 같은 동급 최고의 도구를 사용하여 이러한 문제를 해결하는 방법을 단계별로 살펴보겠습니다. 이 게시물이 끝나면 사용자 정의 데이터 세트에서 객체 감지 모델을 훈련하고 이를 사용하여 새 이미지가 나타날 때마다 예측을 할 수 있게 될 것입니다.

전제

위성 이미지에 있는 항공기 유형을 인식할 수 있기를 원한다고 가정해 보겠습니다. 또한 사전 구축된 데이터 세트도 없고 사전 훈련된 모델도 없이 처음부터 시작한다고 가정해 보겠습니다. 다음은 위성 이미지에서 감지하고 인식하려는 두 대의 샘플 항공기입니다.


왼쪽에서 오른쪽으로: (1) Su-30, (2) Tu-95


이 게시물에 설명된 단계는 거의 모든 도메인에 일반화될 수 있습니다. 항공기 유형을 탐지하는 대신 토지 이용을 분류하거나 회귀 분석을 수행하여 작물 수확량을 예측할 수 있습니다. 전통적인 이미지 외에도 LiDAR 포인트 클라우드 또는 3D 지진 이미지와 같은 다른 유형의 다차원 데이터에 대해 훈련하고 추론을 수행할 수도 있습니다. 훈련 데이터가 어떻게 보이는지에 대한 질문이 됩니다(그리고 잠재적으로 YOLO 대신 다른 딥러닝 모델이 될 수도 있습니다). 특정 사용 사례에서 이것이 어떤 모습일지 더 궁금한 점이 있으면 언제든지 GitHub 저장소 에 문제를 제기해 주세요!


1단계: 교육 샘플 확보 및 관리

이 프로젝트에서는 주로 주문형 영상 위성을 소유하지 않았기 때문에 Google 어스의 비행장을 방문하여 이러한 비행기 중 일부가 보이는 지역의 스크린샷을 여러 장 찍었습니다. 이 이미지 세트를 조립하는 데 시간이 꽤 걸리므로 MinIO 서버의 "object-Detection"이라는 버킷에 모두 저장했습니다. 생산 환경에서는 수집된 샘플을 MinIO에 저장하면 더욱 큰 이점을 얻을 수 있습니다. 활성-활성 복제, 최고 수준의 암호화 및 초고속 GET/PUT(몇 가지 예)을 통해 부지런히 수집된 샘플의 가용성이 높고 안전하며 보안이 유지됩니다.

2단계: 데이터세트 생성

데이터세트 생성


사용 사례에 맞게 객체 감지 모델을 훈련하려면 레이블이 지정된(또는 '주석이 달린') 데이터 세트가 필요합니다. 이를 위한 훌륭한 도구는 OpenCV의 CVAT입니다. 멋진 기능은 CVAT가 버킷의 이미지를 데이터 세트 주석 도구에 직접 제공하기 위해 MinIO 버킷을 "클라우드 스토리지"로 연결하는 유틸리티를 제공한다는 것입니다. 이렇게 하려면 특히 MinIO 서버를 온프레미스 또는 노트북에서 로컬로 실행하는 경우 MinIO 서버의 호스트가 CVAT 서버에 액세스할 수 있는지 확인하세요. 또한 참고로 CVAT를 사용하는 방법에는 (1) app.cvat.ai 에서 제공된 웹 앱을 사용하거나 (2) 로컬에서 실행하는 두 가지 방법이 있습니다. 두 경우 모두 CVAT를 연 후 메뉴 표시줄에서 '클라우드 저장소'를 클릭하세요. 여기에서 양식을 작성하여 (S3 호환) MinIO 버킷을 연결할 수 있습니다.


클라우드 저장소 만들기


이제 "Tasks(작업)" 아래에 새 라벨링 작업을 만들어 보겠습니다.


라벨링 작업


다음 사항을 작성해야 하는 양식이 표시됩니다.


새 작업 만들기


작업을 생성할 때 클래스 레이블을 올바르게 정의하는 것이 중요합니다(저는 감지하려는 두 평면에 해당하는 "SU30" 및 "TU95"라는 제목의 두 개의 직사각형 레이블을 정의했습니다).


클래스 라벨 정의


이제 남은 단계는 이전에 추가한 MinIO 버킷을 데이터 소스로 연결하는 것입니다. “파일 선택”에서 “Cloud Storage”를 클릭하고 이전에 해당 소스에 제공한 이름을 입력합니다. 위에서는 "minio-cv-bucket"이라는 이름을 사용했습니다.


MinIO 버킷을 데이터 소스로 연결


업로드 과정은 몇 분 정도 소요됩니다. 완료되면 '작업' 아래에서 사용 가능한 주석 작업을 볼 수 있습니다.


업로드 완료


이제 작업을 클릭하면 각 이미지에 주석을 달 수 있습니다. 경고: 이는 불균형적으로 시간이 많이 소요되는 프로세스일 수 있습니다. 일반적으로 주석이 많이 필요한 생산 환경에서는 이 작업을 전담 내부 팀이나 타사 데이터 라벨링 회사에 오프로드하는 것이 가장 좋습니다.


주석 달기 시작하기


주석 달기가 완료되면 데이터 세트를 YOLO 형식으로 내보냅니다.


데이터 내보내기

3단계: 훈련 데이터 정리하기

내보낸 데이터세트는 zip 파일 형식입니다. 압축을 풀면 YOLO 형식의 주석 텍스트 파일이 동봉된 폴더에 들어 있습니다. 자유롭게 살펴보세요. YOLO 형식에서 각 이미지의 주석은 각 줄에 경계 상자와 클래스의 두 모서리가 포함된 텍스트 파일에 있습니다. 클래스 번호는 작업을 생성할 때 레이블을 정의한 순서에 해당합니다. 따라서 이 예에서 0은 Su-30에 해당하고 1은 Tu-95에 해당합니다.


이 시점에서 새 작업 디렉터리를 만듭니다(또는 이미 만든 디렉터리를 입력합니다). 이 디렉터리 내에 'dataset'라는 하위 디렉터리를 만듭니다. 'dataset' 내에서 작업 디렉터리가 다음과 같은 디렉터리를 만듭니다.


 my_cv_project (WORKING DIRECTORY) |---- dataset |----images |----train |----val |----test |----annotations |----train |----val |----test



이제 이미지와 해당 주석(텍스트 파일) 모두에 대한 train, val 및 test 하위 디렉터리를 채워야 합니다. 샘플을 검색하고 분할하는 방법은 귀하에게 달려 있습니다. 좋은 방법은 총 훈련 샘플 양을 훈련 80%, 검증 10%, 테스트 10%로 나누는 것입니다. 이미지를 분할하기 전에 이미지를 무작위로 섞으십시오.


개인적으로 저는 명령줄에서 MinIO 클라이언트의 mc cp를 사용하여 '객체 감지' 버킷에서 모든 이미지를 빠르게 검색했습니다. 또는 로컬 컴퓨터의 한 곳에 이미 모든 샘플 이미지가 있는 경우 해당 이미지로 직접 작업할 수 있습니다. 모든 샘플을 한 곳에 모은 후 Python 스크립트를 사용하여 이미지와 주석을 섞고, 분할하고, train, val 및 test 디렉터리로 이동했습니다. 다음은 편의를 위해 제공된 스크립트입니다 . 사용 방법에 대해 궁금한 점이 있으면 언제든지 repo 에 문제를 제기하세요!


궁극적으로, Images/train, Images/val 또는 Images/test에 배치한 각 이미지에 대해 일치하는 주석 .txt 파일이 주석/ 디렉터리 내의 해당 하위 디렉터리에도 있는지 확인하십시오. 예를 들어:


 my_cv_project (WORKING DIRECTORY) |---- dataset |----images |----train - 5.png - 3.png - 2.png |----val - 4.png |----test - 1.png |----annotations |----train - 5.txt - 3.txt - 2.txt |----val - 4.txt |----test - 1.txt


이제 데이터가 준비되었습니다. 이제 객체 감지 모델을 살펴보고 훈련을 시작할 시간입니다.

4단계: 객체 감지 모델

객체 인식에 대한 현재의 최적 표준(성능 및 사용 용이성 측면)은 YOLO(You Only Look Once) 클래스의 모델입니다. 이 글을 쓰는 시점에서 YOLOv8은 최신 버전이며 Ultralytics에서 오픈 소스로 유지 관리됩니다. YOLOv8은 새로 생성된 주석에 대해 모델을 훈련하는 데 활용할 수 있는 간단한 API를 제공합니다(결국 추론도 실행함).


YOLOv8을 다운로드하자:


 $ pip install ultralytics


이제 YOLOv8 CLI 도구 또는 Python SDK를 사용하여 학습, 검증 및 예측할 수 있습니다. 자세한 내용은 YOLOv8 문서를 참조하세요.

5단계: 훈련

작업 디렉터리에서 데이터 세트의 위치와 클래스에 대한 세부 정보를 지정하는 YAML 파일을 정의합니다. 경로가 이전에 작업 디렉터리에서 만든 경로와 어떻게 동일한지 확인하세요. 나는 내 파일을 ' objDetect.yaml '이라고 불렀습니다. 또한 두 개의 항공기 클래스 라벨은 CVAT에서와 동일한 순서로 정의되어야 합니다.


 train: ./dataset/images/train/ val: ./dataset/images/val/ test: ./dataset/images/test/ # number of classes nc: 2 # class names names: ["SU-30","TU-95"]


다음 명령을 사용하여 데이터세트에서 YOLOv8 모델 학습을 시작합니다(YOLO CLI 도구 사용). 훈련을 위해 구성할 수 있는 다양한 옵션에 대해 자세히 알아보려면 YOLO 문서를 참조하세요. 여기서는 100세대에 대한 훈련을 시작하고 이미지 크기를 640픽셀로 설정합니다(모든 훈련 이미지는 훈련 중에 그에 따라 크기가 조정됩니다).


 $ yolo task=detect \ mode=train \ model=yolov8s.pt \ data=objdetect.yaml \ epochs=100 \ imgsz=640


훈련에는 시간이 좀 걸릴 것입니다. 특히 저처럼 노트북으로 작업하는 경우라면 지금이 휴식을 취하기에 좋은 시간입니다(또는 미리 읽어보세요 😀)!


훈련 루프가 끝나면 훈련된 모델은 다른 흥미로운 그래프 및 차트와 함께 'runs'라는 자동 생성 디렉터리에 저장됩니다. 아래와 같은 터미널 출력은 최신 실행 결과의 특정 위치를 나타냅니다. 모델을 훈련할 때마다 'runs/Detect/' 내에 비슷한 디렉터리가 생성됩니다.


 Results saved to runs/detect/train


참고: running/Detect/train/weights/에는 정확한 훈련된 가중치가 포함된 PT 파일이 포함됩니다. 나중을 위해 이 위치를 기억해 두세요.

5B단계: 모델 검증 및 테스트

다음 명령을 사용하여 유효성 검사를 실행할 수 있습니다.


 $ yolo task=detect \ mode=val \ model=path/to/best.pt \ data=objdetect.yaml


결과는 'runs/Detect/val' 형식의 경로를 사용하여 작업 디렉터리의 폴더에 자동으로 저장됩니다.


테스트 세트에 대해 추론을 수행하려면 다음 명령을 사용할 수 있습니다.


 $ yolo task=detect \ mode=predict \ model=path/to/best.pt \ conf=0.5 \ source=dataset/images/test


결과는 'runs/Detect/predict'에 저장됩니다. 테스트 세트에 대한 몇 가지 예측 결과는 다음과 같습니다.


예측 결과


6단계: MinIO 버킷 알림을 사용한 새로운 이미지 추론

이제 위성 이미지에 있는 일부 항공기 유형을 인식할 수 있는 훈련된 모델이 있으므로 간단한 방법으로 새 이미지에 이를 어떻게 활용할 수 있습니까 ?


MinIO 버킷 알림 사용


MinIO 버킷 알림은 이를 위한 완벽한 도구입니다. 웹훅의 도움을 받아 버킷에 삭제된 새 이미지에 대해 객체 감지 추론을 자동으로 수행할 수 있는 시스템을 구축할 수 있습니다.


높은 수준에서는 3단계가 있습니다. 먼저 훈련된 모델을 사용하여 새 이미지에서 객체 감지를 수행하기 위해 웹훅 역할을 할 수 있는 엔드포인트를 정의해야 합니다. 둘째, 이벤트가 발생할 때 웹훅 엔드포인트에 도달하도록 지시하는 MinIO 서버 배포에 대한 일부 환경 변수를 구성해야 합니다. 셋째, 어떤 유형의 버킷 이벤트(예: PUT)를 수행할지 구성해야 합니다. 단계별로 살펴보겠습니다.


다음은 MinIO 버킷에 추가된 새 이미지에 대해 추론을 실행하는 간단한 Flask 기반 서버( Detection_server.py )에 대한 코드입니다.


 """ This is a simple Flask inference server implementation that serves as a webhook for the event of a new image being added to a MinIO bucket. Object detection using YOLO will be performed on that image and the resulting predictions will be returned. """ from flask import Flask, request, abort, make_response from ultralytics import YOLO import tempfile from minio import Minio # Make sure the following are populated with your MinIO details # (Best practice is to use environment variables!) MINIO_ENDPOINT = '' MINIO_ACCESS_KEY = '' MINIO_SECRET_KEY = '' model = YOLO('/PATH/TO/best.pt') # load a custom model (path to trained weights) client = Minio( MINIO_ENDPOINT, access_key=MINIO_ACCESS_KEY, secret_key=MINIO_SECRET_KEY, ) app = Flask(__name__) @app.route('/', methods=['POST']) async def inference_bucket_webhook(): """ This endpoint will be called when a new object is placed in your inference bucket """ if request.method == 'POST': # Get the request event from the 'POST' call event = request.json bucket = event['Records'][0]['s3']['bucket']['name'] obj_name = event['Records'][0]['s3']['object']['key'] with tempfile.TemporaryDirectory() as temp_dir: temp_file_name = temp_dir+'/'+obj_name client.fget_object(bucket, obj_name, temp_file_name) # See https://docs.ultralytics.com/modes/predict/ for more information about YOLO inference options results = model.predict(source=temp_file_name, conf=0.5, stream=False) # A list of bounding boxes (if any) is returned. # Each bounding box is in the format [x1, y1, x2, y2, probability, class]. result = {"results": results[0].boxes.data.tolist()} print(result) resp = make_response(result, 200) return resp else: abort(400) if __name__ == '__main__': app.run()


추론 서버를 시작해 보겠습니다.


 $ python detection_server.py * Serving Flask app 'detection_server' * Debug mode: off * Running on http://127.0.0.1:5000 Press CTRL+C to quit


Flask 애플리케이션이 실행 중인 호스트 이름과 포트를 기록해 둡니다.


다음으로 MinIO 측에서 웹후크 구성 작업을 시작하겠습니다. 먼저 다음 환경 변수를 설정합니다. <YOURFUNCTIONNAME>을 선택한 함수 이름으로 바꾸세요. 단순화를 위해 '추론'을 사용했습니다. 또한 엔드포인트 환경 변수가 추론 서버에 대한 올바른 호스트 및 포트로 설정되어 있는지 확인하세요. 이 경우 http://localhost:5000은 Flask 애플리케이션이 실행되는 곳입니다.


 $ export MINIO_NOTIFY_WEBHOOK_ENABLE_<YOURFUNCTIONNAME>=on $ export MINIO_NOTIFY_WEBHOOK_ENDPOINT_<YOURFUNCTIONNAME>=http://localhost:5000


이제 mc admin service restart ALIAS 명령을 사용하여 MinIO 서버를 다시 시작하거나 서버를 처음 시작하는 경우 minio 서버 명령을 사용할 수도 있습니다. MinIO 서버 다시 시작/다시 시작에 대한 자세한 내용은 MinIO 문서를 확인하세요. 참고: ALIAS는 MinIO 서버 배포에 대한 별칭으로 바꿔야 합니다. 별칭을 설정하거나 기존 별칭을 보는 방법에 대한 자세한 내용은 문서를 확인하세요.


마지막으로 알림을 받고 싶은 버킷과 이벤트를 추가해 보겠습니다. 우리의 경우 버킷의 ' put' 이벤트(새 객체 생성)에 대한 알림을 받고 싶습니다. 이 목적을 위해 '탐지 추론' 이라는 제목의 빈 버킷을 새로 만들었으므로 이를 'BUCKET'으로 대체하겠습니다.


 $ mc event add ALIAS/BUCKET arn:minio:sqs::<YOURFUNCTIONNAME>:webhook --event put


다음 명령을 실행할 때 " s3:ObjectCreated:* "가 출력되는지 확인하여 버킷 알림에 대한 올바른 이벤트 유형을 구성했는지 확인할 수 있습니다.


 $ mc event ls local/detect-inference arn:minio:sqs::<YOURFUNCTIONNAME>:webhook


버킷 이벤트를 웹훅에 게시하는 방법에 대한 자세한 설명은 문서를 확인하세요. 이제 새로운 이미지에서 객체 감지를 시도할 준비가 되었습니다!

추론 시스템 시험해보기

추론을 수행하려는 새 이미지('1.png')는 다음과 같습니다.


추론 시스템 시험해보기


'감지 추론' 버킷에 새 이미지를 삭제합니다.


새 버킷에 이미지 삭제


거의 즉시 Flask 서버에서 다음 결과를 볼 수 있습니다.


 $ python detection_server.py * Serving Flask app 'detection_server' * Debug mode: off * Running on http://127.0.0.1:5000 Press CTRL+C to quit image 1/1 /var/folders/xf/q7x0z8sn5nvckccp1g0m1vpm0000gn/T/tmpo6jx3w8u/1.png: 448x736 2 SU-30s, 101.0ms Speed: 4.1ms preprocess, 101.0ms inference, 5.8ms postprocess per image at shape (1, 3, 448, 736) {'results': [[1927.78369140625, 627.7123413085938, 1995.090576171875, 715.3443603515625, 0.8142037987709045, 0.0], [1735.740234375, 477.2108154296875, 1809.181640625, 555.767578125, 0.7766116261482239, 0.0]]} 127.0.0.1 - - [14/Sep/2023 15:39:21] "POST / HTTP/1.1" 200 -


결과 목록에서 감지된 각 경계 상자는 YOLO 형식 [x1, y1, x2, y2, 확률, 클래스]입니다. 원본 이미지에 겹쳐진 경계 상자와 예측 클래스는 다음과 같습니다.


다른 두 제트기는 Su-30이 아닙니다. 내 초기 데이터 세트에는 최대 100개의 이미지가 포함되어 있었기 때문에 모델이 이미 비슷하게 생긴 항공기 간의 미묘한 차이를 포착할 수 있다는 사실에 놀랐습니다. 여기서의 교훈은 경사하강법을 결코 과소평가하지 말라는 것입니다!


참고: 프로덕션 환경 및/또는 대규모 기계 학습 모델의 경우 PyTorch Serve 또는 Triton Server와 같은 확립된 모델 제공 프레임워크를 사용하여 추론을 더욱 강력하고 안정적으로 만드는 것이 좋습니다. 이에 관심이 있다면 MinIO 및 PyTorch Serve를 사용한 AI 모델 제공 최적화 에 대한 이전 게시물을 확인하세요.

결론적 생각

우리는 해냈다! 우리는 수집된 이미지 샘플을 안전하게 유지하고 사용 가능하게 유지하기 위해 MinIO와 CVAT를 함께 사용하는 방법과 사용자 지정 개체 감지 데이터 세트를 만드는 방법을 살펴보았습니다. 그런 다음 맞춤형 작업을 위해 자체 맞춤형 YOLO 모델을 교육했습니다. 마지막으로, 50줄이 조금 넘는 코드로 MinIO 버킷 알림을 사용하여 맞춤형 학습 개체 감지 모델을 지나 새 이미지를 실행할 수 있는 추론 서버를 구성했습니다.


MinIO와 YOLO가 엣지에 배포되었습니다.


또한 대부분의 미션 크리티컬 컴퓨터 비전 애플리케이션의 경우 에지에서 추론을 수행하는 것이 가장 좋습니다. 그렇지 않으면 해당 애플리케이션은 새로운 데이터를 퍼블릭 클라우드에 업로드하고 클라우드의 추론 서버가 응답을 받을 때까지 기다리는 것과 관련된 대기 시간에 취약합니다. 네트워크 연결 결함의 위험은 말할 것도 없습니다. 이러한 이유로 데이터 계층인 MinIO를 중심으로 하는 컴퓨터 비전 파이프라인이 훨씬 더 적합합니다. 비행장 위를 비행하는 드론이 완전히 내장된 하드웨어와 소프트웨어를 사용하여 새로운 이미지에 대해 훈련된 모델을 캡처, 저장 및 사용할 수 있다고 상상해 보십시오. MinIO 서버의 로컬 배포를 통해 게시물 끝부분에서 구축한 버킷 알림 기반 추론 시스템은 이 시나리오와 이와 유사한 수많은 다른 시나리오에 완벽하게 작동합니다.


질문이 있는 경우 Slack 채널 에 가입하거나 [email protected] 로 메모를 남겨주세요. 우리는 당신을 돕기 위해 여기 있습니다.


여기에도 게시되었습니다.