import os import shutil import torch import torch.nn as nn import torchvision.transforms as transforms import torchvision.models as models from torchvision import datasets from torch.utils.data import DataLoader import numpy as np import matplotlib.pyplot as plt import seaborn as sns from sklearn.metrics import confusion_matrix, classification_report # Define dataset paths structured_dataset_path = "C:\\Users\\srira\\OneDrive\\Desktop\\AI_PROJ\\structured_data" train_dir = os.path.join(structured_dataset_path, "train") val_dir = os.path.join(structured_dataset_path, "val") test_dir = os.path.join(structured_dataset_path, "test") # Define data augmentation transformations train_transform = transforms.Compose([ transforms.Resize((224, 224)), transforms.RandomHorizontalFlip(), transforms.RandomRotation(20), transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2, hue=0.1), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), ]) val_test_transform = transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), ]) # Load datasets train_dataset = datasets.ImageFolder(root=train_dir, transform=train_transform) val_dataset = datasets.ImageFolder(root=val_dir, transform=val_test_transform) test_dataset = datasets.ImageFolder(root=test_dir, transform=val_test_transform) train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True) val_loader = DataLoader(val_dataset, batch_size=32, shuffle=False) test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False) # Load pretrained model model = models.resnet50(pretrained=True) num_ftrs = model.fc.in_features model.fc = nn.Linear(num_ftrs, len(train_dataset.classes)) # Define loss function and optimizer criterion = nn.CrossEntropyLoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.001) scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.1) # Reduce LR every 5 epochs def train_model(model, train_loader, val_loader, criterion, optimizer, scheduler, num_epochs=10): device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model.to(device) for epoch in range(num_epochs): model.train() running_loss = 0.0 correct = 0 total = 0 for images, labels in train_loader: images, labels = images.to(device), labels.to(device) optimizer.zero_grad() outputs = model(images) loss = criterion(outputs, labels) loss.backward() optimizer.step() running_loss += loss.item() _, predicted = outputs.max(1) total += labels.size(0) correct += predicted.eq(labels).sum().item() scheduler.step() train_acc = 100 * correct / total val_acc = evaluate_model(model, val_loader) print(f"Epoch {epoch+1}/{num_epochs}, Loss: {running_loss/len(train_loader):.4f}, Train Acc: {train_acc:.2f}%, Val Acc: {val_acc:.2f}%") return model def evaluate_model(model, test_loader): model.eval() correct = 0 total = 0 all_preds = [] all_labels = [] device = torch.device("cuda" if torch.cuda.is_available() else "cpu") with torch.no_grad(): for images, labels in test_loader: images, labels = images.to(device), labels.to(device) outputs = model(images) _, predicted = outputs.max(1) total += labels.size(0) correct += predicted.eq(labels).sum().item() all_preds.extend(predicted.cpu().numpy()) all_labels.extend(labels.cpu().numpy()) cm = confusion_matrix(all_labels, all_preds) plt.figure(figsize=(8, 6)) sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=test_dataset.classes, yticklabels=test_dataset.classes) plt.xlabel('Predicted') plt.ylabel('Actual') plt.title('Confusion Matrix') plt.show() print("Classification Report:") print(classification_report(all_labels, all_preds, target_names=test_dataset.classes)) return 100 * correct / total # Train the model with augmentation and learning rate scheduling trained_model = train_model(model, train_loader, val_loader, criterion, optimizer, scheduler, num_epochs=10) # Save the model torch.save(trained_model.state_dict(), "smart_recycling_model1.pth") print ("Model saved successfully!")