CNN SVM

Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 4

### train

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 sklearn.svm import SVC
import joblib
import os
import numpy as np

# Parameters
dropoutfactor = 0.5
maxepoch = 100
batchsize = 128
learning_rate = 0.001
optimizer_fn = optim.Adam

# Define transforms for data preprocessing


data_transforms = {
'train': transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
]),
}

# Load the dataset


def load_data(data_dir, batch_size):
train_dir = os.path.join(data_dir, 'train')

image_dataset = datasets.ImageFolder(train_dir, data_transforms['train'])


dataloader = DataLoader(image_dataset, batch_size=batch_size, shuffle=True)

print(f"Loaded {len(image_dataset)} training images.")


return dataloader, image_dataset.classes

# Load MobileNetV2 pretrained on ImageNet and modify for fine-tuning


def get_mobilenet_v2_finetuning(num_classes):
model = models.mobilenet_v2(weights='DEFAULT') # Sử dụng weights tốt nhất
model.classifier = nn.Sequential(
nn.Dropout(dropoutfactor),
nn.Linear(model.last_channel, num_classes)
)
return model

# Train MobileNetV2 model with fine-tuning


def train_mobilenetv2(model, train_loader, max_epoch, learning_rate, optimizer_fn):
optimizer = optimizer_fn(model.parameters(), lr=learning_rate)
criterion = nn.CrossEntropyLoss()
best_accuracy = 0.0
best_model_weights = None

for epoch in range(max_epoch):


model.train() # Enable training mode
running_loss = 0.0
correct = 0
total = 0
for inputs, labels in train_loader:
inputs, labels = inputs.to(device), labels.to(device) # Move to GPU
optimizer.zero_grad() # Clear gradients
outputs = model(inputs) # Forward pass
loss = criterion(outputs, labels) # Compute loss
loss.backward() # Backpropagation
optimizer.step() # Update weights

running_loss += loss.item()
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()

# Calculate accuracy
accuracy = 100 * correct / total
# Print epoch, loss, and accuracy
print(f"Epoch [{epoch+1}/{max_epoch}], Loss: {running_loss /
len(train_loader):.4f}, Accuracy: {accuracy:.2f}%")

# Save the best model


if accuracy > best_accuracy:
best_accuracy = accuracy
best_model_weights = model.state_dict()

# Load best model weights


model.load_state_dict(best_model_weights)
return model

# Extract features from MobileNetV2


def extract_features(model, loader):
model.eval()
features = []
labels = []

with torch.no_grad():
for inputs, target_labels in loader:
inputs = inputs.to(device) # Move to GPU
outputs = model(inputs)
features.append(outputs.cpu().numpy())
labels.append(target_labels.cpu().numpy())

features = np.concatenate(features, axis=0)


labels = np.concatenate(labels, axis=0)
return features, labels

# Train SVM on extracted features


def train_svm(features, labels):
svm_classifier = SVC(kernel='linear')
svm_classifier.fit(features, labels)
return svm_classifier

# Path to thyroid dataset


data_dir = '/kaggle/input/thyroid/split1'

# Load data
dataloaders, class_names = load_data(data_dir, batchsize)

# Initialize GPU device


device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"Using device: {device}")

# Initialize MobileNetV2 for fine-tuning


mobilenet_v2_model = get_mobilenet_v2_finetuning(num_classes=len(class_names))
mobilenet_v2_model.to(device) # Move model to GPU

# Fine-tune MobileNetV2 model for maxepoch epochs and save best model
mobilenet_v2_model = train_mobilenetv2(mobilenet_v2_model, dataloaders, maxepoch,
learning_rate, optimizer_fn)

# Extract features from fine-tuned MobileNetV2


train_features, train_labels = extract_features(mobilenet_v2_model, dataloaders)

# Train SVM classifier on the extracted features


svm_classifier = train_svm(train_features, train_labels)

# Save the fine-tuned MobileNetV2 and SVM models


torch.save(mobilenet_v2_model.state_dict(), 'finetuned_mobilenet_v2_best.pth')
joblib.dump(svm_classifier, 'svm_classifier_finetuned_mobilenetv2.joblib')

print("Fine-tuning complete. Best MobileNetV2 and SVM models saved.")

### test

import torch
import numpy as np
from torchvision import datasets, transforms, models
from torch.utils.data import DataLoader
import joblib
import os
from sklearn.metrics import f1_score, confusion_matrix

# Define transforms for data preprocessing


data_transforms = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])

# Load the dataset for testing


def load_test_data(data_dir, batch_size):
test_dir = os.path.join(data_dir, 'test')
test_dataset = datasets.ImageFolder(test_dir, data_transforms)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)

print(f"Loaded {len(test_dataset)} test images.")


return test_loader, test_dataset.classes

# Extract features from MobileNetV2 for testing


def extract_test_features(model, loader):
model.eval()
features = []
labels = []

with torch.no_grad():
for inputs, target_labels in loader:
inputs = inputs.to(device) # Move to GPU
outputs = model(inputs)
features.append(outputs.cpu().numpy())
labels.append(target_labels.cpu().numpy())

features = np.concatenate(features, axis=0)


labels = np.concatenate(labels, axis=0)
return features, labels

# Evaluate the model on the test dataset


def evaluate_model(model, svm_classifier, test_loader):
test_features, test_labels = extract_test_features(model, test_loader)
predictions = svm_classifier.predict(test_features)

# Calculate metrics
accuracy = np.sum(predictions == test_labels) / len(test_labels)
tn, fp, fn, tp = confusion_matrix(test_labels, predictions).ravel()

sensitivity = tp / (tp + fn) if (tp + fn) > 0 else 0


specificity = tn / (tn + fp) if (tn + fp) > 0 else 0
f_measure = f1_score(test_labels, predictions, average='binary')

# Print results
print(f'Accuracy: {accuracy:.4f}')
print(f'F-measure: {f_measure:.4f}')
print(f'Sensitivity: {sensitivity:.4f}')
print(f'Specificity: {specificity:.4f}')

# Path to thyroid dataset


data_dir = '/kaggle/input/thyroid/split1'
batchsize=32
# Load test data
test_loader, class_names = load_test_data(data_dir, batchsize)

# Initialize GPU device


device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"Using device: {device}")

# Load the fine-tuned MobileNetV2 model


mobilenet_v2_model = get_mobilenet_v2_finetuning(num_classes=len(class_names))
mobilenet_v2_model.load_state_dict(torch.load('/kaggle/input/model-thyroid/
finetuned_mobilenet_v2_best.pth'))
mobilenet_v2_model.to(device)

# Load the SVM classifier


svm_classifier =
joblib.load('/kaggle/input/model-thyroid/svm_classifier_finetuned_mobilenetv2.jobli
b')

# Evaluate the model on the test set


evaluate_model(mobilenet_v2_model, svm_classifier, test_loader)

You might also like