0
respostas

[Projeto] Exemplo de função que constrói a rede Ajuste conforme o notebook da aula

============================================================

COMPARAÇÃO DE BATCH SIZE NO TREINAMENTO

============================================================

import time
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader

------------------------------------------------------------

Exemplo de hiperparâmetros-base

------------------------------------------------------------

base_args = {
'num_workers': 4,
'num_classes': 10,
'lr': 1e-4,
'weight_decay': 5e-4,
'num_epochs': 30,
'device': 'cuda' if torch.cuda.is_available() else 'cpu'
}

------------------------------------------------------------

Função de treino por 1 época

------------------------------------------------------------

def train_one_epoch(loader, net, criterion, optimizer, device):
net.train()
losses = []

for dado, rotulo in loader:
    dado = dado.to(device)
    rotulo = rotulo.to(device)

    pred = net(dado)
    loss = criterion(pred, rotulo)

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    losses.append(loss.item())

return np.mean(losses), np.std(losses)

------------------------------------------------------------

Função principal para testar um batch_size

------------------------------------------------------------

def run_experiment(batch_size, train_dataset, build_model):
args = base_args.copy()
args['batch_size'] = batch_size

# DataLoader
train_loader = DataLoader(
    train_dataset,
    batch_size=args['batch_size'],
    shuffle=True,
    num_workers=args['num_workers']
)

# Modelo novo para cada experimento
net = build_model().to(args['device'])

# Loss e otimizador
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(
    net.parameters(),
    lr=args['lr'],
    weight_decay=args['weight_decay']
)

epoch_times = []
epoch_below_16 = None
history = []

print(f"\n===== Testando batch_size = {batch_size} =====")

for epoch in range(1, args['num_epochs'] + 1):
    start = time.time()

    mean_loss, std_loss = train_one_epoch(
        train_loader, net, criterion, optimizer, args['device']
    )

    elapsed = time.time() - start
    epoch_times.append(elapsed)
    history.append(mean_loss)

    print(
        f"Época {epoch:02d} | "
        f"Loss: {mean_loss:.4f} +- {std_loss:.4f} | "
        f"Tempo: {elapsed:.2f}s"
    )

    # Registra a primeira época em que loss < 1.6
    if epoch_below_16 is None and mean_loss < 1.6:
        epoch_below_16 = epoch

avg_epoch_time = np.mean(epoch_times)

return {
    'batch_size': batch_size,
    'avg_epoch_time': avg_epoch_time,
    'epoch_below_16': epoch_below_16,
    'loss_history': history
}

------------------------------------------------------------

Exemplo de função que constrói a rede

Ajuste conforme o notebook da aula

------------------------------------------------------------

def build_model():
return nn.Sequential(
nn.Flatten(),
nn.Linear(28 * 28, 128),
nn.ReLU(),
nn.Linear(128, 10)
)

------------------------------------------------------------

EXECUÇÃO DOS EXPERIMENTOS

train_dataset deve já existir no notebook

------------------------------------------------------------

results = []

for bs in [100, 20, 5]:
result = run_experiment(bs, train_dataset, build_model)
results.append(result)

------------------------------------------------------------

RELATÓRIO FINAL

------------------------------------------------------------

print("\n========== RESUMO FINAL ==========")
for r in results:
print(f"\nBatch size: {r['batch_size']}")
print(f"Tempo médio por época: {r['avg_epoch_time']:.2f} segundos")

if r['epoch_below_16'] is not None:
    print(f"Loss < 1.6 na época: {r['epoch_below_16']}")
else:
    print("Não atingiu loss < 1.6 em 30 épocas")