I tried using Sklearn to get the F1-Score and Confusion Matrix for the following data but with no success. Here is the working code.
import torch, torch.nn as nn, torch.nn.functional as F
from torch.autograd import Variable
import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
import torch.utils.data as data_utils
from sklearn.metrics import f1_score
from torchvision import datasets
from torchvision import transforms
from torch.utils.data import DataLoader
from torch.utils.data import SubsetRandomSampler
import torch.nn.functional as F
import matplotlib.pyplot as plt
import torch
import time
from sklearn.datasets import load_breast_cancer
%matplotlib inline
RANDOM_SEED = 123
BATCH_SIZE = 32
NO_OF_FEATURES=30
NO_OF_CLASSES=2
NUM_HIDDEN_1 = 75
NUM_HIDDEN_2 = 65
DROP_PROBA = 0.5
NUM_EPOCHS = 17
DEVICE = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
df = load_breast_cancer()
X, y = df.data, df.target
sc = StandardScaler()
X = sc.fit_transform(X)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1)
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.25, random_state=1) # 0.25 x 0.8 = 0.2
X_train = torch.from_numpy(X_train)
y_train = torch.from_numpy(y_train).double()
train = data_utils.TensorDataset(X_train, y_train)
train_loader = data_utils.DataLoader(train, batch_size=BATCH_SIZE, shuffle=True)
X_val = torch.from_numpy(X_val)
y_val = torch.from_numpy(y_val).double()
valid = data_utils.TensorDataset(X_val, y_val)
valid_loader = data_utils.DataLoader(valid, batch_size=BATCH_SIZE, shuffle=True)
X_test = torch.from_numpy(X_test)
y_test = torch.from_numpy(y_test).double()
test = data_utils.TensorDataset(X_test, y_test)
test_loader = data_utils.DataLoader(test, batch_size=BATCH_SIZE, shuffle=True)
class MultilayerPerceptron(torch.nn.Module):
def __init__(self, num_features, num_classes,
num_hidden_1, num_hidden_2):
super(MultilayerPerceptron, self).__init__()
self.my_network = torch.nn.Sequential(
torch.nn.Linear(num_features, num_hidden_1),
torch.nn.ReLU(),
torch.nn.Linear(num_hidden_1, num_hidden_2),
torch.nn.ReLU(),
torch.nn.Linear(num_hidden_2, num_classes)
)
def forward(self, x):
logits = self.my_network(x)
probas = F.softmax(logits, dim=1)
return logits, probas
def compute_accuracy_and_loss_f1score_metrics(model, data_loader, device):
correct_pred, num_examples = 0, 0
cross_entropy = 0.
for i, (features, targets) in enumerate(data_loader):
#features = features.view(-1, 28*28)
features = Variable(features.type(torch.FloatTensor))
targets = Variable(targets.type(torch.FloatTensor))
features = features.to(device)
targets = targets.to(device)
logits, probas = model(features)
cross_entropy += F.cross_entropy(logits, targets.type(torch.LongTensor)).item()
_, predicted_labels = torch.max(probas, 1)
num_examples += targets.size(0)
correct_pred += (predicted_labels == targets.type(torch.LongTensor)).sum()
#F1-score
target_ = targets.data.cpu().numpy()
output_ = predicted_labels.data.cpu().numpy()
f1_batch = f1_score(output_ , target_ , average='macro')
#f1_batch = f1_score(targets.cpu(),logits.sigmoid().cpu() > 0.15,average='macro')
#conf_matrix = confusion_matrix(predicted_labels.view(-1), targets.view(-1))
#TP = predicted_labels * targets
#FP = predicted_labels * (1-targets)
#FN = (1-predicted_labels) * targets
#TN = (1-predicted_labels) * (1-targets)
return correct_pred.float()/num_examples * 100, cross_entropy/num_examples, f1_batch
# Model Initialization
torch.manual_seed(RANDOM_SEED)
model = MultilayerPerceptron(num_features=NO_OF_FEATURES,
num_hidden_1=NUM_HIDDEN_1,
num_hidden_2=NUM_HIDDEN_2,
num_classes=NO_OF_CLASSES)
model = model.to(DEVICE)
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
# Training
start_time = time.time()
train_acc_lst, valid_acc_lst = [], []
train_loss_lst, valid_loss_lst = [], []
train_f1_lst, valid_f1_lst = [], []
for epoch in range(NUM_EPOCHS):
model.train()
for batch_idx, (features, targets) in enumerate(train_loader):
### PREPARE MINIBATCH
#features = features.view(-1, 28*28)
features = Variable(features.type(torch.FloatTensor))
targets = Variable(targets.type(torch.FloatTensor))
features = features.to(DEVICE)
targets = targets.to(DEVICE)
### FORWARD AND BACK PROP
logits, probas = model(features)
cost = F.cross_entropy(logits, targets.type(torch.LongTensor))
optimizer.zero_grad()
cost.backward()
### UPDATE MODEL PARAMETERS
optimizer.step()
### LOGGING
if not batch_idx % 120:
print (f'Epoch: {epoch+1:03d}/{NUM_EPOCHS:03d} | '
f'Batch {batch_idx:03d}/{len(train_loader):03d} | '
f'Cost: {cost:.4f}')
# no need to build the computation graph for backprop when computing accuracy
model.eval()
with torch.set_grad_enabled(False):
train_acc, train_loss, f1 = compute_accuracy_and_loss_f1score_metrics(model, train_loader, device=DEVICE)
valid_acc, valid_loss, f1 = compute_accuracy_and_loss_f1score_metrics(model, valid_loader, device=DEVICE)
train_acc_lst.append(train_acc)
valid_acc_lst.append(valid_acc)
train_loss_lst.append(train_loss)
valid_loss_lst.append(valid_loss)
train_f1_lst.append(train_f1)
valid_f1_lst.append(valid_f1)
print(f'Epoch: {epoch+1:03d}/{NUM_EPOCHS:03d} Train Acc.: {train_acc:.4f}%'
f' | Validation Acc.: {valid_acc:.4f}% | '
f' |Validation f1.: {valid_f1:.4f}%')
elapsed = (time.time() - start_time)/60
print(f'Time elapsed: {elapsed:.2f} min')
elapsed = (time.time() - start_time)/60
print(f'Total Training Time: {elapsed:.2f} min')
Error
Epoch: 001/017 | Batch 000/011 | Cost: 0.6913
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-88-e8b9b1f72c62> in <module>
174 train_f1_lst.append(train_f1)
175 valid_f1_lst.append(valid_f1)
--> 176 print(f'Epoch: {epoch+1:03d}/{NUM_EPOCHS:03d} Train Acc.: {train_acc:.4f}%'
177 f' | Validation Acc.: {valid_f1:.4f}%')
178
~/miniconda2/lib/python3.6/site-packages/torch/tensor.py in __format__(self, format_spec)
385 if self.dim() == 0:
386 return self.item().__format__(format_spec)
--> 387 return object.__format__(self, format_spec)
388
389 def __ipow__(self, other):
TypeError: unsupported format string passed to Tensor.__format__