PyTorch 多层感知机 (MLP) 模型对比:用于心脏病预测
import torch import torch.nn as nn import torch.optim as optim import pandas as pd import numpy as np import matplotlib.pyplot as plt from sklearn.metrics import roc_curve, auc
Define the first model
class Model1(nn.Module): def init(self, input_size, hidden_size, num_classes): super(Model1, self).init() self.fc1 = nn.Linear(input_size, hidden_size) self.relu = nn.ReLU() self.fc2 = nn.Linear(hidden_size, num_classes)
def forward(self, x):
out = self.fc1(x)
out = self.relu(out)
out = self.fc2(out)
return out
Define the second model
class Model2(nn.Module): def init(self, input_size, hidden_size, num_classes): super(Model2, self).init() self.fc1 = nn.Linear(input_size, hidden_size) self.relu = nn.ReLU() self.fc2 = nn.Linear(hidden_size, num_classes)
def forward(self, x):
out = self.fc1(x)
out = self.relu(out)
out = self.fc2(out)
return out
Define the third model
class Model3(nn.Module): def init(self, input_size, hidden_size, num_classes): super(Model3, self).init() self.fc1 = nn.Linear(input_size, hidden_size) self.relu = nn.ReLU() self.fc2 = nn.Linear(hidden_size, num_classes) self.sigmoid = nn.Sigmoid()
def forward(self, x):
out = self.fc1(x)
out = self.relu(out)
out = self.fc2(out)
out = self.sigmoid(out)
return out
Define the training function for each model
def train(model, criterion, optimizer, num_epochs, train_loader, device): train_loss = [] train_acc = []
# Loop through each epoch
for epoch in range(num_epochs):
running_loss = 0.0
running_corrects = 0.0
# Loop through each batch in the training set
for inputs, labels in train_loader:
inputs = inputs.to(device)
labels = labels.to(device)
# Zero the parameter gradients
optimizer.zero_grad()
# Forward + backward + optimize
outputs = model(inputs.float())
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
# Track the statistics
running_loss += loss.item() * inputs.size(0)
_, preds = torch.max(outputs, 1)
running_corrects += torch.sum(preds == labels.data)
# Calculate the epoch loss and accuracy
epoch_loss = running_loss / len(train_loader.dataset)
epoch_acc = running_corrects.double() / len(train_loader.dataset)
# Print the statistics for this epoch
print(f'Epoch {epoch + 1}/{num_epochs}, '
f'Train Loss: {epoch_loss:.4f}, '
f'Train Acc: {epoch_acc:.4f}')
# Save the statistics for plotting
train_loss.append(epoch_loss)
train_acc.append(epoch_acc)
return model, train_loss, train_acc
Define a function to plot the loss and accuracy curves
def plot_curves(train_loss, train_acc, model_num): plt.figure(figsize=(10, 5)) plt.subplot(1, 2, 1) plt.plot(train_loss) plt.title(f'Model {model_num} Training Loss') plt.xlabel('Epoch') plt.ylabel('Loss') plt.subplot(1, 2, 2) plt.plot(train_acc) plt.title(f'Model {model_num} Training Accuracy') plt.xlabel('Epoch') plt.ylabel('Accuracy') plt.show()
Load the data
data = pd.read_csv('heart.csv') data = data.sample(frac=1).reset_index(drop=True)
Split the data into train and test sets
train_data = data[:200] test_data = data[200:]
Define the input size and number of classes
input_size = 13 num_classes = 2
Define the device
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
Define the hyperparameters
learning_rate = 0.01 hidden_size = 50 num_epochs = 100
Define the data loaders
train_loader = torch.utils.data.DataLoader(train_data, batch_size=32, shuffle=True) test_loader = torch.utils.data.DataLoader(test_data, batch_size=32, shuffle=False)
Train the first model
model1 = Model1(input_size, hidden_size, num_classes).to(device) criterion1 = nn.CrossEntropyLoss() optimizer1 = optim.Adam(model1.parameters(), lr=learning_rate) model1, train_loss1, train_acc1 = train(model1, criterion1, optimizer1, num_epochs, train_loader, device) plot_curves(train_loss1, train_acc1, 1)
Train the second model
model2 = Model2(input_size, hidden_size, num_classes).to(device) criterion2 = nn.CrossEntropyLoss() optimizer2 = optim.Adam(model2.parameters(), lr=learning_rate) model2, train_loss2, train_acc2 = train(model2, criterion2, optimizer2, num_epochs, train_loader, device) plot_curves(train_loss2, train_acc2, 2)
Train the third model
model3 = Model3(input_size, hidden_size, num_classes).to(device) criterion3 = nn.BCELoss() optimizer3 = optim.Adam(model3.parameters(), lr=learning_rate) model3, train_loss3, train_acc3 = train(model3, criterion3, optimizer3, num_epochs, train_loader, device) plot_curves(train_loss3, train_acc3, 3)
Evaluate the models on the test set
model1.eval() model2.eval() model3.eval()
y_true = [] y_pred1 = [] y_pred2 = [] y_pred3 = []
with torch.no_grad(): for inputs, labels in test_loader: inputs = inputs.to(device) labels = labels.to(device)
outputs1 = model1(inputs.float())
outputs2 = model2(inputs.float())
outputs3 = model3(inputs.float())
_, preds1 = torch.max(outputs1, 1)
_, preds2 = torch.max(outputs2, 1)
preds3 = outputs3.squeeze().cpu().numpy().tolist()
y_true += labels.cpu().numpy().tolist()
y_pred1 += preds1.cpu().numpy().tolist()
y_pred2 += preds2.cpu().numpy().tolist()
y_pred3 += preds3
fpr1, tpr1, thresholds1 = roc_curve(y_true, y_pred1) fpr2, tpr2, thresholds2 = roc_curve(y_true, y_pred2) fpr3, tpr3, thresholds3 = roc_curve(y_true, y_pred3) roc_auc1 = auc(fpr1, tpr1) roc_auc2 = auc(fpr2, tpr2) roc_auc3 = auc(fpr3, tpr3)
plt.figure(figsize=(10, 5)) plt.subplot(1, 2, 1) plt.plot(fpr1, tpr1, label=f'Model 1 (AUC = {roc_auc1:.2f})') plt.plot(fpr2, tpr2, label=f'Model 2 (AUC = {roc_auc2:.2f})') plt.plot(fpr3, tpr3, label=f'Model 3 (AUC = {roc_auc3:.2f})') plt.plot([0, 1], [0, 1], '--', color='gray') plt.title('Receiver Operating Characteristic Curve') plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plt.legend() plt.subplot(1, 2, 2) plt.bar(['Model 1', 'Model 2', 'Model 3'], [roc_auc1, roc_auc2, roc_auc3]) plt.title('Area Under the Curve') plt.ylabel('AUC') plt.show()
原文地址: https://www.cveoy.top/t/topic/mmx2 著作权归作者所有。请勿转载和采集!