Spaces:
Runtime error
Runtime error
| import os | |
| import time | |
| import torch | |
| import torch.nn as nn | |
| import torch.optim as optim | |
| from torchvision import datasets, models, transforms | |
| # Configuration and Paths | |
| DATA_DIR = 'dataset' | |
| NUM_CLASSES = 10 | |
| BATCH_SIZE = 32 | |
| NUM_EPOCHS = 10 | |
| DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu") | |
| print(f"Running on device: {DEVICE}") | |
| # Data Pipeline and Preprocessing | |
| data_transforms = { | |
| 'train': transforms.Compose([ | |
| transforms.RandomResizedCrop(224), | |
| transforms.RandomHorizontalFlip(), | |
| transforms.ToTensor(), | |
| transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) | |
| ]), | |
| 'val': transforms.Compose([ | |
| transforms.Resize(256), | |
| transforms.CenterCrop(224), | |
| transforms.ToTensor(), | |
| transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) | |
| ]), | |
| } | |
| image_datasets = { | |
| x: datasets.ImageFolder(os.path.join(DATA_DIR, x), data_transforms[x]) | |
| for x in ['train', 'val'] | |
| } | |
| dataloaders = { | |
| x: torch.utils.data.DataLoader(image_datasets[x], batch_size=BATCH_SIZE, shuffle=True) | |
| for x in ['train', 'val'] | |
| } | |
| class_names = image_datasets['train'].classes | |
| print(f"Found {len(class_names)} classes: {class_names}") | |
| # Load Pretrained EfficientNet-B0 and Modify Classifier | |
| try: | |
| weights = models.EfficientNet_B0_Weights.DEFAULT | |
| model = models.efficientnet_b0(weights=weights) | |
| except AttributeError: | |
| model = models.efficientnet_b0(pretrained=True) | |
| num_ftrs = model.classifier[1].in_features | |
| model.classifier[1] = nn.Linear(num_ftrs, NUM_CLASSES) | |
| model = model.to(DEVICE) | |
| criterion = nn.CrossEntropyLoss() | |
| optimizer = optim.Adam(model.parameters(), lr=0.001) | |
| # Training Loop | |
| best_acc = 0.0 | |
| start_time = time.time() | |
| for epoch in range(NUM_EPOCHS): | |
| print(f'\nEpoch {epoch+1}/{NUM_EPOCHS}') | |
| print('-' * 15) | |
| for phase in ['train', 'val']: | |
| if phase == 'train': | |
| model.train() | |
| else: | |
| model.eval() | |
| running_loss = 0.0 | |
| running_corrects = 0 | |
| for inputs, labels in dataloaders[phase]: | |
| inputs, labels = inputs.to(DEVICE), labels.to(DEVICE) | |
| optimizer.zero_grad() | |
| with torch.set_grad_enabled(phase == 'train'): | |
| outputs = model(inputs) | |
| _, preds = torch.max(outputs, 1) | |
| loss = criterion(outputs, labels) | |
| if phase == 'train': | |
| loss.backward() | |
| optimizer.step() | |
| running_loss += loss.item() * inputs.size(0) | |
| running_corrects += torch.sum(preds == labels.data) | |
| epoch_loss = running_loss / len(image_datasets[phase]) | |
| epoch_acc = running_corrects.double() / len(image_datasets[phase]) | |
| print(f'[{phase.upper()}] Loss: {epoch_loss:.4f} | Accuracy: {epoch_acc:.4f}') | |
| # Save the best model | |
| if phase == 'val' and epoch_acc > best_acc: | |
| best_acc = epoch_acc | |
| torch.save(model.state_dict(), 'best_thai_food_model.pth') | |
| print("Best model updated and saved.") | |
| time_elapsed = time.time() - start_time | |
| print(f'\nTraining complete in {time_elapsed // 60:.0f}m {time_elapsed % 60:.0f}s') | |
| print(f'Highest Validation Accuracy: {best_acc:.4f}') | |