1

How could I get probabilities from Keras?

I trained my CNN model for 3 classes. When I use predict() method of the trained model (using Functional API) on new test image I always get one hot encoded output, e.i [0, 1, 0], whereas I'd like to get output such as [0.1, 0.95, 0.1].

I am using softmax as last activation so all probabilities sum up to 1 which is expected. However I made a dummy model where I trained it only on one epoch and I still get one hot encoded output and not the probabilities.

Am I doing something wrong here, like calling wrong method? Otherwise how could I get the output of last layer, so I could normalize the output?

Snippet of prediction script:

model = load_model('./model.h5')
model.compile(loss='categorical_crossentropy',
              optimizer='adadelta',
              metrics=['acc'])

img = image.load_img(path.name,
                     target_size=(128, 128),
                     color_mode='grayscale')
img = image.img_to_array(img)
img = np.expand_dims(img, axis=0)
probability = model.predict(img)
print(probability)

Train script:

# Creates input shape for theano or tensorflow.
if K.image_data_format() == 'channels_first':
    input_shape = (1, 128, 128)
else:
    input_shape = (128, 128, 1)
visible = Input(shape=input_shape)

conv1_1 = Conv2D(filters=8,kernel_size=(5, 5),padding='same', strides = 1)(visible)
prelu1_1 = PReLU(alpha_initializer='zeros')(conv1_1)
pool1_1 = MaxPooling2D(pool_size=(2, 2),strides=2)(prelu1_1)

flat1 = Flatten()(pool1_1)

conv2_1 = Conv2D(filters=8,kernel_size=(5, 5),padding='same', strides = 1)(visible)
prelu2_1 = PReLU(alpha_initializer='zeros')(conv2_1)
pool2_1 = MaxPooling2D(pool_size=(2, 2),strides=2)(prelu2_1)

flat2 = Flatten()(pool2_1)

# Merge layers
merge = concatenate([flat1, flat2])

dense = Dense(64)(merge)
prelu3 = PReLU(alpha_initializer='zeros')(dense)
dropout3 = Dropout(rate=0.4)(prelu3)

dense4 = Dense(3)(dropout3)
output = Activation('softmax')(dense4)

model = Model(inputs=visible, outputs=output)

model.compile(loss='categorical_crossentropy',
              optimizer='Adadelta',
              metrics=['accuracy'])

train_datagen = ImageDataGenerator(
    rescale=1. / 255,
    shear_range=0.2,
    width_shift_range=0.1,
    height_shift_range=0.1,
    rotation_range=5,
    horizontal_flip=True)

test_datagen = ImageDataGenerator(
    rescale=1. / 255, )


train_data_dir = r'D:\path\to\train'
validation_data_dir = r'D:\path\to\validation'

train_generator = train_datagen.flow_from_directory(
    train_data_dir,
    target_size=(128, 128),
    batch_size=32,
    color_mode='grayscale',
    class_mode='categorical')

validation_generator = test_datagen.flow_from_directory(
    validation_data_dir,
    target_size=(128, 128),
    batch_size=32,
    color_mode='grayscale',
    class_mode='categorical')

model_final = model.fit_generator(
    train_generator,
    steps_per_epoch=11000 // 32,
    epochs=1,
    validation_data=validation_generator,
    validation_steps=3000 // 32)

# Save model
model.save('./model.h5')

Keras version: 2.1.6

NOTE: model is built on the functional API, that is (keras.models.Model())

user3053452
  • 640
  • 1
  • 12
  • 38
  • Neural Networks for classification are known to have overconfident probabilities, so its not unexpected that you get one-hot encoded-like probabilities. – Dr. Snoopy Apr 05 '19 at 09:11

1 Answers1

2

If you are not using the functional API you could do model.predict_proba() for obtaining probabilities.

probability = model.predict_proba(img)

Hope this helps.

BCJuan
  • 805
  • 8
  • 17
  • This is not possible anymore. predict_proba() is deprecated. – user3053452 Apr 03 '19 at 09:47
  • If you use the functional API https://github.com/keras-team/keras/issues/2524#issuecomment-218590463 https://stackoverflow.com/questions/52653320/predict-proba-method-of-keras-model-does-not-exist – BCJuan Apr 03 '19 at 09:52
  • Here they have the other way around problem: from probs to classes. Maybe this will help you: https://stackoverflow.com/questions/38971293/get-class-labels-from-keras-functional-model/45176824#45176824 If you post the training script I can try to help you more – BCJuan Apr 03 '19 at 10:00
  • 1
    The thing is, I get the feeling that predict already returns argmax of probabilities. Since there is little chance that 1000 predicted pictures would get 100% probability after training for 1 epoch. – user3053452 Apr 03 '19 at 10:52
  • @user3053452 No, predict returns the output of the model, without any postprocessing. – Dr. Snoopy Apr 05 '19 at 08:32
  • @MatiasValdenegro which means? Returns the probability or the classes? Both are output of the model. – user3053452 Apr 05 '19 at 10:03
  • @user3053452 your model outputs probabilities, the output class indices are a postprocessing by applying argmax, but only predict_classes does that, not predict – Dr. Snoopy Apr 05 '19 at 10:21
  • I have later seen your other comment about overconfidence. So atm Im looking into that. – user3053452 Apr 05 '19 at 10:23