So, I'm new to deep learning and I've started with cats and dogs dataset for a CNN Model using Keras.
In my code, I'm unable to get probabilities as output for both classifier.predict
or classifier.predict_proba
. I'm just getting the output as [[0,1]]
or [[1,0]]
. I've tried with several images.
But I'm looking for something like, [[0.4,0.6]]
, [[0.89,0.11]]
I've tried changing loss function from binary_crossentropy
to categorical_crossentropy
.
I've tried changing the activation function of the output layer from sigmoid
to softmax
.
I've also tried changing the class_mode
in flow_from_directory
from binary
to categorical
.
I think I might be going wrong with the data type, as the type of array of output is float32. But even if that is the error, I don't know how to change it though.
I'm unable to find where I'm going wrong. Please clarify/help. Thanks.
Why do I need probabilities?
In my another project, I'll be splitting an image into 'n' number of smaller pieces. I'll then use the classifier on 'n' number of pieces separately and find the one piece with the largest probability. For this, I won't use the dataset of cats and dogs though. It's for bin-picking and that dataset will also be binary output as 'YES' or 'NO'. Any suggestions for this is also welcome. Thanks.
Link for the code in Github.
#Building the CNN
from keras.models import Sequential
from keras.layers import Convolution2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
#Initialising the CNN
classifier = Sequential()
#Step 1 - Convolution
classifier.add(Convolution2D(filters=32,kernel_size=[3,3],input_shape=(64,64,3),activation='relu'))
#Step 2 - Pooling
classifier.add(MaxPooling2D(pool_size=(2,2),strides=2))
#Adding another Convolutional Layer for better accuracy
#classifier.add(Convolution2D(filters=32,kernel_size=[3,3],activation='relu'))
#classifier.add(MaxPooling2D(pool_size=(2,2),strides=2))
#Step 3 - Flattening
classifier.add(Flatten())
#Step 4 - Fully Connected Layers
classifier.add(Dense(units= 64, activation='relu'))
classifier.add(Dense(units= 2, activation='softmax'))
#Compiling the CNN
classifier.compile(optimizer='adam',loss = 'categorical_crossentropy', metrics=['accuracy'])
#Part 2 - Fitting the CNN to the images
from keras.preprocessing.image import ImageDataGenerator
train_datagen=ImageDataGenerator(
rescale=1./255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
test_datagen=ImageDataGenerator(rescale=1./255)
training_set = train_datagen.flow_from_directory('dataset/training_set',
target_size=(64,64),
batch_size=32,
class_mode='categorical')
test_set = test_datagen.flow_from_directory('dataset/test_set',
target_size=(64,64),
batch_size=32,
class_mode='categorical')
classifier.fit_generator(training_set,
steps_per_epoch=250,
epochs=3, #Just for time being I've kept very few epochs.
validation_data=test_set,
validation_steps=62)
#Making new Predictions
import numpy as np
from keras.preprocessing import image
test_image_luna=image.load_img('dataset/single/SkilletLuna.JPG',target_size=(64,64))
test_image2=image.img_to_array(test_image_luna)
test_image2=np.expand_dims(test_image2,axis=0)
luna=classifier.predict_proba(test_image2)
In [11]: luna
...:
Out[11]: array([[0., 1.]], dtype=float32)
I think I found the mistake. You are rescaling your train and test data with the ImageDataGenerator
. But you are not doing that when testing a single image.
Try this:
# Making new Predictions
import numpy as np
from keras.preprocessing import image
test_image_luna = image.load_img('D:\\NR\\data\\live2013\\caps.bmp', target_size=(64,64))
test_image2 = image.img_to_array(test_image_luna)/255.
test_image2 = np.expand_dims(test_image2, axis=0)
luna = classifier.predict_proba(test_image2)
The high input values lead to very high output values. Since you are using softmax activation these values are leading to predictions very close to 0 and 1.