feat: 초기 프로젝트 구조 추가

This commit is contained in:
Kim Min Jae
2026-06-10 16:18:41 +09:00
parent 5d985560c5
commit a48a4b5fe5
100 changed files with 10530 additions and 0 deletions

3
ai/__init__.py Normal file
View File

@@ -0,0 +1,3 @@
# ai 패키지 — Detector, Trainer 노출
from .detector import Detector
from .trainer import Trainer

9
ai/dataset/data.yaml Normal file
View File

@@ -0,0 +1,9 @@
names:
- 스크래치
- 이물
- 흑점
- 변형
nc: 4
path: e:\ANT\ai\dataset
train: images/train
val: images/val

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

View File

@@ -0,0 +1 @@
0 0.233974 0.409524 0.339744 0.590476

View File

@@ -0,0 +1 @@
0 0.318598 0.542781 0.472561 0.754011

BIN
ai/dataset/labels/val.cache Normal file

Binary file not shown.

View File

@@ -0,0 +1,2 @@
0 0.227074 0.195219 0.401747 0.215139
1 0.853712 0.252988 0.257642 0.330677

59
ai/detector.py Normal file
View File

@@ -0,0 +1,59 @@
# AI 추론 — YOLOv8 기반 불량(스크래치/이물/흑점/변형) 검출
import os
import numpy as np
from utils.path_helper import BASE_PATH
class Detector:
class_names = ["스크래치", "이물", "흑점", "변형"]
def __init__(self):
self._model = None
self.model_path = None
def load_model(self, model_path: str) -> bool:
if model_path and not os.path.isabs(model_path):
model_path = os.path.join(BASE_PATH, model_path)
try:
from ultralytics import YOLO # 지연 로딩 — 앱 시작 시 torch DLL 오류 방지
self._model = YOLO(model_path)
self.model_path = model_path
print(f"[AI] 모델 로드 성공: {model_path}")
return True
except Exception as e:
print(f"[AI] 모델 로드 실패: {e}")
self._model = None
return False
def is_loaded(self) -> bool:
return self._model is not None
def detect(self, image: np.ndarray) -> list:
"""
image: numpy array (BGR)
반환: [{"class_id": int, "class_name": str,
"confidence": float, "bbox": [x1,y1,x2,y2]}, ...]
"""
if self._model is None:
return []
try:
results = self._model(image, verbose=False)
detections = []
for result in results:
for box in result.boxes:
class_id = int(box.cls[0])
detections.append({
"class_id": class_id,
"class_name": (
self.class_names[class_id]
if class_id < len(self.class_names)
else str(class_id)
),
"confidence": float(box.conf[0]),
"bbox": box.xyxy[0].tolist(),
})
return detections
except Exception as e:
print(f"[AI] 추론 오류: {e}")
return []

BIN
ai/models/best.pt Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

110
ai/runs/train/args.yaml Normal file
View File

@@ -0,0 +1,110 @@
task: detect
mode: train
model: yolov8n.pt
data: e:\ANT\ai\dataset\data.yaml
epochs: 100
time: null
patience: 100
batch: 16
imgsz: 640
save: true
save_period: -1
cache: false
device: null
workers: 0
project: e:\ANT\ai\runs
name: train
exist_ok: true
pretrained: true
optimizer: auto
verbose: true
seed: 0
deterministic: true
single_cls: false
rect: false
cos_lr: false
close_mosaic: 10
resume: false
amp: false
fraction: 1.0
profile: false
freeze: null
multi_scale: 0.0
compile: false
overlap_mask: true
mask_ratio: 4
dropout: 0.0
val: true
split: val
save_json: false
conf: null
iou: 0.7
max_det: 300
half: false
dnn: false
plots: false
end2end: null
source: null
vid_stride: 1
stream_buffer: false
visualize: false
augment: false
agnostic_nms: false
classes: null
retina_masks: false
embed: null
show: false
save_frames: false
save_txt: false
save_conf: false
save_crop: false
show_labels: true
show_conf: true
show_boxes: true
line_width: null
format: torchscript
keras: false
optimize: false
int8: false
dynamic: false
simplify: true
opset: null
workspace: null
nms: false
lr0: 0.01
lrf: 0.01
momentum: 0.937
weight_decay: 0.0005
warmup_epochs: 3.0
warmup_momentum: 0.8
warmup_bias_lr: 0.1
box: 7.5
cls: 0.5
cls_pw: 0.0
dfl: 1.5
pose: 12.0
kobj: 1.0
rle: 1.0
angle: 1.0
nbs: 64
hsv_h: 0.015
hsv_s: 0.7
hsv_v: 0.4
degrees: 0.0
translate: 0.1
scale: 0.5
shear: 0.0
perspective: 0.0
flipud: 0.0
fliplr: 0.5
bgr: 0.0
mosaic: 1.0
mixup: 0.0
cutmix: 0.0
copy_paste: 0.0
copy_paste_mode: flip
auto_augment: randaugment
erasing: 0.4
cfg: null
tracker: botsort.yaml
save_dir: E:\ANT\ai\runs\train

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

101
ai/runs/train/results.csv Normal file
View File

@@ -0,0 +1,101 @@
epoch,time,train/box_loss,train/cls_loss,train/dfl_loss,metrics/precision(B),metrics/recall(B),metrics/mAP50(B),metrics/mAP50-95(B),val/box_loss,val/cls_loss,val/dfl_loss,lr/pg0,lr/pg1,lr/pg2
1,0.744601,2.4784,4.2576,2.37292,0.00581,0.5,0.00599,0.00178,2.08106,4.5092,2.3941,0,0,0
2,1.17594,3.54636,4.89413,2.76008,0.00588,0.5,0.00622,0.00124,2.10159,4.51392,2.40401,1.23763e-05,1.23763e-05,1.23763e-05
3,1.4434,3.2212,4.47996,3.91873,0.01514,1,0.01568,0.0022,2.24221,4.37976,2.4629,2.4505e-05,2.4505e-05,2.4505e-05
4,1.81097,3.23832,4.18544,3.38558,0.01459,1,0.01534,0.0037,2.32948,4.47892,2.46147,3.63862e-05,3.63862e-05,3.63862e-05
5,2.17724,2.76973,4.43589,2.74067,0.00556,0.5,0.00711,0.00195,2.33679,4.46132,2.45867,4.802e-05,4.802e-05,4.802e-05
6,2.47758,2.93916,4.25681,2.81574,0.00562,0.5,0.00711,0.00197,2.23356,4.4439,2.55513,5.94062e-05,5.94062e-05,5.94062e-05
7,2.77856,2.95798,3.80506,2.41629,0.01433,1,0.0167,0.00167,2.13047,4.47684,2.46296,7.0545e-05,7.0545e-05,7.0545e-05
8,3.08538,2.97272,3.8706,2.66583,0.00847,0.5,0.00939,0.00094,1.93983,4.4964,2.44096,8.14362e-05,8.14362e-05,8.14362e-05
9,3.38628,1.96121,4.27233,2.04591,0,0,0,0,1.67434,4.64554,2.3051,9.208e-05,9.208e-05,9.208e-05
10,3.68733,2.62766,3.67184,2.50334,0,0,0,0,1.44683,4.71852,2.19216,0.000102476,0.000102476,0.000102476
11,3.97817,2.60241,4.1424,2.70991,0.00556,0.5,0.01605,0.0016,1.42181,4.70011,2.16441,0.000112625,0.000112625,0.000112625
12,4.28608,3.28551,4.52089,2.67545,0.00588,0.5,0.01345,0.00269,1.52292,4.67835,2.13383,0.000122526,0.000122526,0.000122526
13,4.58546,2.2033,4.2669,2.49512,0.00562,0.5,0.01157,0.00231,1.68387,4.61194,2.17338,0.00013218,0.00013218,0.00013218
14,4.88485,2.87394,4.40826,2.70916,0.00568,0.5,0.00975,0.00195,1.89075,4.58147,2.30027,0.000141586,0.000141586,0.000141586
15,5.19968,2.71982,4.27341,2.72914,0,0,0,0,1.96866,4.44855,2.33624,0.000150745,0.000150745,0.000150745
16,5.49215,1.68605,4.24646,1.87531,0,0,0,0,2.00553,4.48707,2.29285,0.000159656,0.000159656,0.000159656
17,5.79325,2.00138,3.94773,2.26758,0,0,0,0,2.09648,4.63246,2.4007,0.00016832,0.00016832,0.00016832
18,6.09155,3.05671,5.53908,2.66707,0,0,0,0,2.09648,4.63246,2.4007,0.000176736,0.000176736,0.000176736
19,6.39052,2.20901,3.52372,2.04393,0.00806,0.5,0.02369,0.00237,2.20865,4.54601,2.56285,0.000184905,0.000184905,0.000184905
20,6.66892,2.4483,3.70065,2.23467,0.00806,0.5,0.02369,0.00237,2.20865,4.54601,2.56285,0.000192826,0.000192826,0.000192826
21,6.9332,2.19448,3.86943,2.10117,0.00463,0.5,0.03317,0.00663,2.32559,4.48125,2.62548,0.0002005,0.0002005,0.0002005
22,7.30519,2.9479,4.3599,2.76934,0.00463,0.5,0.03317,0.00663,2.32559,4.48125,2.62548,0.000207926,0.000207926,0.000207926
23,7.68986,1.39714,3.40426,1.6151,0.01578,1,0.08837,0.01146,2.44041,4.6826,2.72339,0.000215105,0.000215105,0.000215105
24,7.99967,2.46841,3.48691,2.13383,0.01578,1,0.08837,0.01146,2.44041,4.6826,2.72339,0.000222036,0.000222036,0.000222036
25,8.31396,2.56835,4.10281,2.20972,0.00481,0.5,0.01777,0.00355,2.61255,4.61058,2.86581,0.00022872,0.00022872,0.00022872
26,8.55453,1.65391,3.70866,1.88456,0.00481,0.5,0.01777,0.00355,2.61255,4.61058,2.86581,0.000235156,0.000235156,0.000235156
27,8.80235,2.00119,3.45089,1.89926,0.01604,1,0.05212,0.00521,2.74287,4.6437,2.91424,0.000241345,0.000241345,0.000241345
28,9.04528,1.89956,3.68555,2.16165,0.01604,1,0.05212,0.00521,2.74287,4.6437,2.91424,0.000247286,0.000247286,0.000247286
29,9.29273,1.42472,2.92227,1.75125,0.01111,0.5,0.12437,0.01244,3.06977,4.5736,3.06093,0.00025298,0.00025298,0.00025298
30,9.60359,1.35767,2.62078,1.55004,0.01111,0.5,0.12437,0.01244,3.06977,4.5736,3.06093,0.000258426,0.000258426,0.000258426
31,9.94422,2.37035,4.66417,2.27559,0.01316,0.5,0.16583,0.01658,3.36893,4.24859,3.23425,0.000263625,0.000263625,0.000263625
32,10.2594,1.61322,2.86179,1.53237,0.01316,0.5,0.16583,0.01658,3.36893,4.24859,3.23425,0.000268576,0.000268576,0.000268576
33,10.6412,1.85856,3.15064,1.88045,0.02083,0.5,0.16583,0.01658,3.44544,4.47775,3.34489,0.00027328,0.00027328,0.00027328
34,10.9661,1.62452,2.88937,1.72429,0.02083,0.5,0.16583,0.01658,3.44544,4.47775,3.34489,0.000277736,0.000277736,0.000277736
35,11.2888,1.21431,3.51628,1.62717,0,0,0,0,3.47481,4.57555,3.33539,0.000281945,0.000281945,0.000281945
36,11.5318,1.39337,2.94668,1.47319,0,0,0,0,3.47481,4.57555,3.33539,0.000285906,0.000285906,0.000285906
37,11.7887,2.14196,3.0238,1.80533,0,0,0,0,3.7452,4.84862,3.44227,0.00028962,0.00028962,0.00028962
38,12.0408,1.81846,2.33607,1.79617,0,0,0,0,3.7452,4.84862,3.44227,0.000293086,0.000293086,0.000293086
39,12.2951,1.17175,1.92086,1.3652,0,0,0,0,4.06912,4.91101,3.62994,0.000296305,0.000296305,0.000296305
40,12.5315,1.62593,2.48208,1.50529,0,0,0,0,4.06912,4.91101,3.62994,0.000299276,0.000299276,0.000299276
41,12.8727,2.11165,2.67321,1.7814,0,0,0,0,4.39582,4.54093,3.81935,0.000302,0.000302,0.000302
42,13.1287,1.58216,2.68408,1.63978,0,0,0,0,4.39582,4.54093,3.81935,0.000304476,0.000304476,0.000304476
43,13.4027,1.4236,2.75829,1.527,0.01351,0.5,0.02163,0.00216,4.3829,4.34724,3.73475,0.000306705,0.000306705,0.000306705
44,13.6611,1.58086,3.04931,1.97095,0.01351,0.5,0.02163,0.00216,4.3829,4.34724,3.73475,0.000308686,0.000308686,0.000308686
45,13.94,1.70552,2.1028,1.7847,0.0119,0.5,0.03109,0.00311,4.02893,4.68709,3.46274,0.00031042,0.00031042,0.00031042
46,14.2063,1.17287,2.30212,1.21687,0.0119,0.5,0.03109,0.00311,4.02893,4.68709,3.46274,0.000311906,0.000311906,0.000311906
47,14.4787,0.75953,1.79745,0.99198,0.01111,0.5,0.04523,0.00452,4.16401,4.4644,3.55846,0.000313145,0.000313145,0.000313145
48,14.7356,2.12559,4.16293,2.21951,0.01111,0.5,0.04523,0.00452,4.16401,4.4644,3.55846,0.000314136,0.000314136,0.000314136
49,15.0753,0.92121,2.05049,1.10199,0.00962,0.5,0.04146,0.00829,3.90365,4.64333,3.48688,0.00031488,0.00031488,0.00031488
50,15.3345,1.19831,1.99876,1.28056,0.00962,0.5,0.04146,0.00829,3.90365,4.64333,3.48688,0.000315376,0.000315376,0.000315376
51,15.6062,2.135,2.40625,1.81904,0.01042,0.5,0.05528,0.0229,3.18088,5.77238,3.2612,0.000315625,0.000315625,0.000315625
52,15.9429,1.72253,3.24847,1.71661,0.01042,0.5,0.05528,0.0229,3.18088,5.77238,3.2612,0.000315626,0.000315626,0.000315626
53,16.2756,0.98827,2.52014,1.26921,0.01042,0.5,0.05528,0.0229,3.18088,5.77238,3.2612,0.00031538,0.00031538,0.00031538
54,16.6349,1.8328,2.53368,1.66716,0.01316,0.5,0.12437,0.01244,3.8633,4.65938,3.23911,0.000314886,0.000314886,0.000314886
55,16.8944,1.1818,1.78296,1.15008,0.01316,0.5,0.12437,0.01244,3.8633,4.65938,3.23911,0.000314145,0.000314145,0.000314145
56,17.2351,1.26713,2.38825,1.40594,0.01316,0.5,0.12437,0.01244,3.8633,4.65938,3.23911,0.000313156,0.000313156,0.000313156
57,17.5174,1.32827,1.94378,1.44297,0.01562,0.5,0.02073,0.00207,3.86529,4.77191,3.13775,0.00031192,0.00031192,0.00031192
58,17.7998,0.93866,1.97455,1.19817,0.01562,0.5,0.02073,0.00207,3.86529,4.77191,3.13775,0.000310436,0.000310436,0.000310436
59,18.0565,1.34164,4.69334,1.52493,0.01562,0.5,0.02073,0.00207,3.86529,4.77191,3.13775,0.000308705,0.000308705,0.000308705
60,18.3262,1.70827,3.61104,1.67179,0,0,0,0,3.93656,4.99738,3.11248,0.000306726,0.000306726,0.000306726
61,18.6133,0.82569,1.96032,1.1105,0,0,0,0,3.93656,4.99738,3.11248,0.0003045,0.0003045,0.0003045
62,18.8669,1.33918,2.16787,1.37237,0,0,0,0,3.93656,4.99738,3.11248,0.000302026,0.000302026,0.000302026
63,19.133,0.9404,2.00419,1.09295,0,0,0,0,3.54929,5.50927,3.04358,0.000299305,0.000299305,0.000299305
64,19.4517,0.83957,1.71834,1.04536,0,0,0,0,3.54929,5.50927,3.04358,0.000296336,0.000296336,0.000296336
65,19.7046,1.05975,1.98836,1.25573,0,0,0,0,3.54929,5.50927,3.04358,0.00029312,0.00029312,0.00029312
66,19.966,0.79495,1.71511,1.07986,0.01111,0.5,0.02073,0.00415,3.48677,6.07562,2.94905,0.000289656,0.000289656,0.000289656
67,20.2315,0.89674,1.76647,1.12805,0.01111,0.5,0.02073,0.00415,3.48677,6.07562,2.94905,0.000285945,0.000285945,0.000285945
68,20.4951,1.27186,2.05522,1.24621,0.01111,0.5,0.02073,0.00415,3.48677,6.07562,2.94905,0.000281986,0.000281986,0.000281986
69,20.763,0.72455,1.86789,1.0569,0,0,0,0,4.16796,5.98914,3.4865,0.00027778,0.00027778,0.00027778
70,21.0206,0.94838,1.5672,1.15049,0,0,0,0,4.16796,5.98914,3.4865,0.000273326,0.000273326,0.000273326
71,21.2798,1.62956,2.8345,1.75908,0,0,0,0,4.16796,5.98914,3.4865,0.000268625,0.000268625,0.000268625
72,21.6185,0.82159,1.62683,0.94171,0,0,0,0,4.70051,5.39397,3.87655,0.000263676,0.000263676,0.000263676
73,21.8885,0.84998,2.02611,1.30797,0,0,0,0,4.70051,5.39397,3.87655,0.00025848,0.00025848,0.00025848
74,22.1454,0.85087,1.42472,1.15593,0,0,0,0,4.70051,5.39397,3.87655,0.000253036,0.000253036,0.000253036
75,22.4095,1.1786,1.83474,1.21092,0,0,0,0,4.86689,6.24371,3.95955,0.000247345,0.000247345,0.000247345
76,22.6694,0.78564,1.66187,0.97539,0,0,0,0,4.86689,6.24371,3.95955,0.000241406,0.000241406,0.000241406
77,22.9286,0.79013,1.96926,1.26206,0,0,0,0,4.86689,6.24371,3.95955,0.00023522,0.00023522,0.00023522
78,23.1943,0.8152,1.59465,1.07906,0,0,0,0,4.81344,5.97521,4.01022,0.000228786,0.000228786,0.000228786
79,23.4546,0.61829,1.29337,0.98868,0,0,0,0,4.81344,5.97521,4.01022,0.000222105,0.000222105,0.000222105
80,23.7685,0.95007,1.79471,1.1416,0,0,0,0,4.81344,5.97521,4.01022,0.000215176,0.000215176,0.000215176
81,24.1034,0.93272,2.22583,1.20421,0.00617,0.5,0.00905,0.0009,4.60774,5.39816,3.81369,0.000208,0.000208,0.000208
82,24.3629,0.63241,1.21512,1.08097,0.00617,0.5,0.00905,0.0009,4.60774,5.39816,3.81369,0.000200576,0.000200576,0.000200576
83,24.6222,1.39649,2.39204,1.52958,0.00617,0.5,0.00905,0.0009,4.60774,5.39816,3.81369,0.000192905,0.000192905,0.000192905
84,24.9101,0.63485,1.24139,0.96726,0.00641,0.5,0.01913,0.00459,4.14874,5.15654,3.60735,0.000184986,0.000184986,0.000184986
85,25.1903,0.88995,1.76109,1.04753,0.00641,0.5,0.01913,0.00459,4.14874,5.15654,3.60735,0.00017682,0.00017682,0.00017682
86,25.4597,1.16455,2.35159,1.15176,0.00641,0.5,0.01913,0.00459,4.14874,5.15654,3.60735,0.000168406,0.000168406,0.000168406
87,25.761,0.86574,1.60094,1.1271,0.00641,0.5,0.01913,0.00459,4.14874,5.15654,3.60735,0.000159745,0.000159745,0.000159745
88,26.1232,0.57931,1.17361,0.95885,0.00704,0.5,0.01658,0.00332,3.66565,5.88071,3.25055,0.000150836,0.000150836,0.000150836
89,26.4022,0.88857,1.97356,1.07497,0.00704,0.5,0.01658,0.00332,3.66565,5.88071,3.25055,0.00014168,0.00014168,0.00014168
90,26.7071,0.71015,1.22162,1.07789,0.00704,0.5,0.01658,0.00332,3.66565,5.88071,3.25055,0.000132276,0.000132276,0.000132276
91,27.0615,0.80611,2.15097,0.95926,0.00704,0.5,0.01658,0.00332,3.66565,5.88071,3.25055,0.000122625,0.000122625,0.000122625
92,27.3798,0.75395,1.9817,1.18844,0.00758,0.5,0.01463,0.00368,3.64756,5.57493,3.04703,0.000112726,0.000112726,0.000112726
93,27.6734,0.52999,2.16673,0.94249,0.00758,0.5,0.01463,0.00368,3.64756,5.57493,3.04703,0.00010258,0.00010258,0.00010258
94,27.9692,0.29519,1.34975,0.94508,0.00758,0.5,0.01463,0.00368,3.64756,5.57493,3.04703,9.21862e-05,9.21862e-05,9.21862e-05
95,28.2525,0.533,1.80971,0.96369,0.00758,0.5,0.01463,0.00368,3.64756,5.57493,3.04703,8.1545e-05,8.1545e-05,8.1545e-05
96,28.5584,0.37619,1.67301,0.82287,0.00714,0.5,0.01309,0.00361,3.45585,5.23022,2.909,7.06563e-05,7.06563e-05,7.06563e-05
97,28.8522,0.58993,1.73032,0.93823,0.00714,0.5,0.01309,0.00361,3.45585,5.23022,2.909,5.952e-05,5.952e-05,5.952e-05
98,29.2014,1.19689,2.95317,1.27242,0.00714,0.5,0.01309,0.00361,3.45585,5.23022,2.909,4.81363e-05,4.81363e-05,4.81363e-05
99,29.5194,0.44641,1.50801,0.93925,0.00714,0.5,0.01309,0.00361,3.45585,5.23022,2.909,3.6505e-05,3.6505e-05,3.6505e-05
100,29.8906,0.52149,1.81476,0.89577,0.0061,0.5,0.01157,0.00231,3.45621,5.51821,2.93443,2.46263e-05,2.46263e-05,2.46263e-05
1 epoch time train/box_loss train/cls_loss train/dfl_loss metrics/precision(B) metrics/recall(B) metrics/mAP50(B) metrics/mAP50-95(B) val/box_loss val/cls_loss val/dfl_loss lr/pg0 lr/pg1 lr/pg2
2 1 0.744601 2.4784 4.2576 2.37292 0.00581 0.5 0.00599 0.00178 2.08106 4.5092 2.3941 0 0 0
3 2 1.17594 3.54636 4.89413 2.76008 0.00588 0.5 0.00622 0.00124 2.10159 4.51392 2.40401 1.23763e-05 1.23763e-05 1.23763e-05
4 3 1.4434 3.2212 4.47996 3.91873 0.01514 1 0.01568 0.0022 2.24221 4.37976 2.4629 2.4505e-05 2.4505e-05 2.4505e-05
5 4 1.81097 3.23832 4.18544 3.38558 0.01459 1 0.01534 0.0037 2.32948 4.47892 2.46147 3.63862e-05 3.63862e-05 3.63862e-05
6 5 2.17724 2.76973 4.43589 2.74067 0.00556 0.5 0.00711 0.00195 2.33679 4.46132 2.45867 4.802e-05 4.802e-05 4.802e-05
7 6 2.47758 2.93916 4.25681 2.81574 0.00562 0.5 0.00711 0.00197 2.23356 4.4439 2.55513 5.94062e-05 5.94062e-05 5.94062e-05
8 7 2.77856 2.95798 3.80506 2.41629 0.01433 1 0.0167 0.00167 2.13047 4.47684 2.46296 7.0545e-05 7.0545e-05 7.0545e-05
9 8 3.08538 2.97272 3.8706 2.66583 0.00847 0.5 0.00939 0.00094 1.93983 4.4964 2.44096 8.14362e-05 8.14362e-05 8.14362e-05
10 9 3.38628 1.96121 4.27233 2.04591 0 0 0 0 1.67434 4.64554 2.3051 9.208e-05 9.208e-05 9.208e-05
11 10 3.68733 2.62766 3.67184 2.50334 0 0 0 0 1.44683 4.71852 2.19216 0.000102476 0.000102476 0.000102476
12 11 3.97817 2.60241 4.1424 2.70991 0.00556 0.5 0.01605 0.0016 1.42181 4.70011 2.16441 0.000112625 0.000112625 0.000112625
13 12 4.28608 3.28551 4.52089 2.67545 0.00588 0.5 0.01345 0.00269 1.52292 4.67835 2.13383 0.000122526 0.000122526 0.000122526
14 13 4.58546 2.2033 4.2669 2.49512 0.00562 0.5 0.01157 0.00231 1.68387 4.61194 2.17338 0.00013218 0.00013218 0.00013218
15 14 4.88485 2.87394 4.40826 2.70916 0.00568 0.5 0.00975 0.00195 1.89075 4.58147 2.30027 0.000141586 0.000141586 0.000141586
16 15 5.19968 2.71982 4.27341 2.72914 0 0 0 0 1.96866 4.44855 2.33624 0.000150745 0.000150745 0.000150745
17 16 5.49215 1.68605 4.24646 1.87531 0 0 0 0 2.00553 4.48707 2.29285 0.000159656 0.000159656 0.000159656
18 17 5.79325 2.00138 3.94773 2.26758 0 0 0 0 2.09648 4.63246 2.4007 0.00016832 0.00016832 0.00016832
19 18 6.09155 3.05671 5.53908 2.66707 0 0 0 0 2.09648 4.63246 2.4007 0.000176736 0.000176736 0.000176736
20 19 6.39052 2.20901 3.52372 2.04393 0.00806 0.5 0.02369 0.00237 2.20865 4.54601 2.56285 0.000184905 0.000184905 0.000184905
21 20 6.66892 2.4483 3.70065 2.23467 0.00806 0.5 0.02369 0.00237 2.20865 4.54601 2.56285 0.000192826 0.000192826 0.000192826
22 21 6.9332 2.19448 3.86943 2.10117 0.00463 0.5 0.03317 0.00663 2.32559 4.48125 2.62548 0.0002005 0.0002005 0.0002005
23 22 7.30519 2.9479 4.3599 2.76934 0.00463 0.5 0.03317 0.00663 2.32559 4.48125 2.62548 0.000207926 0.000207926 0.000207926
24 23 7.68986 1.39714 3.40426 1.6151 0.01578 1 0.08837 0.01146 2.44041 4.6826 2.72339 0.000215105 0.000215105 0.000215105
25 24 7.99967 2.46841 3.48691 2.13383 0.01578 1 0.08837 0.01146 2.44041 4.6826 2.72339 0.000222036 0.000222036 0.000222036
26 25 8.31396 2.56835 4.10281 2.20972 0.00481 0.5 0.01777 0.00355 2.61255 4.61058 2.86581 0.00022872 0.00022872 0.00022872
27 26 8.55453 1.65391 3.70866 1.88456 0.00481 0.5 0.01777 0.00355 2.61255 4.61058 2.86581 0.000235156 0.000235156 0.000235156
28 27 8.80235 2.00119 3.45089 1.89926 0.01604 1 0.05212 0.00521 2.74287 4.6437 2.91424 0.000241345 0.000241345 0.000241345
29 28 9.04528 1.89956 3.68555 2.16165 0.01604 1 0.05212 0.00521 2.74287 4.6437 2.91424 0.000247286 0.000247286 0.000247286
30 29 9.29273 1.42472 2.92227 1.75125 0.01111 0.5 0.12437 0.01244 3.06977 4.5736 3.06093 0.00025298 0.00025298 0.00025298
31 30 9.60359 1.35767 2.62078 1.55004 0.01111 0.5 0.12437 0.01244 3.06977 4.5736 3.06093 0.000258426 0.000258426 0.000258426
32 31 9.94422 2.37035 4.66417 2.27559 0.01316 0.5 0.16583 0.01658 3.36893 4.24859 3.23425 0.000263625 0.000263625 0.000263625
33 32 10.2594 1.61322 2.86179 1.53237 0.01316 0.5 0.16583 0.01658 3.36893 4.24859 3.23425 0.000268576 0.000268576 0.000268576
34 33 10.6412 1.85856 3.15064 1.88045 0.02083 0.5 0.16583 0.01658 3.44544 4.47775 3.34489 0.00027328 0.00027328 0.00027328
35 34 10.9661 1.62452 2.88937 1.72429 0.02083 0.5 0.16583 0.01658 3.44544 4.47775 3.34489 0.000277736 0.000277736 0.000277736
36 35 11.2888 1.21431 3.51628 1.62717 0 0 0 0 3.47481 4.57555 3.33539 0.000281945 0.000281945 0.000281945
37 36 11.5318 1.39337 2.94668 1.47319 0 0 0 0 3.47481 4.57555 3.33539 0.000285906 0.000285906 0.000285906
38 37 11.7887 2.14196 3.0238 1.80533 0 0 0 0 3.7452 4.84862 3.44227 0.00028962 0.00028962 0.00028962
39 38 12.0408 1.81846 2.33607 1.79617 0 0 0 0 3.7452 4.84862 3.44227 0.000293086 0.000293086 0.000293086
40 39 12.2951 1.17175 1.92086 1.3652 0 0 0 0 4.06912 4.91101 3.62994 0.000296305 0.000296305 0.000296305
41 40 12.5315 1.62593 2.48208 1.50529 0 0 0 0 4.06912 4.91101 3.62994 0.000299276 0.000299276 0.000299276
42 41 12.8727 2.11165 2.67321 1.7814 0 0 0 0 4.39582 4.54093 3.81935 0.000302 0.000302 0.000302
43 42 13.1287 1.58216 2.68408 1.63978 0 0 0 0 4.39582 4.54093 3.81935 0.000304476 0.000304476 0.000304476
44 43 13.4027 1.4236 2.75829 1.527 0.01351 0.5 0.02163 0.00216 4.3829 4.34724 3.73475 0.000306705 0.000306705 0.000306705
45 44 13.6611 1.58086 3.04931 1.97095 0.01351 0.5 0.02163 0.00216 4.3829 4.34724 3.73475 0.000308686 0.000308686 0.000308686
46 45 13.94 1.70552 2.1028 1.7847 0.0119 0.5 0.03109 0.00311 4.02893 4.68709 3.46274 0.00031042 0.00031042 0.00031042
47 46 14.2063 1.17287 2.30212 1.21687 0.0119 0.5 0.03109 0.00311 4.02893 4.68709 3.46274 0.000311906 0.000311906 0.000311906
48 47 14.4787 0.75953 1.79745 0.99198 0.01111 0.5 0.04523 0.00452 4.16401 4.4644 3.55846 0.000313145 0.000313145 0.000313145
49 48 14.7356 2.12559 4.16293 2.21951 0.01111 0.5 0.04523 0.00452 4.16401 4.4644 3.55846 0.000314136 0.000314136 0.000314136
50 49 15.0753 0.92121 2.05049 1.10199 0.00962 0.5 0.04146 0.00829 3.90365 4.64333 3.48688 0.00031488 0.00031488 0.00031488
51 50 15.3345 1.19831 1.99876 1.28056 0.00962 0.5 0.04146 0.00829 3.90365 4.64333 3.48688 0.000315376 0.000315376 0.000315376
52 51 15.6062 2.135 2.40625 1.81904 0.01042 0.5 0.05528 0.0229 3.18088 5.77238 3.2612 0.000315625 0.000315625 0.000315625
53 52 15.9429 1.72253 3.24847 1.71661 0.01042 0.5 0.05528 0.0229 3.18088 5.77238 3.2612 0.000315626 0.000315626 0.000315626
54 53 16.2756 0.98827 2.52014 1.26921 0.01042 0.5 0.05528 0.0229 3.18088 5.77238 3.2612 0.00031538 0.00031538 0.00031538
55 54 16.6349 1.8328 2.53368 1.66716 0.01316 0.5 0.12437 0.01244 3.8633 4.65938 3.23911 0.000314886 0.000314886 0.000314886
56 55 16.8944 1.1818 1.78296 1.15008 0.01316 0.5 0.12437 0.01244 3.8633 4.65938 3.23911 0.000314145 0.000314145 0.000314145
57 56 17.2351 1.26713 2.38825 1.40594 0.01316 0.5 0.12437 0.01244 3.8633 4.65938 3.23911 0.000313156 0.000313156 0.000313156
58 57 17.5174 1.32827 1.94378 1.44297 0.01562 0.5 0.02073 0.00207 3.86529 4.77191 3.13775 0.00031192 0.00031192 0.00031192
59 58 17.7998 0.93866 1.97455 1.19817 0.01562 0.5 0.02073 0.00207 3.86529 4.77191 3.13775 0.000310436 0.000310436 0.000310436
60 59 18.0565 1.34164 4.69334 1.52493 0.01562 0.5 0.02073 0.00207 3.86529 4.77191 3.13775 0.000308705 0.000308705 0.000308705
61 60 18.3262 1.70827 3.61104 1.67179 0 0 0 0 3.93656 4.99738 3.11248 0.000306726 0.000306726 0.000306726
62 61 18.6133 0.82569 1.96032 1.1105 0 0 0 0 3.93656 4.99738 3.11248 0.0003045 0.0003045 0.0003045
63 62 18.8669 1.33918 2.16787 1.37237 0 0 0 0 3.93656 4.99738 3.11248 0.000302026 0.000302026 0.000302026
64 63 19.133 0.9404 2.00419 1.09295 0 0 0 0 3.54929 5.50927 3.04358 0.000299305 0.000299305 0.000299305
65 64 19.4517 0.83957 1.71834 1.04536 0 0 0 0 3.54929 5.50927 3.04358 0.000296336 0.000296336 0.000296336
66 65 19.7046 1.05975 1.98836 1.25573 0 0 0 0 3.54929 5.50927 3.04358 0.00029312 0.00029312 0.00029312
67 66 19.966 0.79495 1.71511 1.07986 0.01111 0.5 0.02073 0.00415 3.48677 6.07562 2.94905 0.000289656 0.000289656 0.000289656
68 67 20.2315 0.89674 1.76647 1.12805 0.01111 0.5 0.02073 0.00415 3.48677 6.07562 2.94905 0.000285945 0.000285945 0.000285945
69 68 20.4951 1.27186 2.05522 1.24621 0.01111 0.5 0.02073 0.00415 3.48677 6.07562 2.94905 0.000281986 0.000281986 0.000281986
70 69 20.763 0.72455 1.86789 1.0569 0 0 0 0 4.16796 5.98914 3.4865 0.00027778 0.00027778 0.00027778
71 70 21.0206 0.94838 1.5672 1.15049 0 0 0 0 4.16796 5.98914 3.4865 0.000273326 0.000273326 0.000273326
72 71 21.2798 1.62956 2.8345 1.75908 0 0 0 0 4.16796 5.98914 3.4865 0.000268625 0.000268625 0.000268625
73 72 21.6185 0.82159 1.62683 0.94171 0 0 0 0 4.70051 5.39397 3.87655 0.000263676 0.000263676 0.000263676
74 73 21.8885 0.84998 2.02611 1.30797 0 0 0 0 4.70051 5.39397 3.87655 0.00025848 0.00025848 0.00025848
75 74 22.1454 0.85087 1.42472 1.15593 0 0 0 0 4.70051 5.39397 3.87655 0.000253036 0.000253036 0.000253036
76 75 22.4095 1.1786 1.83474 1.21092 0 0 0 0 4.86689 6.24371 3.95955 0.000247345 0.000247345 0.000247345
77 76 22.6694 0.78564 1.66187 0.97539 0 0 0 0 4.86689 6.24371 3.95955 0.000241406 0.000241406 0.000241406
78 77 22.9286 0.79013 1.96926 1.26206 0 0 0 0 4.86689 6.24371 3.95955 0.00023522 0.00023522 0.00023522
79 78 23.1943 0.8152 1.59465 1.07906 0 0 0 0 4.81344 5.97521 4.01022 0.000228786 0.000228786 0.000228786
80 79 23.4546 0.61829 1.29337 0.98868 0 0 0 0 4.81344 5.97521 4.01022 0.000222105 0.000222105 0.000222105
81 80 23.7685 0.95007 1.79471 1.1416 0 0 0 0 4.81344 5.97521 4.01022 0.000215176 0.000215176 0.000215176
82 81 24.1034 0.93272 2.22583 1.20421 0.00617 0.5 0.00905 0.0009 4.60774 5.39816 3.81369 0.000208 0.000208 0.000208
83 82 24.3629 0.63241 1.21512 1.08097 0.00617 0.5 0.00905 0.0009 4.60774 5.39816 3.81369 0.000200576 0.000200576 0.000200576
84 83 24.6222 1.39649 2.39204 1.52958 0.00617 0.5 0.00905 0.0009 4.60774 5.39816 3.81369 0.000192905 0.000192905 0.000192905
85 84 24.9101 0.63485 1.24139 0.96726 0.00641 0.5 0.01913 0.00459 4.14874 5.15654 3.60735 0.000184986 0.000184986 0.000184986
86 85 25.1903 0.88995 1.76109 1.04753 0.00641 0.5 0.01913 0.00459 4.14874 5.15654 3.60735 0.00017682 0.00017682 0.00017682
87 86 25.4597 1.16455 2.35159 1.15176 0.00641 0.5 0.01913 0.00459 4.14874 5.15654 3.60735 0.000168406 0.000168406 0.000168406
88 87 25.761 0.86574 1.60094 1.1271 0.00641 0.5 0.01913 0.00459 4.14874 5.15654 3.60735 0.000159745 0.000159745 0.000159745
89 88 26.1232 0.57931 1.17361 0.95885 0.00704 0.5 0.01658 0.00332 3.66565 5.88071 3.25055 0.000150836 0.000150836 0.000150836
90 89 26.4022 0.88857 1.97356 1.07497 0.00704 0.5 0.01658 0.00332 3.66565 5.88071 3.25055 0.00014168 0.00014168 0.00014168
91 90 26.7071 0.71015 1.22162 1.07789 0.00704 0.5 0.01658 0.00332 3.66565 5.88071 3.25055 0.000132276 0.000132276 0.000132276
92 91 27.0615 0.80611 2.15097 0.95926 0.00704 0.5 0.01658 0.00332 3.66565 5.88071 3.25055 0.000122625 0.000122625 0.000122625
93 92 27.3798 0.75395 1.9817 1.18844 0.00758 0.5 0.01463 0.00368 3.64756 5.57493 3.04703 0.000112726 0.000112726 0.000112726
94 93 27.6734 0.52999 2.16673 0.94249 0.00758 0.5 0.01463 0.00368 3.64756 5.57493 3.04703 0.00010258 0.00010258 0.00010258
95 94 27.9692 0.29519 1.34975 0.94508 0.00758 0.5 0.01463 0.00368 3.64756 5.57493 3.04703 9.21862e-05 9.21862e-05 9.21862e-05
96 95 28.2525 0.533 1.80971 0.96369 0.00758 0.5 0.01463 0.00368 3.64756 5.57493 3.04703 8.1545e-05 8.1545e-05 8.1545e-05
97 96 28.5584 0.37619 1.67301 0.82287 0.00714 0.5 0.01309 0.00361 3.45585 5.23022 2.909 7.06563e-05 7.06563e-05 7.06563e-05
98 97 28.8522 0.58993 1.73032 0.93823 0.00714 0.5 0.01309 0.00361 3.45585 5.23022 2.909 5.952e-05 5.952e-05 5.952e-05
99 98 29.2014 1.19689 2.95317 1.27242 0.00714 0.5 0.01309 0.00361 3.45585 5.23022 2.909 4.81363e-05 4.81363e-05 4.81363e-05
100 99 29.5194 0.44641 1.50801 0.93925 0.00714 0.5 0.01309 0.00361 3.45585 5.23022 2.909 3.6505e-05 3.6505e-05 3.6505e-05
101 100 29.8906 0.52149 1.81476 0.89577 0.0061 0.5 0.01157 0.00231 3.45621 5.51821 2.93443 2.46263e-05 2.46263e-05 2.46263e-05

BIN
ai/runs/train/results.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Binary file not shown.

269
ai/trainer.py Normal file
View File

@@ -0,0 +1,269 @@
# AI 학습 — YOLOv8 재학습 및 모델 저장
import multiprocessing
import os
import random
import shutil
from utils.path_helper import get_path
import yaml
from PyQt5.QtCore import QThread, pyqtSignal
class Trainer:
def __init__(self):
self.model = None
self.is_training = False
# ------------------------------------------------------------------ #
def prepare_dataset(self, image_folder: str) -> str:
dataset_dir = get_path("ai", "dataset")
if os.path.exists(dataset_dir):
shutil.rmtree(dataset_dir)
for split in ("train", "val"):
os.makedirs(os.path.join(dataset_dir, "images", split), exist_ok=True)
os.makedirs(os.path.join(dataset_dir, "labels", split), exist_ok=True)
pairs = []
for f in os.listdir(image_folder):
if f.lower().endswith((".jpg", ".jpeg", ".png", ".bmp")):
img_path = os.path.join(image_folder, f)
txt_path = os.path.join(
image_folder, os.path.splitext(f)[0] + ".txt"
)
if os.path.exists(txt_path):
pairs.append((img_path, txt_path))
random.shuffle(pairs)
split_idx = int(len(pairs) * 0.8)
train_pairs = pairs[:split_idx]
val_pairs = pairs[split_idx:]
for img, lbl in train_pairs:
shutil.copy(img, os.path.join(dataset_dir, "images", "train"))
shutil.copy(lbl, os.path.join(dataset_dir, "labels", "train"))
for img, lbl in val_pairs:
shutil.copy(img, os.path.join(dataset_dir, "images", "val"))
shutil.copy(lbl, os.path.join(dataset_dir, "labels", "val"))
yaml_content = {
"path": dataset_dir,
"train": "images/train",
"val": "images/val",
"nc": 4,
"names": ["스크래치", "이물", "흑점", "변형"],
}
yaml_path = os.path.join(dataset_dir, "data.yaml")
with open(yaml_path, "w", encoding="utf-8") as fh:
yaml.dump(yaml_content, fh, allow_unicode=True)
return yaml_path
# ------------------------------------------------------------------ #
def train(
self,
image_folder: str,
epochs: int,
batch: int,
save_path: str,
log_callback=None,
progress_callback=None,
):
self.is_training = True
try:
if log_callback:
log_callback("데이터셋 준비 중...")
yaml_path = self.prepare_dataset(image_folder)
if log_callback:
log_callback(f"데이터셋 준비 완료: {yaml_path}")
if log_callback:
log_callback("YOLOv8 모델 로드 중...")
from ultralytics import YOLO # 지연 로딩 — 앱 시작 시 torch DLL 오류 방지
self.model = YOLO("yolov8n.pt")
if log_callback:
log_callback(f"학습 시작 (epoch={epochs}, batch={batch})")
def _on_epoch_end(trainer):
ep = trainer.epoch + 1
try:
loss_val = float(trainer.loss)
loss_str = f"{loss_val:.4f}"
except Exception:
loss_str = "?"
if log_callback:
log_callback(f"Epoch {ep}/{epochs} loss={loss_str}")
if progress_callback:
progress_callback(int(ep / epochs * 100))
self.model.add_callback("on_train_epoch_end", _on_epoch_end)
self.model.train(
data=yaml_path,
epochs=epochs,
batch=batch,
imgsz=640,
project=get_path("ai", "runs"),
name="train",
exist_ok=True,
verbose=True,
workers=0, # disable DataLoader multiprocessing inside subprocess
amp=False, # AMP check also spawns a subprocess on Windows
plots=False, # matplotlib can interfere with Qt event loop
)
# best.pt 복사
best_pt = get_path("ai", "runs", "train", "weights", "best.pt")
if os.path.exists(best_pt):
os.makedirs(os.path.dirname(save_path), exist_ok=True)
shutil.copy(best_pt, save_path)
if log_callback:
log_callback(f"모델 저장 완료: {save_path}")
if progress_callback:
progress_callback(100)
if log_callback:
log_callback("학습 완료!")
except BaseException as e:
import traceback
if log_callback:
try:
log_callback(f"학습 오류: {e}")
log_callback(traceback.format_exc())
except Exception:
pass
finally:
self.is_training = False
# ------------------------------------------------------------------ #
def stop(self):
self.is_training = False
# ====================================================================== #
# Subprocess entry point — defined at module level so it is picklable.
# ultralytics training can call sys.exit() internally; running it in a
# separate process completely isolates the Qt application from that.
# ====================================================================== #
def _train_subprocess_main(queue, image_folder, epochs, batch, save_path):
"""Entry point for the isolated training subprocess."""
try:
trainer = Trainer()
def _log(msg):
try:
queue.put(("log", msg))
except Exception:
pass
def _progress(pct):
try:
queue.put(("progress", int(pct)))
except Exception:
pass
trainer.train(
image_folder=image_folder,
epochs=epochs,
batch=batch,
save_path=save_path,
log_callback=_log,
progress_callback=_progress,
)
queue.put(("done", True))
except BaseException as e:
import traceback
try:
queue.put(("log", f"학습 오류: {e}"))
queue.put(("log", traceback.format_exc()))
except Exception:
pass
try:
queue.put(("done", False))
except Exception:
pass
# ====================================================================== #
class TrainWorker(QThread):
log_signal = pyqtSignal(str)
progress_signal = pyqtSignal(int)
finished_signal = pyqtSignal(bool)
def __init__(self, trainer, image_folder, epochs, batch, save_path):
super().__init__()
self.trainer = trainer
self.image_folder = image_folder
self.epochs = epochs
self.batch = batch
self.save_path = save_path
self._proc = None # training subprocess handle
def run(self):
# Spawn an isolated subprocess so that any sys.exit() call inside
# ultralytics does not reach PyQt5's QThread handler and trigger
# QApplication.exit() in the main process.
ctx = multiprocessing.get_context("spawn")
q = ctx.Queue()
self._proc = ctx.Process(
target=_train_subprocess_main,
args=(q, self.image_folder, self.epochs, self.batch, self.save_path),
daemon=True,
)
self._proc.start()
success = False
while True:
proc_alive = self._proc.is_alive()
try:
msg_type, msg_data = q.get(timeout=0.3)
except Exception:
# queue.Empty — check if subprocess died unexpectedly
if not proc_alive:
# Give one last chance to read remaining messages
while True:
try:
msg_type, msg_data = q.get_nowait()
except Exception:
break
if msg_type == "log":
self.log_signal.emit(str(msg_data))
elif msg_type == "progress":
self.progress_signal.emit(int(msg_data))
elif msg_type == "done":
success = bool(msg_data)
break
continue
if msg_type == "log":
self.log_signal.emit(str(msg_data))
elif msg_type == "progress":
self.progress_signal.emit(int(msg_data))
elif msg_type == "done":
success = bool(msg_data)
break
self._proc.join(timeout=30)
if self._proc.is_alive():
self._proc.terminate()
self._proc.join(timeout=5)
self.finished_signal.emit(success)
def stop_subprocess(self):
"""Call from the main thread to forcefully stop training."""
if self._proc and self._proc.is_alive():
self._proc.terminate()