Por que utilizar GPU na nuvem para testar o ResNet18?
Ao desenvolver sistemas inteligentes como portarias, muitos enfrentam limitações de desempenho em placas como Raspberry Pi, onde o ResNet18 pode operar a apenas 2-3 FPS, tornando a detecção inviável. GPUs na nuvem oferecem uma alternativa acessível, permitindo taxas de quadros acima de 20 FPS sem configuração complexa, com cobrança por uso e desligamento imediato.
Dica: Modelos como ResNet18 exigem poder computacional sginificativo; testar na nuvem antes de invetsir em hardware dedicado como Jetson reduz riscos financeiros.
Implantação rápida do ambiente em 5 minutos
Seleção de imagem pré-configurada
Utilize plataformas de computação em nuvem que ofereçam imagens com PyTorch 1.8+, torchvision, OpenCV e pesos do ResNet18 pré-carregados.
Inicialização da instância GPU
Escolha uma especificação básica de GPU (ex.: T4) e acesse via terminal web após a ativação.
Verificação do ambiente
Execute os seguintes comandos para confirmar a disponibilidade:
python -c "import torch; print(torch.cuda.is_available())"
python -c "import cv2; print(cv2.__version__)"
Desenvolvimento do script de detecção em tempo real
Crie um arquivo detecao.py com o código abaixo:
import cv2
import torch
import torchvision.transforms as transf
from torchvision.models import resnet18
# Configuração do modelo
rede = resnet18(pretrained=True).eval().cuda()
rotulos = open('rotulos_imagenet.txt').read().splitlines() # Baixe conforme instrução
# Processamento do fluxo de vídeo
camera = cv2.VideoCapture(0)
transformacao = transf.Compose([
transf.ToPILImage(),
transf.Resize(256),
transf.CenterCrop(224),
transf.ToTensor(),
transf.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])
while True:
sucesso, quadro = camera.read()
if not sucesso:
break
# Pré-processamento e inferência
tensor_entrada = transformacao(quadro).unsqueeze(0).cuda()
with torch.no_grad():
saida = rede(tensor_entrada)
# Resultado
_, predicao = torch.max(saida, 1)
classe = rotulos[predicao.item()]
cv2.putText(quadro, f"Classe: {classe}", (10,30),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0,255,0), 2)
cv2.imshow('ResNet18 Detecao', quadro)
if cv2.waitKey(1) == 27: # Tecla ESC para sair
break
camera.release()
cv2.destroyAllWindows()
Baixe o arquivo de rótulos do ImageNet:
wget https://raw.githubusercontent.com/anishathalye/imagenet-simple-labels/master/imagenet-simple-labels.txt -O rotulos_imagenet.txt
Técnicas de otimização de parâmetros
Ajuste de resolução
Modifique transf.Resize(256) para valores entre 224-320: valores menores aumentam a velocidade mas reduzem precisão.
Melhoria de taxa de quadros
Adicione cálculo de FPS no laço principle:
import time
tempo_anterior = time.time()
while True:
# ...código existente...
tempo_atual = time.time()
fps = 1/(tempo_atual - tempo_anterior)
tempo_anterior = tempo_atual
cv2.putText(quadro, f"FPS: {fps:.1f}", (10,70),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0,255,0), 2)
Processamento com múltiplas threads
Separe captura e inferência usando threading:
from threading import Thread
import queue
fila_quadros = queue.Queue(maxsize=1)
fila_resultados = queue.Queue(maxsize=1)
def captura_thread():
while True:
sucesso, quadro = camera.read()
if fila_quadros.empty():
fila_quadros.put(quadro)
def inferencia_thread():
while True:
quadro = fila_quadros.get()
# ...código de inferência...
fila_resultados.put((quadro, classe))
Thread(target=captura_thread, daemon=True).start()
Thread(target=inferencia_thread, daemon=True).start()
while True:
quadro, classe = fila_resultados.get()
# ...código de exibição...
Problemas comuns e soluções
Inacesso à câmera
Servidores na nuvem não possuem câmeras físicas. Alternativas: usar câmeras IP (como smartphones) ou carregar arquivos de vídeo modificando camera = cv2.VideoCapture('teste.mp4').
Precisão insatisfatória
O ResNet18 é treinado para classificação ImageNet. Para melhorar: realize fine-tuning com seu dataset ou utilize modelos como SSD/YOLO para detecção.
Memória GPU limitada
Em GPUs com menos de 4GB, adicione torch.cuda.empty_cache() após inferências ou reduza o tamanho do batch (já é 1 neste caso).