Tzetha's picture
Uploaded Complete App
81e78bd verified
import os
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms, models
from torch.utils.data import DataLoader
from tqdm import tqdm
from pathlib import Path
# Set device
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# Paths
root_dir = Path("/oxford_pet_dataset")
train_dir = root_dir / "train"
val_dir = root_dir / "val"
# Parameters
BATCH_SIZE = 32
EPOCHS = 10
NUM_CLASSES = len(os.listdir(train_dir)) # Assumes one folder per class
# Transforms
train_transforms = transforms.Compose([
transforms.Resize((224, 224)),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize([0.5]*3, [0.5]*3)
])
val_transforms = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize([0.5]*3, [0.5]*3)
])
# Datasets
train_dataset = datasets.ImageFolder(train_dir, transform=train_transforms)
val_dataset = datasets.ImageFolder(val_dir, transform=val_transforms)
# DataLoaders
train_loader = DataLoader(train_dataset, batch_size=BATCH_SIZE, shuffle=True)
val_loader = DataLoader(val_dataset, batch_size=BATCH_SIZE)
# Model
model = models.resnet18(pretrained=True)
model.fc = nn.Linear(model.fc.in_features, NUM_CLASSES)
model = model.to(device)
# Loss and optimizer
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=1e-4)
# Training loop
for epoch in range(EPOCHS):
model.train()
train_loss, train_correct = 0.0, 0
for inputs, labels in tqdm(train_loader, desc=f"Epoch {epoch+1}/{EPOCHS} [Train]"):
inputs, labels = inputs.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
train_loss += loss.item() * inputs.size(0)
train_correct += (outputs.argmax(1) == labels).sum().item()
train_acc = train_correct / len(train_dataset)
# Validation
model.eval()
val_loss, val_correct = 0.0, 0
with torch.no_grad():
for inputs, labels in tqdm(val_loader, desc=f"Epoch {epoch+1}/{EPOCHS} [Val]"):
inputs, labels = inputs.to(device), labels.to(device)
outputs = model(inputs)
loss = criterion(outputs, labels)
val_loss += loss.item() * inputs.size(0)
val_correct += (outputs.argmax(1) == labels).sum().item()
val_acc = val_correct / len(val_dataset)
print(f"Epoch {epoch+1}: Train Acc: {train_acc:.4f}, Val Acc: {val_acc:.4f}")
# Save model
torch.save(model.state_dict(), "pet_classifier.pth")
print("Model saved as pet_classifier.pth")