๐ท ํ์ต ์ค ์ ๋ฆฌํ ๋ด์ฉ์ผ๋ก ๋ฌธ์ ๊ฐ ์๋ค๋ฉด ๋ฉ์ผ(jnw__@๋ค์ด๋ฒ)๋ก ์ฐ๋ฝ ๋ถํ๋๋ฆฝ๋๋ค. :D
Reference
Reference
Baek Kyun Shin๋์ ๋ ผ๋ฌธ ๋ฆฌ๋ทฐ - YOLO(You Only Look Once) ํบ์๋ณด๊ธฐ
You Only Look Once๋ผ๋ ์ด๋ฆ์ YOLO
ํ ๋ฒ์ Convolution Network๋ก ์ด๋ฏธ์ง์ bounding box์ ๊ทธ ํ๋ฅ ์ ๊ณ์ฐํ์ฌ ๊ฐ์ฅ ํ๋ฅ ์ด ๋์ bounding box๋ฅผ ์ถ๋ก ํ๋ ๋ชจ๋ธ
๊ฐ์ฒด ํ์ง์ ์ข์ ์ฑ๋ฅ์ ๋ณด์ด๋ฉด์๋ ์ค์๊ฐ ํ์ง ์๋๋ ๋น ๋ฅด๋ค.
์ต๊ทผ Ultralytics์์ YOLOv8๋ฅผ ๋ฐํํ๊ณ , backbone๊ณผ neck architecture๋ฅผ ๊ฐํํ์ฌ ๊ฐ์ ๋ ์ฑ๋ฅ์ ๋ณด์ฌ์ค๋ค.
์๋ ๊ตฌ์กฐ๋ YOLOv4 ๋
ผ๋ฌธ์์ ๊ฐ์ ธ์จ ๊ฒ
Docs์ ์ ์ ๋ฆฌ๋ ๋ด์ฉ๋ค์ ์ค์ตํด๋ณด๋ฉด์ MLFlow๋ก ๊ฐ๋จํ๊ฒ ํ์ต ๊ด๋ฆฌ๋ฅผ ํด๋ณด์๊ณ , ๊ทธ ๋ด์ฉ์ ๊ธฐ๋กํ๊ณ ์ ํ๋ค. :D
ํ ์คํธ ํ๊ฒฝ
- Linux 18.04
- Ultralytics YOLOv8.0.110
- Python-3.8.16
- torch-2.0.1+cu117 CUDA:0
- (Tesla V100-SXM2-32GB, 32510MiB)
ํจํค์ง ์ค์น
pip install ultralytics
pip install opencv-python
๐ ๋น ๋ฅด๊ณ ๊ฐ๋จํ ์ฌ์ฉ์ฑ
์ด๋ฏธ ํ์ต๋ ๋ชจ๋ธ์ ๊ฐ์ ธ์์ ๊ฐ๋จํ ํ ์คํธ ํด๋ณผ ์ ์๋ค.
from ultralytics import YOLO
import cv2
model = YOLO("yolov8n.pt")
# accepts all formats - image/dir/Path/URL/video/PIL/ndarray. 0 for webcam
# from ndarray
im2 = cv2.imread("bbang2.jpg")
results = model.predict(source=im2, save=True, save_txt=True) # save predictions as labels
์๋์ ๊ฐ์ด ์์ธก ๊ฒฐ๊ณผ๊ฐ ๋จ๊ณ ์ ์ฅ๋ ์ด๋ฏธ์ง๋ฅผ ํ์ธํ ์ ์๋ค.
640x480 8 persons, 7.0ms
Speed: 2.5ms preprocess, 7.0ms inference, 1.5ms postprocess per image at shape (1, 3, 640, 640)
๐ Custom Dataset ์ผ๋ก ํ์ต/์์ธก์ ํด๋ณด์.
- ์ด๋ฏธ์ง์ ํ์ผ ์ด๋ฆ์ด ๊ฐ์ ํ ์คํธ ์์ด ํ์
- ํ ์คํธ๋ ๊ฐ์ฒด์ class์ center_x, center_y, width, height๋ก ๊ตฌ์ฑ๋์ด์ผ ํ๋ค.
๐ Ultralytics๋ yaml ํ์ผ์ ์ ์ฅ๋ ๊ฒฝ๋ก๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ฐธ์กฐ
- ๋ฐ์ดํฐ ๊ฒฝ๋ก ์ค๋ฅ๊ฐ ๋๋ฉด ์๋ ํ์ผ์์
datasets_dir
์ ์์ ํ๋ฉด ๋จ
- .config/Ultralytics/settings.yaml
YOLO ๋ชจ๋ธ์ ์ฌ์ฉํ ์ ์๊ฒ ๋ฐ์ดํฐ ๋ณํ
object_class center_x center_y width height
๋ก ์ฐ์ฌ์ผ ํ๋ค.๋ณํ ์ฝ๋
image_width
, image_height
๋ก ๋๋ ์ฃผ๋๊ฒ์ bounding box์ ํฌํค๋ฅผ ์ผ๋ฐํํ๊ธฐ ์ํจx_min, y_min = float(min(line[5], line[7])), float(min(line[6], line[8]))
x_max, y_max = float(max(line[1], line[3])), float(max(line[2], line[4]))
x, y = float(((x_min + x_max) / 2) / image_width), float(((y_min + y_max) / 2) / image_height)
w, h = abs(x_max - x_min) / image_width, abs(y_max - y_min) / image_height
yolo_labels.append(f"{class_name} {x} {y} {w} {h}")
๐ YOLO ๋ชจ๋ธ์ yaml ํ์ผ์ ๊ธฐ์ค์ผ๋ก ๋ฐ์ดํฐ์ ๋ถ๋ฅ ํด๋์ค๋ฅผ ์ฐธ์กฐ
yaml ํ์ผ ์ ์
yaml_data = {
"names": classes,
"nc": len(classes),
"path": "data/yolo/",
"train": "train",
"val": "valid",
"test": "test"
}
train
# model = YOLO(f"{MODEL}/train/weights/last.pt")
model = YOLO("yolov8x")
results = model.train(
**opt
)
predict
model = YOLO("v2/train/weights/best.pt")
test_image_paths = glob("./data/yolo/test/*.png")
for i, image in tqdm(enumerate(get_test_image_paths(test_image_paths)), total=int(len(test_image_paths)/BATCH_SIZE)):
model.predict(image, imgsz=(1024, 1024), iou=0.2, conf=0.5, save_conf=True, save=False, save_txt=True, project=f"{MODEL}", name="predict",
exist_ok=True, device=0, augment=True, verbose=False)
if i % 5 == 0:
clear_output(wait=True)
result
๐ ๋ ์ข์ ๋ฐฉ๋ฒ์ด ์๋ค๋ฉด ๊ผญ ์๋ ค์ฃผ์ธ์ !
์ฐธ๊ณ
Databricks ๋ฌด๋ฃ ๋ฒ์ ์ ์๋ ๋ฒํผ์ผ๋ก ๊ฐ์ ํ๊ธฐ
๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น
conda install mlflow
conda install databricks-cli
๊ณ์ ์ค์
databricks configure --host https://community.cloud.databricks.com/
call back function ์ ์ธ
def on_fit_epoch_end(trainer):
if mlflow:
metrics_dict = {f"{re.sub('[()]', '', k)}": float(v) for k, v in trainer.metrics.items()}
mlflow.log_metrics(metrics=metrics_dict, step=trainer.epoch)
import mlflow
mlflow.set_tracking_uri("databricks")
mlflow.set_experiment("/Users/{user-id}/{project-name}")
# ์คํ ์ธ์
์์ฑ
with mlflow.start_run():
model.add_callback("on_fit_epoch_end",on_fit_epoch_end)
results = model.train(
**opt
)
๐ 8๊ธฐ๊ฐ ์ด์์ ๋จ์ ํ ๋นํ ๊ฒ์ ์ ์
- ์ค๋ฅ๊ฐ ์์ฒญ ๋ฐ์ํ๋๋ฐ, ์ค์ต์ฉ์ผ๋ก epoch๋ฅผ ๋ฎ์ถฐ์ ์คํ
ํจํค์ง ์ค์น
pip install -U ultralytics "ray[tune]" # install and/or update pip install wandb # optional
from ray import tune
model = YOLO(f"{MODEL}/train/weights/last.pt")
result = model.tune(
data="/opt/ml/yujin/DataAnalysisPractice/Dacon/03.๋ฐ์ด์ฝ ํฉ์ฑ๋ฐ์ดํฐ ๊ธฐ๋ฐ ๊ฐ์ฒด ํ์ง AI ๊ฒฝ์ง๋ํ/data/yolo/custom.yaml",
space={"lr0": tune.uniform(1e-5, 1e-1)},
train_args={"epochs": 10}
)