so this morning did some heavy machine learning project that train model using CNN EfficientNet model using torch python for image classification. Just now, when i want to rerun my other python project that uses opencv, it was very laggy and i can't escape the webcam window (im collecting data using webcam). i tried cleaning ram, background processes, restarting my laptop and shitting down and opening it back, but it's still the same. i even tried to uninstall and reinstall python, i also uninstalled torch because i figured that maybe the model training was eating my laptop ram or cpu. but its still the same. anyone know how should i fix this, my opencv webcam window was working perfectly fine and fast before i did the model training project.. i searched tutorials on youtube and still won't make it fast like before. im using macbook air m1 btw. this was the code i ran: import os import numpy as np import torch import torch.nn as nn from torch.optim import Adam from torch.utils.data import DataLoader, SubsetRandomSampler from torchvision.datasets import DatasetFolder from torchvision.io import read_image import torchvision.transforms as T from torchvision.models import efficientnet_b0 from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix, ConfusionMatrixDisplay import matplotlib.pyplot as plt from tqdm import tqdm # ---- Dataset & Transform ---- transform = T.Compose([ T.Resize((224, 224)), # EfficientNet input size T.Lambda(lambda img: img.convert("RGB")), T.ToTensor(), T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) dataset_path = "/Users/HA/fish-classification/Fish_Dataset/Fish_Dataset" dataset = DatasetFolder( dataset_path, loader=lambda path: T.ToPILImage()(read_image(path)), extensions=('jpg', 'png'), transform=transform ) class_names = dataset.classes num_classes = len(class_names) labels = np.array(dataset.targets) indices = np.arange(len(dataset)) np.random.seed(123) train_indices, test_indices, y_train, y_test = train_test_split(indices, labels, test_size=0.2, stratify=labels) train_indices, val_indices, y_train, y_val = train_test_split(train_indices, y_train, test_size=0.2, stratify=y_train) train_loader = DataLoader(dataset, sampler=SubsetRandomSampler(train_indices), batch_size=16) val_loader = DataLoader(dataset, sampler=SubsetRandomSampler(val_indices), batch_size=16) test_loader = DataLoader(dataset, sampler=SubsetRandomSampler(test_indices), batch_size=16) # ---- Model ---- class FishEfficientNet(nn.Module): def __init__(self, num_classes): super(FishEfficientNet, self).__init__() self.base = efficientnet_b0(pretrained=True) # Freeze feature extractor for param in self.base.features.parameters(): param.requires_grad = False # Replace classifier in_features = self.base.classifier[1].in_features self.base.classifier[1] = nn.Linear(in_features, num_classes) def forward(self, x): return self.base(x) # ---- Training ---- def train_model(model, train_loader, val_loader, optimizer, criterion, epochs, device): model.to(device) history = {'train': {'loss': [], 'acc': []}, 'val': {'loss': [], 'acc': []}} for epoch in range(epochs): model.train() total_loss, correct, total = 0, 0, 0 for inputs, labels in tqdm(train_loader, desc=f"Epoch {epoch+1}/{epochs}"): inputs, labels = inputs.to(device), labels.to(device) optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() total_loss += loss.item() * inputs.size(0) preds = outputs.argmax(1) correct += (preds == labels).sum().item() total += labels.size(0) train_loss = total_loss / total train_acc = correct / total history['train']['loss'].append(train_loss) history['train']['acc'].append(train_acc) val_metrics = evaluate_model(model, val_loader, criterion, device) history['val']['loss'].append(val_metrics['loss']) history['val']['acc'].append(val_metrics['acc']) print(f"Epoch {epoch+1}: Train Loss={train_loss:.4f}, Acc={train_acc:.4f}, Val Loss={val_metrics['loss']:.4f}, Val Acc={val_metrics['acc']:.4f}") return history # ---- Evaluation ---- def evaluate_model(model, loader, criterion, device): model.eval() total_loss, correct, total = 0, 0, 0 all_preds, all_labels = [], [] with torch.no_grad(): for inputs, labels in loader: inputs, labels = inputs.to(device), labels.to(device) outputs = model(inputs) loss = criterion(outputs, labels) total_loss += loss.item() * inputs.size(0) preds = outputs.argmax(1) correct += (preds == labels).sum().item() total += labels.size(0) all_preds.extend(preds.cpu().numpy()) all_labels.extend(labels.cpu().numpy()) return { 'loss': total_loss / total, 'acc': correct / total, 'prec': precision_score(all_labels, all_preds, average='macro', zero_division=1), 'rec': recall_score(all_labels, all_preds, average='macro', zero_division=1), 'f1': f1_score(all_labels, all_preds, average='macro', zero_division=1), 'cm': confusion_matrix(all_labels, all_preds) } # ---- Run ---- device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model = FishEfficientNet(num_classes).to(device) optimizer = Adam(model.parameters(), lr=0.0003) criterion = nn.CrossEntropyLoss() history = train_model(model, train_loader, val_loader, optimizer, criterion, epochs=10, device=device) # Save model weights torch.save(model.state_dict(), 'model.pth') # ---- Plotting ---- plt.figure() plt.plot(history['train']['loss'], label='Train Loss') plt.plot(history['val']['loss'], label='Val Loss') plt.legend() plt.title("Loss over Epochs") plt.xlabel("Epoch") plt.ylabel("Loss") plt.show() plt.figure() plt.plot(history['train']['acc'], label='Train Acc') plt.plot(history['val']['acc'], label='Val Acc') plt.legend() plt.title("Accuracy over Epochs") plt.xlabel("Epoch") plt.ylabel("Accuracy") plt.show() # ---- Final Test ---- results = evaluate_model(model, test_loader, criterion, device) print(f"Test Accuracy: {results['acc']:.4f}, Precision: {results['prec']:.4f}, Recall: {results['rec']:.4f}, F1: {results['f1']:.4f}") disp = ConfusionMatrixDisplay(confusion_matrix=results['cm'], display_labels=class_names) disp.plot() plt.show() Continue reading...