Desenvolvedores independentes frequentemente enfrentam o desafio de testar modelos de aprendizado profundo, como o ResNet18, em computadores sem GPUs dedicadas. No entanto, serviços de computação em nuvem oferecem uma alternativa acessível, permitindo executar modelos de forma eficiente com custos controlados.
Vantagens do Uso de GPU em Nuvem
Dispositivos locais, como notebooks com gráficos integrados, limitam o desempenho em tarefas de visão computacional. O ResNet18, apesar de leve, consome tempo excessivo em CPUs, tornando-o impraticável para testes rápidos. Serviços de nuvem resolvem isso com:
- Pagamento por uso, minimizando custos iniciais.
- Hardware especializado (GPUs como T4 ou A10) para aceleração significativa.
- Ambientes pré-configurados com bibliotecas essenciais.
Configuração Rápida para Iniciantes
Para começar, selecione uma plataforma de nuvem que ofereça instâncias GPU. Escolha uma imagem base com PyTorch e CUDA instalados, como "PyTorch 1.12 + CUDA 113". Após implantar a instância, acesse um notebook Jupyter para desenvolvimento.
Carregamento e Avaliação do Modelo ResNet18
Primeiro, importe as bibliotecas necessárias e carregue o modelo pré-treinado. Ajuste o código para detecção automática de GPU e defina o modo de avaliação:
import torch
import torchvision.models as redes_neurais
# Inicializar modelo ResNet18 com pesos pré-treinados
modelo_carregado = redes_neurais.resnet18(pretrained=True)
modelo_carregado.eval()
# Verificar disponibilidade de GPU e mover modelo
dispositivo = torch.device("cuda" if torch.cuda.is_available() else "cpu")
modelo_carregado = modelo_carregado.to(dispositivo)
print("Modelo carregado em:", dispositivo)
Preprocessamanto de Imagens para Inferência
O ResNet18 requer imagens com dimensões específicas. Implemente uma sequência de transformações para ajustar e normalizar os dados de entrada:
from PIL import Image
from torchvision import transforms
# Definir pipeline de transformação
transformacoes = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])
# Processar imagem de teste
caminho_imagem = "amostra.jpg"
imagem = Image.open(caminho_imagem)
tensor_imagem = transformacoes(imagem).unsqueeze(0).to(dispositivo)
Realização de Previsões
Execute o modelo para classificar a imagem e mapeie os resultados para categorisa do ImageNet:
# Gerar previsões
with torch.no_grad():
saidas = modelo_carregado(tensor_imagem)
# Determinar classe prevista
_, classe_predita = torch.max(saidas, 1)
# Carregar rótulos do ImageNet
import json
with open("indices_classes_imagenet.json") as arquivo:
categorias = json.load(arquivo)
# Exibir resultado
print("Classe prevista:", categorias[str(classe_predita.item())][1])
Na primeira execução, o download dos pesos do modelo e dos rótulos será automático, exigindo conexão com a internet.
Adaptação para Conjuntos de Dados Personalizados
Para classificar dados próprios, utilize aprendizado por transferência. Estruture o diretório de dados em subpastas para treino e validação:
meu_conjunto/
├── treino/
│ ├── classe_a/
│ └── classe_b/
└── validacao/
├── classe_a/
└── classe_b/
Modifique a última camada do modelo para corresponder ao número de classes desejado e treine com dados customizados:
import torch.optim as otimizador
from torchvision import datasets, transforms
# Configurar carregamento de dados
transformacoes_treino = transforms.Compose([
transforms.RandomResizedCrop(224),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])
conjunto_dados = datasets.ImageFolder('meu_conjunto/treino', transformacoes_treino)
carregador_dados = torch.utils.data.DataLoader(conjunto_dados, batch_size=32, shuffle=True)
# Ajustar a arquitetura do modelo
modelo_customizado = redes_neurais.resnet18(pretrained=True)
num_classes = len(conjunto_dados.classes)
modelo_customizado.fc = torch.nn.Linear(modelo_customizado.fc.in_features, num_classes)
modelo_customizado = modelo_customizado.to(dispositivo)
# Definir função de perda e otimizador
funcao_perda = torch.nn.CrossEntropyLoss()
otimizador_sgd = otimizador.SGD(modelo_customizado.parameters(), lr=0.001, momentum=0.9)
# Loop de treinamento simplificado
for epoca in range(5):
for entradas, rotulos in carregador_dados:
entradas, rotulos = entradas.to(dispositivo), rotulos.to(dispositivo)
otimizador_sgd.zero_grad()
saidas_treino = modelo_customizado(entradas)
perda = funcao_perda(saidas_treino, rotulos)
perda.backward()
otimizador_sgd.step()
print(f"Época {epoca+1}, Perda: {perda.item():.4f}")
Dicas para Solução de Problemas e Otimização
Se as previsões forem imprecisas, verifique a consistência no preprocessamento das imagens e certifique-se de que o modelo está no dispositivo correto. Para melhorar a acurácia em dados personalizados, aumente o volume de dados, aplique técnicas de aumento, ajuste a taxa de aprendizado e prolongue o treinamento. Em termos de custo, utilize instâncias sob demenda e libere recursos após o uso para evitar cobranças desnecessárias.