As I already talked about here lately, I am trying to implement a CNN to make binary classification (0 or 1) on MRI Images about brain hemorragies. I implemented a model, tried to evaluate it, but I am pretty sure this is not working correctly and I don’t know how to correct it.
The architecture seems fine, but I am not sure I am processing correctly the data with it to have either 0 or 1 at the end.
class Net(Module):
def __init__(self):
super(Net, self).__init__()
self.cnn_layers = Sequential(
# Defining a 2D convolution layer
Conv2d(3, 4, kernel_size=3, stride=1, padding=1),
BatchNorm2d(4),
ReLU(inplace=True),
MaxPool2d(kernel_size=2),
# Defining another 2D convolution layer
Conv2d(4, 4, kernel_size=4, stride=1, padding=1),
BatchNorm2d(4),
ReLU(inplace=True),
MaxPool2d(kernel_size=2),
)
self.linear_layers = Sequential(
Linear(4 * 49 * 49, 100),
ReLU(inplace=True),
Dropout(p=0.8),
Linear(100,200),
ReLU(inplace=True),
Linear(200,1),
)
# Defining the forward pass
def forward(self, x):
x = self.cnn_layers(x)
x = x.view(x.size(0), -1)
x = self.linear_layers(x)
#print("Après FC : ",x)
return x
# defining the model
model = Net()
#model = model.to('cuda')
# defining the optimizer
optimizer = Adam(model.parameters(), lr=0.07)
# defining the loss function
criterion = BCEWithLogitsLoss()
# checking if GPU is available
#if torch.cuda.is_available():
# model = model.cuda()
# criterion = criterion.cuda()
from torchsummary import summary
#vgg = models.vgg16()
#summary(model.cuda(), (3, 200, 200))
print(model)
def perf_measure(y_actual, y_hat):
TP = 0
FP = 0
TN = 0
FN = 0
for i in range(len(y_hat)):
if y_actual[i]==y_hat[i]==1:
TP += 1
if y_hat[i]==1 and y_actual[i]!=y_hat[i]:
FP += 1
if y_actual[i]==y_hat[i]==0:
TN += 1
if y_hat[i]==0 and y_actual[i]!=y_hat[i]:
FN += 1
return(TP, FP, TN, FN)
#Fonction d'entraînement actuelle.
def train2(epoch):
model.train()
tr_loss = 0
total = 0
correct = 0
target_true = 0
predicted_true = 0
correct_true = 0
X_train = X
y_train = y
# converting the data into GPU format
#if torch.cuda.is_available():
# X_train = X_train.cuda()
# y_train = y_train.cuda()
# clearing the Gradients of the model parameters
optimizer.zero_grad()
# prediction for training and validation set
output_train = model(X_train)
#y_pred = output_train.round()
# computing the training and validation loss
loss_train = criterion(output_train, y_train.unsqueeze(1).type_as(output_train))
train_losses.append(loss_train.item())
total += y_train.size(0)
correct += (output_train.argmax(-1) == y_train).sum().item()
# computing the updated weights of all the model parameters
loss_train.backward()
optimizer.step()
tr_loss = loss_train.item()
truepos, falsepos, trueneg, falseneg = perf_measure(output_train.round(), y_train.unsqueeze(1).type_as(output_train))
print("TP :", truepos, "FP :", falsepos, "TN :", trueneg, "FN :",falseneg)
average_precision = average_precision_score(y_train.cpu().detach().numpy(), output_train.cpu().detach().numpy())
if epoch%2 == 0:
# printing the validation loss
print('Epoch : ',epoch+1, '\t', 'loss : ', tr_loss, 'accuracy : ', (correct / total)*100)
print('Average precision-recall score: {0:0.2f}'.format(
average_precision))
# defining the number of epochs
n_epochs = 100
# empty list to store training losses
train_losses = []
test_losses = []
# training the model
for epoch in range(n_epochs):
train2(epoch)
And the result of the training :
TP : 0 FP : 99 TN : 0 FN : 701
Epoch : 1 loss : 0.37433111667633057 accuracy : 87.625
Average precision-recall score: 0.12
TP : 0 FP : 99 TN : 0 FN : 701
TP : 0 FP : 99 TN : 0 FN : 701
Epoch : 3 loss : 0.37433186173439026 accuracy : 87.625
Average precision-recall score: 0.12
TP : 0 FP : 99 TN : 0 FN : 701
TP : 0 FP : 99 TN : 0 FN : 701
Epoch : 5 loss : 0.3743324279785156 accuracy : 87.625
Average precision-recall score: 0.12
TP : 0 FP : 99 TN : 0 FN : 701
TP : 0 FP : 99 TN : 0 FN : 701
Epoch : 7 loss : 0.37433212995529175 accuracy : 87.625
Average precision-recall score: 0.12
Thanks already for your help, I’m kind of stuck with it and doesn’t know how to process correctly