Lab09 - YOLO - Treinamento customizado
Treinamento de modelo customizado¶
Para treinar o modelo YOLOv8 basta usar apenas o comando train. Os parâmetros necessários para essa função são:
- configuração de um arquivo yaml com as informações de caminho das imagens e classes
- épocas
- tamanho da imagem
- nome do seu modelo
Neste exemplo vamos treinar um modelo capaz de detectar buracos em ruas e estradas.
Utilizaremos o dataset Potholes Detection for YOLOV4 que foi organizado no repositório abaixo.
Os datasets padrão YOLO são compatíveis com todas as versões, mesmo este dataset originalmente ter sido utilizado para a versão V4.-
Referencia: github/michelpf/fiap-ml-visao-computacional
In [ ]:
Copied!
from ultralytics import YOLO
import ultralytics
model = YOLO('yolov11n.pt')
from ultralytics import YOLO
import ultralytics
model = YOLO('yolov11n.pt')
Clonagem e Preparação do Dataset¶
O dataset utilizado contém imagens de buracos anotadas no formato YOLO, originalmente desenvolvido para YOLOv4 mas compatível com todas as versões YOLO.
Estrutura esperada:
dataset-pothole/
├── dataset/
│ ├── train/
│ │ ├── images/
│ │ └── labels/
│ └── test/
│ ├── images/
│ └── labels/
In [ ]:
Copied!
# certifique se que o repositório do dataset está clonado
# e que o diretório 'dataset-pothole' está presente
# !git clone https://github.com/michelpf/dataset-pothole
# certifique se que o repositório do dataset está clonado
# e que o diretório 'dataset-pothole' está presente
# !git clone https://github.com/michelpf/dataset-pothole
Criação do Arquivo de Configuração¶
In [ ]:
Copied!
!touch model/configs_modelo.yaml
!touch model/configs_modelo.yaml
In [12]:
Copied!
%%writefile configs_modelo.yaml
path: 'dataset-pothole/dataset'
train: 'train/'
val: 'test/'
nc: 1
names: ["pothole"]
%%writefile configs_modelo.yaml
path: 'dataset-pothole/dataset'
train: 'train/'
val: 'test/'
nc: 1
names: ["pothole"]
Overwriting configs_modelo.yaml
In [13]:
Copied!
arquivo_config = "configs_modelo.yaml"
arquivo_config = "configs_modelo.yaml"
O treinamento do modelo também realiza em conjunto a validação com os dados separados do treinamento.
In [15]:
Copied!
# Configurações de treinamento
EPOCHS = 50 # Aumentado para melhor convergência
IMG_SIZE = 640 # Tamanho padrão do YOLOv8
BATCH_SIZE = 16
LEARNING_RATE = 0.01
# Hiperparâmetros específicos
hyperparameters = {
'epochs': EPOCHS,
'imgsz': IMG_SIZE,
'batch': BATCH_SIZE,
'lr0': LEARNING_RATE,
'workers': 8,
'patience': 10, # Early stopping
'save_period': 10, # Salvar checkpoint a cada 10 épocas
'cache': True, # Cache das imagens
'mosaic': 1.0, # Data augmentation
'mixup': 0.1,
'copy_paste': 0.1
}
resultados = model.train(
data=arquivo_config,
name='yolov8_pothole_custom',
**hyperparameters
)
# treinamento simples
# resultados = model.train(data=arquivo_config, epochs=3, imgsz=720, name='yolov8_pothole')
# Configurações de treinamento
EPOCHS = 50 # Aumentado para melhor convergência
IMG_SIZE = 640 # Tamanho padrão do YOLOv8
BATCH_SIZE = 16
LEARNING_RATE = 0.01
# Hiperparâmetros específicos
hyperparameters = {
'epochs': EPOCHS,
'imgsz': IMG_SIZE,
'batch': BATCH_SIZE,
'lr0': LEARNING_RATE,
'workers': 8,
'patience': 10, # Early stopping
'save_period': 10, # Salvar checkpoint a cada 10 épocas
'cache': True, # Cache das imagens
'mosaic': 1.0, # Data augmentation
'mixup': 0.1,
'copy_paste': 0.1
}
resultados = model.train(
data=arquivo_config,
name='yolov8_pothole_custom',
**hyperparameters
)
# treinamento simples
# resultados = model.train(data=arquivo_config, epochs=3, imgsz=720, name='yolov8_pothole')
New https://pypi.org/project/ultralytics/8.3.153 available 😃 Update with 'pip install -U ultralytics' Ultralytics 8.3.134 🚀 Python-3.9.6 torch-2.3.0 CPU (Apple M2) engine/trainer: agnostic_nms=False, amp=True, augment=False, auto_augment=randaugment, batch=16, bgr=0.0, box=7.5, cache=False, cfg=None, classes=None, close_mosaic=10, cls=0.5, conf=None, copy_paste=0.0, copy_paste_mode=flip, cos_lr=False, cutmix=0.0, data=configs_modelo.yaml, degrees=0.0, deterministic=True, device=cpu, dfl=1.5, dnn=False, dropout=0.0, dynamic=False, embed=None, epochs=3, erasing=0.4, exist_ok=False, fliplr=0.5, flipud=0.0, format=torchscript, fraction=1.0, freeze=None, half=False, hsv_h=0.015, hsv_s=0.7, hsv_v=0.4, imgsz=720, int8=False, iou=0.7, keras=False, kobj=1.0, line_width=None, lr0=0.01, lrf=0.01, mask_ratio=4, max_det=300, mixup=0.0, mode=train, model=yolov8n.pt, momentum=0.937, mosaic=1.0, multi_scale=False, name=yolov8_pothole2, nbs=64, nms=False, opset=None, optimize=False, optimizer=auto, overlap_mask=True, patience=100, perspective=0.0, plots=True, pose=12.0, pretrained=True, profile=False, project=None, rect=False, resume=False, retina_masks=False, save=True, save_conf=False, save_crop=False, save_dir=runs/detect/yolov8_pothole2, save_frames=False, save_json=False, save_period=-1, save_txt=False, scale=0.5, seed=0, shear=0.0, show=False, show_boxes=True, show_conf=True, show_labels=True, simplify=True, single_cls=False, source=None, split=val, stream_buffer=False, task=detect, time=None, tracker=botsort.yaml, translate=0.1, val=True, verbose=True, vid_stride=1, visualize=False, warmup_bias_lr=0.1, warmup_epochs=3.0, warmup_momentum=0.8, weight_decay=0.0005, workers=8, workspace=None Overriding model.yaml nc=80 with nc=1 from n params module arguments 0 -1 1 464 ultralytics.nn.modules.conv.Conv [3, 16, 3, 2] 1 -1 1 4672 ultralytics.nn.modules.conv.Conv [16, 32, 3, 2] 2 -1 1 7360 ultralytics.nn.modules.block.C2f [32, 32, 1, True] 3 -1 1 18560 ultralytics.nn.modules.conv.Conv [32, 64, 3, 2] 4 -1 2 49664 ultralytics.nn.modules.block.C2f [64, 64, 2, True] 5 -1 1 73984 ultralytics.nn.modules.conv.Conv [64, 128, 3, 2] 6 -1 2 197632 ultralytics.nn.modules.block.C2f [128, 128, 2, True] 7 -1 1 295424 ultralytics.nn.modules.conv.Conv [128, 256, 3, 2] 8 -1 1 460288 ultralytics.nn.modules.block.C2f [256, 256, 1, True] 9 -1 1 164608 ultralytics.nn.modules.block.SPPF [256, 256, 5] 10 -1 1 0 torch.nn.modules.upsampling.Upsample [None, 2, 'nearest'] 11 [-1, 6] 1 0 ultralytics.nn.modules.conv.Concat [1] 12 -1 1 148224 ultralytics.nn.modules.block.C2f [384, 128, 1] 13 -1 1 0 torch.nn.modules.upsampling.Upsample [None, 2, 'nearest'] 14 [-1, 4] 1 0 ultralytics.nn.modules.conv.Concat [1] 15 -1 1 37248 ultralytics.nn.modules.block.C2f [192, 64, 1] 16 -1 1 36992 ultralytics.nn.modules.conv.Conv [64, 64, 3, 2] 17 [-1, 12] 1 0 ultralytics.nn.modules.conv.Concat [1] 18 -1 1 123648 ultralytics.nn.modules.block.C2f [192, 128, 1] 19 -1 1 147712 ultralytics.nn.modules.conv.Conv [128, 128, 3, 2] 20 [-1, 9] 1 0 ultralytics.nn.modules.conv.Concat [1] 21 -1 1 493056 ultralytics.nn.modules.block.C2f [384, 256, 1] 22 [15, 18, 21] 1 751507 ultralytics.nn.modules.head.Detect [1, [64, 128, 256]] Model summary: 129 layers, 3,011,043 parameters, 3,011,027 gradients, 8.2 GFLOPs Transferred 319/355 items from pretrained weights Freezing layer 'model.22.dfl.conv.weight' WARNING ⚠️ imgsz=[720] must be multiple of max stride 32, updating to [736] train: Fast image access ✅ (ping: 0.0±0.0 ms, read: 110.6±43.8 MB/s, size: 31.9 KB)
train: Scanning /Users/arnaldoalvesvianajunior/shift-fiap/10-lab18-yolo/dataset-pothole/dataset/train... 1562 images, 0 backgrounds, 0 corrupt: 100%|██████████| 1562/1562 [00:00<00:00, 2661.57it/s]
train: New cache created: /Users/arnaldoalvesvianajunior/shift-fiap/10-lab18-yolo/dataset-pothole/dataset/train.cache val: Fast image access ✅ (ping: 0.0±0.0 ms, read: 121.4±22.3 MB/s, size: 31.1 KB)
val: Scanning /Users/arnaldoalvesvianajunior/shift-fiap/10-lab18-yolo/dataset-pothole/dataset/test... 421 images, 0 backgrounds, 0 corrupt: 100%|██████████| 421/421 [00:00<00:00, 2937.88it/s]
val: New cache created: /Users/arnaldoalvesvianajunior/shift-fiap/10-lab18-yolo/dataset-pothole/dataset/test.cache
Plotting labels to runs/detect/yolov8_pothole2/labels.jpg... optimizer: 'optimizer=auto' found, ignoring 'lr0=0.01' and 'momentum=0.937' and determining best 'optimizer', 'lr0' and 'momentum' automatically... optimizer: AdamW(lr=0.002, momentum=0.9) with parameter groups 57 weight(decay=0.0), 64 weight(decay=0.0005), 63 bias(decay=0.0)
2025/06/11 17:29:58 INFO mlflow.tracking.fluent: Experiment with name '/Shared/Ultralytics' does not exist. Creating a new experiment. 2025/06/11 17:29:59 INFO mlflow.tracking.fluent: Autologging successfully enabled for statsmodels. 2025/06/11 17:29:59 WARNING mlflow.utils.autologging_utils: MLflow transformers autologging is known to be compatible with 4.35.2 <= transformers <= 4.51.2, but the installed version is 4.51.3. If you encounter errors during autologging, try upgrading / downgrading transformers to a compatible version, or try upgrading MLflow. 2025/06/11 17:30:02 INFO mlflow.tracking.fluent: Autologging successfully enabled for sklearn. 2025/06/11 17:30:09 INFO mlflow.tracking.fluent: Autologging successfully enabled for keras. 2025/06/11 17:30:09 INFO mlflow.tracking.fluent: Autologging successfully enabled for tensorflow. 2025/06/11 17:30:10 INFO mlflow.tracking.fluent: Autologging successfully enabled for transformers.
MLflow: logging run_id(9f8d1c2250d941ff880ff4c5d5fa221e) to runs/mlflow MLflow: view at http://127.0.0.1:5000 with 'mlflow server --backend-store-uri runs/mlflow' MLflow: disable with 'yolo settings mlflow=False' Image sizes 736 train, 736 val Using 0 dataloader workers Logging results to runs/detect/yolov8_pothole2 Starting training for 3 epochs... Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size
1/3 0G 2.269 3.503 2.163 52 736: 5%|▌ | 5/98 [01:48<33:38, 21.70s/it]
--------------------------------------------------------------------------- KeyboardInterrupt Traceback (most recent call last) Cell In[15], line 1 ----> 1 resultados = model.train(data=arquivo_config, epochs=3, imgsz=720, name='yolov8_pothole') File ~/Library/Python/3.9/lib/python/site-packages/ultralytics/engine/model.py:793, in Model.train(self, trainer, **kwargs) 790 self.model = self.trainer.model 792 self.trainer.hub_session = self.session # attach optional HUB session --> 793 self.trainer.train() 794 # Update model and cfg after training 795 if RANK in {-1, 0}: File ~/Library/Python/3.9/lib/python/site-packages/ultralytics/engine/trainer.py:211, in BaseTrainer.train(self) 208 ddp_cleanup(self, str(file)) 210 else: --> 211 self._do_train(world_size) File ~/Library/Python/3.9/lib/python/site-packages/ultralytics/engine/trainer.py:399, in BaseTrainer._do_train(self, world_size) 394 self.tloss = ( 395 (self.tloss * i + self.loss_items) / (i + 1) if self.tloss is not None else self.loss_items 396 ) 398 # Backward --> 399 self.scaler.scale(self.loss).backward() 401 # Optimize - https://pytorch.org/docs/master/notes/amp_examples.html 402 if ni - last_opt_step >= self.accumulate: File ~/Library/Python/3.9/lib/python/site-packages/torch/_tensor.py:525, in Tensor.backward(self, gradient, retain_graph, create_graph, inputs) 515 if has_torch_function_unary(self): 516 return handle_torch_function( 517 Tensor.backward, 518 (self,), (...) 523 inputs=inputs, 524 ) --> 525 torch.autograd.backward( 526 self, gradient, retain_graph, create_graph, inputs=inputs 527 ) File ~/Library/Python/3.9/lib/python/site-packages/torch/autograd/__init__.py:267, in backward(tensors, grad_tensors, retain_graph, create_graph, grad_variables, inputs) 262 retain_graph = create_graph 264 # The reason we repeat the same comment below is that 265 # some Python versions print out the first line of a multi-line function 266 # calls in the traceback and some print out the last line --> 267 _engine_run_backward( 268 tensors, 269 grad_tensors_, 270 retain_graph, 271 create_graph, 272 inputs, 273 allow_unreachable=True, 274 accumulate_grad=True, 275 ) File ~/Library/Python/3.9/lib/python/site-packages/torch/autograd/graph.py:744, in _engine_run_backward(t_outputs, *args, **kwargs) 742 unregister_hooks = _register_logging_hooks_on_whole_graph(t_outputs) 743 try: --> 744 return Variable._execution_engine.run_backward( # Calls into the C++ engine to run the backward pass 745 t_outputs, *args, **kwargs 746 ) # Calls into the C++ engine to run the backward pass 747 finally: 748 if attach_logging_hooks: KeyboardInterrupt:
In [ ]:
Copied!
import cv2
import matplotlib.pyplot as plt
image = cv2.imread("runs/detect/yolov8_pothole/F1_curve.png", cv2.IMREAD_COLOR)
plt.imshow(image)
import cv2
import matplotlib.pyplot as plt
image = cv2.imread("runs/detect/yolov8_pothole/F1_curve.png", cv2.IMREAD_COLOR)
plt.imshow(image)
In [ ]:
Copied!
image = cv2.imread("runs/detect/yolov8_pothole/results.png", cv2.IMREAD_COLOR)
plt.figure(figsize=(10,5))
plt.imshow(image)
image = cv2.imread("runs/detect/yolov8_pothole/results.png", cv2.IMREAD_COLOR)
plt.figure(figsize=(10,5))
plt.imshow(image)
In [ ]:
Copied!
dir_resultados = "runs/detect/yolov8_pothole5/weights/best.pt"
dir_resultados = "runs/detect/yolov8_pothole5/weights/best.pt"
In [ ]:
Copied!
image = cv2.imread("imagens/buraco2.jpeg")
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image = cv2.imread("imagens/buraco2.jpeg")
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
In [ ]:
Copied!
model = YOLO(dir_resultados)
results = model.predict(source=image, conf=0.25)
model = YOLO(dir_resultados)
results = model.predict(source=image, conf=0.25)
In [ ]:
Copied!
image_result = results[0].plot()
plt.imshow(image_result)
image_result = results[0].plot()
plt.imshow(image_result)
In [ ]:
Copied!
image = cv2.imread("imagens/buraco.jpg")
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image = cv2.imread("imagens/buraco.jpg")
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
In [ ]:
Copied!
results = model.predict(source=image, conf=0.25)
results = model.predict(source=image, conf=0.25)
In [ ]:
Copied!
image_result = results[0].plot()
plt.imshow(image_result)
image_result = results[0].plot()
plt.imshow(image_result)