Visão Computacional na Prática: Treinamento Customizado e Identificação de Objetos com YOLOv8

No cenário de tecnologia atual, a Visão Computacional deixou de ser um conceito teórico para se tornar uma ferramenta essencial de eficiência operacional. Na Netexperts, trabalhamos constantemente para transformar desafios logísticos em soluções automatizadas. Recentemente, desenvolvemos um projeto focado na identificação e separação de itens em “caixas de ferramentas especializadas” (termo substituído por questões de privacidade), visando otimizar a organização de materiais de alto valor.

Neste artigo, detalharei a primeira fase desse projeto: a criação de um modelo de detecção de objetos capaz de diferenciar componentes específicos com alta precisão.

O Desafio e a Coleta de Dados

O objetivo inicial era identificar equipamentos através de imagens, distinguindo, por exemplo, entre diferentes tipos de ferramentas manuais. Para que uma IA aprenda, ela precisa de exemplos claros e variados.

  • Amostragem: Coletamos aproximadamente 120 fotos de cada objeto.
  • Variabilidade: As fotos incluíram diferentes ângulos, posições, combinações de ferramentas e condições de iluminação para garantir que o modelo não fosse “enganado” por sombras ou reflexos.

Anotação: Utilizamos o Roboflow para realizar o labeling (etiquetagem). Criamos classes para cada item e desenhamos as bounding boxes (caixas delimitadoras) em cada foto, gerando o dataset necessário para o treino.

Estrutura do Dataset e Treinamento

Para treinar o modelo YOLOv8 (You Only Look Once), organizamos os dados seguindo o padrão da arquitetura, dividindo o conjunto total de imagens (Split) em três partes fundamentais:

  1. Train (70%): Imagens usadas para o ajuste dos pesos da rede neural. É aqui que a IA “aprende” os padrões.
  2. Val (20%): Dados de validação usados durante o treino para ajustar hiperparâmetros e evitar o overfitting (quando a IA apenas decora as fotos em vez de aprender).
  3. Test (10%): Dados que o modelo nunca viu, usados apenas ao final para medir a performance real em um cenário “cego”.

Infraestrutura: GPU on Demand com RunPod

O treinamento de modelos de visão computacional exige alto poder de processamento gráfico. Para este projeto, utilizamos o RunPod, uma plataforma que permite o aluguel de GPU Pods.

  • Vantagem: Em vez de investir em hardware caro, alugamos instâncias de GPUs potentes e pagamos apenas pelo tempo de uso (per-second billing).

Agilidade: Após o término do treino, o “pod” é encerrado, otimizando custos de infraestrutura.

Tutorial Técnico: Executando o Treino

Abaixo, apresentamos a configuração utilizada para gerar o modelo.

1. Estrutura de Pastas

O YOLO exige que os arquivos estejam organizados desta forma:

Plaintext

dataset/

├── images/

│   ├── train/

│   ├── val/

│   └── test/

├── labels/

│   ├── train/

│   ├── val/

│   └── test/

└── data.yaml

2. Configuração do Arquivo data.yaml

Este arquivo indica ao script onde estão os dados e quais são as classes:

YAML

path: dataset

train: images/train

val: images/val

nc: 2

names: [‘item_A’, ‘item_B’]

3. Comando de Treinamento

No terminal do RunPod, executamos o comando de fine-tuning:

Bash

yolo train model=yolov8n.pt data=data.yaml epochs=100 imgsz=640


  • Epochs (100): O número de vezes que a IA passará por todo o dataset para aprender os padrões.
  • Imgsz (640): Redimensiona as imagens para 640×640 pixels para padronizar a entrada.

Batch: Quantidade de imagens processadas simultaneamente antes de atualizar os pesos (ajustado conforme a memória da GPU).

Avaliação de Métricas e Resultados

Após o treino, analisamos as métricas de performance para validar a eficácia do modelo:

  • mAP (Mean Average Precision): A média da precisão em todas as classes. É o principal indicador de sucesso.
  • Precision: Mede a acurácia das predições positivas (evita falsos positivos).
  • Recall: Mede a capacidade de encontrar todos os objetos reais (evita falsos negativos).

Análise de Erros: Verificamos manualmente casos de Falso Positivo (identificar algo onde não existe), Falso Negativo (não ver o objeto) e Bounding Boxes ruins (caixas mal posicionadas).

Do Treino para a Produção: Implementação da API

Uma dúvida comum é: “Se usei uma GPU potente para treinar, preciso de uma GPU cara para rodar o sistema?”. A resposta é não.

Como o treinamento (processo pesado de ajuste de bilhões de parâmetros) já foi concluído em outra máquina (RunPod) e resultou em um arquivo consolidado (.pt), a fase de inferência (apenas usar o conhecimento pronto) é muito mais leve. O modelo exportado é otimizado e “congelado”, permitindo que ele rode até mesmo em CPU com alta performance e baixa latência, já que ele está local e não depende de processamento de nuvem externo para decidir o que está vendo.

Abaixo, o exemplo de uma API em Flask para realizar essas identificações (Isso se trata apenas de um exemplo, portanto não utilize em produção):

Python

from flask import Flask, request, jsonify

from ultralytics import YOLO

from werkzeug.utils import secure_filename

import os

app = Flask(__name__)

# Carregando o modelo local gerado pelo treinamento

model = YOLO(“best_v2.pt”)

# Definido como CPU, pois o peso computacional da inferência é baixo

device = “cpu”

def proccess_image(file_path):

    results = model.predict(source=file_path, conf=0.25)

    response = []

    for result in results:

        boxes = result.boxes

        names = model.names

        for box in boxes:

            class_id = int(box.cls[0])

            confidence = float(box.conf[0])

            class_name = names[class_id]

            response.append({“name”: class_name, “confidence”: confidence})

    return response

@app.route(“/check”, methods=[“GET”])

def check():

    return jsonify({“message”: “Hello World”})

@app.route(“/predict”, methods=[“POST”])

def predict():

    if “image” not in request.files:

        return jsonify({“error”: “No image provided”}), 400

    file = request.files[“image”]

    filename = secure_filename(file.filename)

    path = f”assets/{filename}”

    file.save(path)

    response = proccess_image(path)

    file.close()

    if os.path.exists(path):

        os.remove(path)

    return jsonify(response)

if __name__ == “__main__”:

    print(“✅ Servidor YOLO iniciado com sucesso na porta 8546…”)

    app.run(host=”0.0.0.0″, port=8546)

Conclusão

Entender a separação entre o treinamento (onde o aluguel de GPUs como o RunPod é vital) e a inferência (onde modelos locais .pt podem rodar em infraestruturas mais simples como CPUs) é fundamental para viabilizar projetos de IA economicamente. Na NetExperts, aplicamos essa lógica para entregar soluções rápidas, resilientes e escaláveis.

Desejamos a todos, um feliz ano novo!

Referências e Documentações Oficiais: