CNN not working correctly

username: SoulHokib
cooked: <p>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.</p>
<p>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.</p>
<pre><code class="lang-auto">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)

</code></pre>
<pre><code class="lang-auto">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)
</code></pre>
<pre><code class="lang-auto">#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))
</code></pre>
<pre><code class="lang-auto"># 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)
</code></pre>
<p>And the result of the training :</p>
<pre><code class="lang-auto">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
</code></pre>
<p>Thanks already for your help, I’m kind of stuck with it and doesn’t know how to process correctly</p>

username: Nikronic
cooked: <p>Hi,</p>
<p>Could you explan about <code>X</code> and <code>y</code> and how you get data?</p>
<aside class="quote no-group" data-username="SoulHokib" data-post="1" data-topic="86396">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/soulhokib/48/14790_2.png" class="avatar"> SoulHokib:</div>
<blockquote>
<p>but I am not sure I am processing correctly the data with it to have either 0 or 1 at the end.</p>
</blockquote>
</aside>
<aside class="quote no-group" data-username="SoulHokib" data-post="1" data-topic="86396">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/soulhokib/48/14790_2.png" class="avatar"> SoulHokib:</div>
<blockquote>
<pre><code class="lang-auto">X_train = X
y_train = y
</code></pre>
</blockquote>
</aside>

username: SoulHokib
cooked: <p>Ultimately, it looks like it is working, but my model is always predicting “0”. I need to adapt and overcome this issue, but I have got many sources for it right now. Thanks for your answer tho</p>