Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to interpret results returned by model.predict?

I'm trying to make a neural network that can identify if there is a cat in a picture. I found this tutorial on tensorflow website and tried to adapt it to my problem. The tutorial is for classifying cats and dogs, but since I only want to detect cats, I changed the categories to cats and non-cats.

For non-cats I downloaded a dataset of random images.

I added two generators to the code from the tutorial:

test_data_gen = test_image_generator.flow_from_directory(batch_size=batch_size,
                                                               directory=test_dir,
                                                               target_size=(IMG_HEIGHT, IMG_WIDTH),
                                                               class_mode='binary')

pred_data_gen = pred_image_generator.flow_from_directory(batch_size=batch_size,
                                                                 directory=pred_dir,
                                                                 target_size=(IMG_HEIGHT, IMG_WIDTH),
                                                                 class_mode='binary')

And then tested the model like this:

print('\n# Evaluate on test data')
results = model.evaluate_generator(test_data_gen)
print('test loss, test acc:', results)

print('\n# Generate predictions')
predictions = model.predict(pred_data_gen)
print(len(predictions))
print(predictions)

That's the output:

# Evaluate on test data
test loss, test acc: [0.45212748232815003, 0.9324082]
# Generate predictions for custom samples
256
[[ -8.023465  ]
 [ -7.781438  ]
 [ 50.281197  ]
 [-10.172492  ]
 [ -5.1096087 ]
 [ 43.0299    ]
 [ 21.416649  ]
 ...
 [-10.866359  ]
 [-14.797473  ]
 [ 84.72212   ]
 [ 23.712345  ]
 [ -6.4916744 ]
 [-18.384903  ]
 [ 33.10642   ]]

The test accuracy is very high, but I have no idea what these results mean. I thought they should be between 0 and 1, but these even have negative values. How should I interpret these results?

EDIT:

This is my model (before adding the sigmoid activation function to the last layer):

model = Sequential([
    Conv2D(16, 3, padding='same', activation='relu', input_shape=(IMG_HEIGHT, IMG_WIDTH, 3)),
    MaxPooling2D(),
    Conv2D(32, 3, padding='same', activation='relu'),
    MaxPooling2D(),
    Conv2D(64, 3, padding='same', activation='relu'),
    MaxPooling2D(),
    Flatten(),
    Dense(512, activation='relu'),
    Dense(1)
])

I changed the last layer to Dense(1, activation='sigmoid') and the output looks like this:

# Evaluate on test data
test loss, test acc: [0.714477022488912, 0.5949367]

# Generate predictions for custom samples
256
[[1.]
 [1.]
 [1.]
 ...
 [1.]
 [1.]
 [1.]]

All predicted values are ones, even though only half of the images are cats in the test set.

EDIT2:

Here is how I compile and fit the model:

model.compile(optimizer='adam',
              loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
              metrics=['accuracy'])

model.summary()

history = model.fit_generator(
    train_data_gen,
    steps_per_epoch=total_train // batch_size,
    epochs=epochs,
    validation_data=val_data_gen,
    validation_steps=total_val // batch_size
)
like image 536
Wojtek Wencel Avatar asked Sep 19 '25 04:09

Wojtek Wencel


1 Answers

The last layer in your model is a Dense layer with a single neuron. Since no parameters have been passed to it, by default it has linear activation. User @Code Pope indicated that it is a "failure" (mistake in Tensorflow docs?). It isn't, the code is perfectly fine.

Your loss function computes binary crossentropy and it can easily work with linear activation. In fact computing sigmoid is just a little extra that is not needed. The ANN will output negative values for one class and positive for the other one. They are not normalised, but are so-called logits - that's why you are saying in your loss function from_logits=True.

How to get predictions:

from sklearn.metrics import accuracy_score

images, actual = next(train_data_gen)
predictions = model.predict(images)
predictions = (predictions > 0).flatten()
accuracy_score(results, pred)
like image 170
Lukasz Tracewski Avatar answered Sep 21 '25 20:09

Lukasz Tracewski