-1

I created a CNN using Tensorflow to identify pneumonia and sometimes it returns a very small number as a prediction. why is this happening?

I have attached the link for the dataset

Here I how I process and load the data.

from tensorflow.keras.preprocessing.image import ImageDataGenerator

train_datagen = ImageDataGenerator( rescale = 1.0/255. )
val_datagen  = ImageDataGenerator( rescale = 1.0/255. )
test_datagen = ImageDataGenerator( rescale = 1.0/255. )

train_generator = train_datagen.flow_from_directory('/kaggle/input/chest-xray-pneumonia/chest_xray/chest_xray/train/',
                                                    batch_size=20,
                                                    class_mode='binary',
                                                    target_size=(350, 350)) 

validation_generator =  val_datagen.flow_from_directory('/kaggle/input/chest-xray-pneumonia/chest_xray/chest_xray/val/',
                                                         batch_size=20,
                                                         class_mode  = 'binary',
                                                         target_size = (350, 350))
test_generator = test_datagen.flow_from_directory('/kaggle/input/chest-xray-pneumonia/chest_xray/chest_xray/test/',
                                                         batch_size=20,
                                                         class_mode  = 'binary',
                                                         target_size = (350, 350

And here the Model, compile and fit functions

import tensorflow as tf

model = tf.keras.models.Sequential([
    # Note the input shape is the desired size of the image 150x150 with 3 bytes color
    tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(350, 350, 3)),
    tf.keras.layers.MaxPooling2D(2,2),
    tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2), 
    tf.keras.layers.Conv2D(64, (3,3), activation='relu'), 
    tf.keras.layers.MaxPooling2D(2,2),
    # Flatten the results to feed into a DNN
    tf.keras.layers.Flatten(), 
    # 512 neuron hidden layer
    tf.keras.layers.Dense(1024, activation='relu'), 
    # Only 1 output neuron. It will contain a value from 0-1 where 0 for 1 class ('cats') and 1 for the other ('dogs')
    tf.keras.layers.Dense(1, activation='sigmoid')  
])

compile the model

from tensorflow.keras.optimizers import RMSprop

model.compile(optimizer=RMSprop(learning_rate=0.001),
              loss='binary_crossentropy',
              metrics = ['accuracy'])

model fit

history = model.fit(train_generator,
                              validation_data=validation_generator,
                              steps_per_epoch=200,
                              epochs=2000,
                              validation_steps=200,
                              callbacks=[callbacks],
                              verbose=2)

The evaluation metrics as followings, loss: 0.2351 - accuracy: 0.9847

The prediction shows a very small number for the negative pneumonia, and for positive it shows more than .50.

I have two questions:

  1. why I get a very small number as 2.xxxx * 10e-20?

  2. why I can't get the following values as null?

    val_acc = history.history[ 'val_accuracy' ] 
    val_loss = history.history['val_loss' ]
    
desertnaut
  • 57,590
  • 26
  • 140
  • 166
Namindu Sanchila
  • 414
  • 1
  • 9
  • 23

1 Answers1

1

I see that there is no problem with your code, neither with the results you get.

This is a binary classification problem (2 classes: Positive or negative pneumonia), and the output of your model is one neurone giving values between 0 and 1.

So if the output is higher than 0.5, this means positive pneumonia. Otherwise, when you have a very small value like 2 * 10e-20 this means that it's negative pneumonia.

For your second question, you are not supposed to have accuracy and loss values to be null simply because the model is well trained and has 98% accuracy on training data.

Reda El Hail
  • 966
  • 1
  • 7
  • 17
  • history= model.fit(), the history object doesn't have either val_accury/val_acc or val_loss. This is why I mentioned it hasn't values. – Namindu Sanchila Nov 24 '21 at 08:51
  • @NaminduSanchila, could you please add the output of `val_acc = history.history[ 'val_accuracy' ] val_loss = history.history['val_loss' ]` to the question. – Reda El Hail Nov 24 '21 at 09:09
  • It is shows error, `--------------------------------------------------------------------------- KeyError Traceback (most recent call last) /tmp/ipykernel_35/1406712358.py in 6 #----------------------------------------------------------- 7 acc = history.history['accuracy'] ----> 8 val_acc = history.history['val_acc'] 9 loss = history.history['loss'] 10 # val_loss = history.history['val_loss'] KeyError: 'val_acc'` – Namindu Sanchila Nov 24 '21 at 10:00
  • The very first epoch is shows like this`200/200 [==============================] - 68s 303ms/step - loss: 0.3897 - accuracy: 0.8739 - val_loss: 1.0525 - val_accuracy: 0.6875` then after epochs it didn't shows val_acc and val_loss – Namindu Sanchila Nov 24 '21 at 10:03
  • 1
    @NaminduSanchila Please **focus** your question (edit it if necessary) to a single clear issue; as is, it is difficult to see what *exactly* your question is about, given also that you seemed to confuse very small numbers for negative ones. "*why I can't get the following values as null?*" does not read like "*I can't get `val_acc` and `val_loss` values*", as you seem to imply in your comments here. – desertnaut Nov 24 '21 at 10:13
  • Yes, there are two quetions. – Namindu Sanchila Nov 24 '21 at 11:39