In [ ]:
!nvidia-smi
import torch
print("CUDA disponible:", torch.cuda.is_available())
print("Torch:", torch.__version__)

from google.colab import files
uploaded = files.upload()

!unzip -q "finetuning-retinanet (2).zip" -d /content/project
!ls -la /content/Project

%cd /content/project
!pip install -r requirements.txt
!pip install torchmetrics
!pip install --upgrade gradio gradio-client

# Entrar a la carpeta del proyecto
%cd /content/project

# Crear las carpetas del dataset si no existen
!mkdir -p /content/project/datasets/african-wildlife/

# Descomprimir data.zip en la carpeta correcta
!unzip -q /content/project/data.zip -d /content/project/datasets/african-wildlife/

# Verificar que las carpetas se crearon correctamente
!ls -la /content/project/datasets/african-wildlife/data/train
!ls -la /content/project/datasets/african-wildlife/data/valid

DATA_DIR = "/content/project/datasets/african-wildlife/data"
TRAIN_IMAGES = f"{DATA_DIR}/train/images"
TRAIN_LABELS = f"{DATA_DIR}/train/labels"
VALID_IMAGES = f"{DATA_DIR}/valid/images"
VALID_LABELS = f"{DATA_DIR}/valid/labels"

import os

# Verificar número de imágenes y labels en entrenamiento
train_imgs = os.listdir(TRAIN_IMAGES)
train_labels = os.listdir(TRAIN_LABELS)
print("Número de imágenes de entrenamiento:", len(train_imgs))
print("Número de labels de entrenamiento:", len(train_labels))
print("Primeros 5 archivos de imágenes:", train_imgs[:5])
print("Primeros 5 archivos de labels:", train_labels[:5])

# Verificar número de imágenes y labels en validación
valid_imgs = os.listdir(VALID_IMAGES)
valid_labels = os.listdir(VALID_LABELS)
print("Número de imágenes de validación:", len(valid_imgs))
print("Número de labels de validación:", len(valid_labels))
print("Primeros 5 archivos de imágenes:", valid_imgs[:5])
print("Primeros 5 archivos de labels:", valid_labels[:5])

classes = ["elephant", "lion", "zebra", "giraffe"]
train_dataset = CustomDataset(TRAIN_IMAGES, TRAIN_LABELS, height=800, classes=classes)

import os

print("Train images folder exists:", os.path.exists(TRAIN_IMAGES))
print("Train labels folder exists:", os.path.exists(TRAIN_LABELS))
print("Archivos en imágenes:", os.listdir(TRAIN_IMAGES)[:5])
print("Archivos en labels:", os.listdir(TRAIN_LABELS)[:5])

%run config.py
%run custom_utils.py
%run model.py
%run datasets.py
%run train.py

!pip install --upgrade torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu126

import torch
import torchvision

print("Torch:", torch.__version__)
print("Torchvision:", torchvision.__version__)
print("CUDA disponible:", torch.cuda.is_available())

%cd /content/project
!ls

!cat datasets.py

classes = ["elephant", "lion", "zebra", "giraffe"]

train_dataset = CustomDataset(
    dir_path="/content/project/datasets/african-wildlife/data/train",  # carpeta padre, no solo images/
    width=800,
    height=800,
    classes=classes
)

import matplotlib.pyplot as plt
import torch
import cv2

# Tomar el primer sample
image, target = train_dataset[0]
print("Imagen shape:", image.shape)
print("Boxes:", target['boxes'])
print("Labels:", target['labels'])

# Convertir tensor a numpy si es necesario
if isinstance(image, torch.Tensor):
    image = image.permute(1,2,0).numpy()

# Escalar a [0,255] si está en [0,1]
if image.max() <= 1.0:
    image = (image * 255).astype('uint8')

# Dibujar los bounding boxes
for i, box in enumerate(target['boxes']):
    x1, y1, x2, y2 = box
    label_idx = int(target['labels'][i]) - 1  # restamos 1 si tu dataset usa label_idx = class_id + 1
    label_name = classes[label_idx]
    cv2.rectangle(image, (int(x1), int(y1)), (int(x2), int(y2)), (255,0,0), 2)
    cv2.putText(image, label_name, (int(x1), int(y1)-5),
                cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0,255,0), 2)

plt.figure(figsize=(10,10))
plt.imshow(image)
plt.axis('off')
plt.show()

NUM_SAMPLES = 5  # cuántas imágenes quieres ver

for i in range(NUM_SAMPLES):
    image, target = train_dataset[i]

    # Convertir tensor a numpy
    if isinstance(image, torch.Tensor):
        image = image.permute(1,2,0).numpy()

    if image.max() <= 1.0:
        image = (image * 255).astype('uint8')

    # Dibujar los boxes
    for j, box in enumerate(target['boxes']):
        x1, y1, x2, y2 = box
        label_idx = int(target['labels'][j]) - 1
        label_name = classes[label_idx]
        cv2.rectangle(image, (int(x1), int(y1)), (int(x2), int(y2)), (255,0,0), 2)
        cv2.putText(image, label_name, (int(x1), int(y1)-5),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0,255,0), 2)

    plt.figure(figsize=(8,8))
    plt.imshow(image)
    plt.axis('off')
    plt.show()


!cat /content/project/model.py

from model import create_model
from config import NUM_CLASSES

# Crear el modelo con el número de clases de tu dataset
model = create_model(num_classes=NUM_CLASSES)

from datasets import create_train_dataset, create_valid_dataset, create_train_loader, create_valid_loader

# Crear datasets
train_dataset = create_train_dataset("/content/project/datasets/african-wildlife/data/train")
valid_dataset = create_valid_dataset("/content/project/datasets/african-wildlife/data/valid")

# Crear DataLoaders
train_loader = create_train_loader(train_dataset)
valid_loader = create_valid_loader(valid_dataset)

import torch

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)

optimizer = torch.optim.SGD(model.parameters(), lr=0.005, momentum=0.9, weight_decay=0.0005)
lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=3, gamma=0.1)

num_epochs = 2  # ajustar según tu necesidad

for epoch in range(num_epochs):
    model.train()
    running_loss = 0.0
    for images, targets in train_loader:
        images = list(img.to(device) for img in images)
        targets = [{k: v.to(device) for k, v in t.items()} for t in targets]

        loss_dict = model(images, targets)
        losses = sum(loss for loss in loss_dict.values())

        optimizer.zero_grad()
        losses.backward()
        optimizer.step()

        running_loss += losses.item()

    print(f"Epoch {epoch+1}/{num_epochs}, Loss: {running_loss/len(train_loader):.4f}")

    lr_scheduler.step()

TRAIN_DIR = "/content/project/datasets/african-wildlife/data/train"
VALID_DIR = "/content/project/datasets/african-wildlife/data/valid"

from datasets import create_train_loader, create_valid_dataset, create_valid_loader

train_dataset = create_train_dataset(TRAIN_DIR)
valid_dataset = create_valid_dataset(VALID_DIR)

train_loader = create_train_loader(train_dataset)
valid_loader = create_valid_loader(valid_dataset)

print("Número de batches en train_loader:", len(train_loader))
print("Número de batches en valid_loader:", len(valid_loader))

CLASSES = ["elephant", "lion", "zebra", "giraffe"]  # tus clases
NUM_CLASSES = len(CLASSES)  # número de clases
RESIZE_TO = 800  # tamaño de las imágenes
BATCH_SIZE = 8   # tamaño del batch para entrenamiento
NUM_WORKERS = 0  # para Colab, evita problemas con multiprocesamiento

%run config.py

def create_train_loader(train_dataset, num_workers=0):
    train_loader = DataLoader(
        train_dataset,
        batch_size=BATCH_SIZE,
        shuffle=True,
        num_workers=num_workers,
        collate_fn=collate_fn,
        drop_last=True,
    )
    return train_loader

from datasets import create_train_dataset, create_valid_dataset

train_dataset = create_train_dataset(TRAIN_DIR)
valid_dataset = create_valid_dataset(VALID_DIR)

print("Samples train_dataset:", len(train_dataset))
print("Samples valid_dataset:", len(valid_dataset))

DATA_DIR = "/content/project/datasets/african-wildlife/data"
TRAIN_IMAGES = f"{DATA_DIR}/train/images"
TRAIN_LABELS = f"{DATA_DIR}/train/labels"
VALID_IMAGES = f"{DATA_DIR}/valid/images"
VALID_LABELS = f"{DATA_DIR}/valid/labels"

def create_train_dataset(DIR):
    train_dataset = CustomDataset(
        dir_path=DIR, width=RESIZE_TO, height=RESIZE_TO, classes=CLASSES, transforms=get_train_transform()
    )
    return train_dataset

def create_train_dataset(DIR):
    train_dataset = CustomDataset(
        dir_path=DIR, width=RESIZE_TO, height=RESIZE_TO, classes=CLASSES, transforms=get_train_transform()
    )
    return train_dataset

import os

train_dir = "/content/project/datasets/african-wildlife/data/train"
valid_dir = "/content/project/datasets/african-wildlife/data/valid"

print("Train dir exists:", os.path.exists(train_dir))
print("Valid dir exists:", os.path.exists(valid_dir))

print("Train images:", os.listdir(os.path.join(train_dir, "images"))[:5])
print("Train labels:", os.listdir(os.path.join(train_dir, "labels"))[:5])

print("Valid images:", os.listdir(os.path.join(valid_dir, "images"))[:5])
print("Valid labels:", os.listdir(os.path.join(valid_dir, "labels"))[:5])



train_dataset = create_train_dataset(train_dir)
valid_dataset = create_valid_dataset(valid_dir)

print("Samples train_dataset:", len(train_dataset))
print("Samples valid_dataset:", len(valid_dataset))

import torch
from datasets import create_train_dataset, create_valid_dataset, create_train_loader, create_valid_loader
from model import create_model
from config import NUM_CLASSES, RESIZE_TO, BATCH_SIZE

# --- Rutas ---
train_dir = "/content/project/datasets/african-wildlife/data/train"
valid_dir = "/content/project/datasets/african-wildlife/data/valid"

# --- Crear datasets ---
train_dataset = create_train_dataset(train_dir)
valid_dataset = create_valid_dataset(valid_dir)

print("Samples train_dataset:", len(train_dataset))
print("Samples valid_dataset:", len(valid_dataset))

# --- Crear loaders ---
train_loader = create_train_loader(train_dataset)
valid_loader = create_valid_loader(valid_dataset)

print("Batches train_loader:", len(train_loader))
print("Batches valid_loader:", len(valid_loader))

# --- Configuración del dispositivo ---
device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")
print("Usando dispositivo:", device)

# --- Crear modelo ---
model = create_model(num_classes=NUM_CLASSES)
model.to(device)

# --- Optimizer y scheduler ---
params = [p for p in model.parameters() if p.requires_grad]
optimizer = torch.optim.AdamW(params, lr=1e-4)
lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.1)

# --- Entrenamiento ---
num_epochs = 2  # puedes aumentar después

from tqdm import tqdm

for epoch in range(num_epochs):
    model.train()
    running_loss = 0.0
    for images, targets in tqdm(train_loader, desc=f"Epoch {epoch+1}"):
        images = list(img.to(device) for img in images)
        targets = [{k: v.to(device) for k, v in t.items()} for t in targets]

        loss_dict = model(images, targets)
        losses = sum(loss for loss in loss_dict.values())

        optimizer.zero_grad()
        losses.backward()
        optimizer.step()

        running_loss += losses.item()

    print(f"Epoch {epoch+1}/{num_epochs}, Loss: {running_loss/len(train_loader):.4f}")
    lr_scheduler.step()

!mkdir -p /content/project/outputs
!mv /content/project/best_model_79.pth /content/project/outputs/

%run app.py
/bin/bash: line 1: nvidia-smi: command not found
CUDA disponible: False
Torch: 2.8.0+cu126
Upload widget is only available when the cell has been executed in the current browser session. Please rerun this cell to enable.