Untitled
unknown
plain_text
9 months ago
6.0 kB
4
Indexable
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
from sklearn.model_selection import train_test_split
# 1. Caricamento e preprocessamento del dataset
def load_monk_dataset(file_path):
"""
Carica il dataset MONK dal file specificato e lo preprocessa.
- file_path: Percorso del file del dataset.
Ritorna:
- X: Tensor con le feature.
- y: Tensor con le label.
"""
features = []
labels = []
with open(file_path, 'r') as file:
for line in file:
parts = line.strip().split()
labels.append(int(parts[0])) # La prima colonna è la label (class)
features.append([int(x) for x in parts[1:-1]]) # Le colonne da a1 a a6 sono le feature
X = torch.tensor(features, dtype=torch.float32)
y = torch.tensor(labels, dtype=torch.long)
return X, y
# 2. Definizione della rete neurale
class SimpleNN(nn.Module):
def __init__(self, input_size, hidden_size, num_classes):
super(SimpleNN, self).__init__()
self.fc1 = nn.Linear(input_size, hidden_size) # Primo layer: da input a hidden
self.relu = nn.ReLU() # Funzione di attivazione ReLU
self.fc2 = nn.Linear(hidden_size, num_classes) # Secondo layer: da hidden a output
def forward(self, x):
x = self.fc1(x) # Passa attraverso il primo layer
x = self.relu(x) # Applica ReLU
x = self.fc2(x) # Passa attraverso il secondo layer
return x
# 3. Funzione per preparare i dati in DataLoader
def prepare_data(X_train, y_train, X_test, y_test, batch_size=16):
"""
Trasforma i dati di addestramento e test in tensori PyTorch
e li organizza in DataLoader per facilitarne la gestione in mini-batch.
- X_train, y_train: Dati di addestramento (features e label).
- X_test, y_test: Dati di test (features e label).
Ritorna:
- train_loader: DataLoader per i dati di addestramento.
- test_loader: DataLoader per i dati di test.
"""
train_dataset = TensorDataset(X_train, y_train)
test_dataset = TensorDataset(X_test, y_test)
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
return train_loader, test_loader
# 4. Funzione per addestrare il modello
def train_model(model, train_loader, criterion, optimizer, epochs=10):
"""
Addestra il modello sui dati di training.
- model: Rete neurale da addestrare.
- train_loader: DataLoader per i dati di addestramento.
- criterion: Funzione di perdita da minimizzare.
- optimizer: Algoritmo di ottimizzazione (es. Adam).
- epochs: Numero di epoche (cicli di addestramento).
"""
model.train()
for epoch in range(epochs):
total_loss = 0
for X_batch, y_batch in train_loader:
optimizer.zero_grad()
outputs = model(X_batch)
loss = criterion(outputs, y_batch)
loss.backward()
optimizer.step()
total_loss += loss.item()
# print(f"Epoch {epoch+1}/{epochs}, Loss: {total_loss:.4f}")
# 5. Funzione per valutare il modello
def evaluate_model(model, test_loader):
"""
Valuta il modello sui dati di test.
- model: Rete neurale da valutare.
- test_loader: DataLoader per i dati di test.
"""
model.eval()
correct = 0
total = 0
with torch.no_grad():
for X_batch, y_batch in test_loader:
outputs = model(X_batch)
_, predicted = torch.max(outputs, 1)
total += y_batch.size(0)
correct += (predicted == y_batch).sum().item()
accuracy = correct / total * 100
print(f"Test Accuracy: {accuracy:.2f}%")
return accuracy
# 6. Carica e preprocessa il dataset
X, y = load_monk_dataset('monks-1.train')
# Normalizzazione delle feature
X_min = X.min(dim=0, keepdim=True)[0]
X_max = X.max(dim=0, keepdim=True)[0]
X = (X - X_min) / (X_max - X_min) # Normalizzazione min-max
# Split in training e validation (cross-validation)
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)
# 7. Configurazione del modello
input_size = X.shape[1] # Numero di feature nel dataset (a1, a2, ..., a6)
hidden_size = 10 # Numero di neuroni nel layer nascosto
num_classes = 2 # Classificazione binaria (0, 1)
learning_rate = 0.001 # Velocità di apprendimento
epochs = 20 # Numero di epoche per l'addestramento
# Inizializza il modello
model = SimpleNN(input_size, hidden_size, num_classes)
# Definisci la funzione di perdita (CrossEntropyLoss per classificazione)
criterion = nn.CrossEntropyLoss()
# Definisci l'ottimizzatore (Adam)
optimizer = optim.Adam(model.parameters(), lr=learning_rate)
# 8. Applicare Cross-Validation (5 fold)
best_model = None
best_accuracy = 0
for fold in range(5):
print(f"\nTraining Fold {fold + 1}/5")
# Prepara i DataLoader per il training e validation
train_loader, val_loader = prepare_data(X_train, y_train, X_val, y_val)
# Addestra il modello
train_model(model, train_loader, criterion, optimizer, epochs)
# Valuta il modello
accuracy = evaluate_model(model, val_loader)
# Se l'accuratezza è migliore, salva il modello
if accuracy > best_accuracy:
best_accuracy = accuracy
best_model = model
# 9. Test del modello su "monk-1.test"
X_test, y_test = load_monk_dataset('monks-1.test')
X_test = (X_test - X_min) / (X_max - X_min) # Normalizza anche i dati di test
# Prepara i DataLoader per il test
_, test_loader = prepare_data(X_test, y_test, X_test, y_test)
# Valuta il miglior modello sui dati di test
print("\nEvaluating the Best Model on Test Data:")
evaluate_model(best_model, test_loader)
Editor is loading...
Leave a Comment