Transfer Learning MobileNet with dataset that contains grayscale images - python

I have a problem. I would like to train a network using MobileNevV2, but from what I know you can only pass color images to it.
My dataset contains ONLY Black and White images.
If I try to pass the shape of the image as (224, 224, 1) obviously the error returns me:
Traceback (most recent call last):
File "/home/andrea/Scrivania/COMPUTER-VISION/MobileNet_train.py", line 40, in <module>
mobielNetV2 = tensorflow.keras.applications.MobileNetV2(input_shape=IMG_SHAPE, include_top=False, weights='imagenet')
File "/home/andrea/.local/lib/python3.9/site-packages/keras/applications/mobilenet_v2.py", line 279, in MobileNetV2
input_shape = imagenet_utils.obtain_input_shape(
File "/home/andrea/.local/lib/python3.9/site-packages/keras/applications/imagenet_utils.py", line 372, in obtain_input_shape
raise ValueError('The input must have 3 channels; Received '
ValueError: The input must have 3 channels; Received `input_shape=(224, 224, 1)`
How can I train the black and white image model?
The following is the code that I've created:
import matplotlib.pyplot as plt
import tensorflow
from tensorflow.keras.layers import Dense, Flatten
from tensorflow.keras.models import Model
from tensorflow.keras.preprocessing.image import ImageDataGenerator
IMAGE_SIZE = (224, 224)
IMG_SHAPE = IMAGE_SIZE + (1,)
DATASET_DIR = "/home/andrea/Scrivania/COMPUTER-VISION/DATASET/KAGGLE/new_train"
BATCH_SIZE = 32
EPOCHS = 5
datagen = ImageDataGenerator(
validation_split=0.2,
rescale=1. / 255, # per processare più velocemente i dati
brightness_range=[1, 2]
)
train_generator = datagen.flow_from_directory(
DATASET_DIR,
target_size=IMAGE_SIZE,
batch_size=BATCH_SIZE,
class_mode="categorical",
subset="training"
)
test_generator = datagen.flow_from_directory(
DATASET_DIR,
target_size=IMAGE_SIZE,
batch_size=BATCH_SIZE,
class_mode="categorical",
subset="validation"
)
mobielNetV2 = tensorflow.keras.applications.MobileNetV2(input_shape=IMG_SHAPE, include_top=False, weights='imagenet')
for layer in mobielNetV2.layers:
layer.trainable = False
x = Flatten()(mobielNetV2.output)
prediction = Dense(6, activation='softmax')(x)
model = Model(inputs=mobielNetV2.input, outputs=prediction)
# tell the model what cost and optimization method to use
model.summary()
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
r = model.fit(train_generator, validation_data=test_generator, epochs=EPOCHS, steps_per_epoch=len(train_generator),
validation_steps=len(test_generator))
model.save("MobileNet_Hand.h5")

The error that you've received it's likely because you're passing a grayscale input but your dataloader expects color_model = rgb by default. Look at the possible options for color mode here - (ISSUE 1). And also you're passing a grayscale input (h, w, 1) to a model with ImageNet weights which trained on RGB input (h, w, 3) - (ISSUE 2).
IMAGE_SIZE = (224, 224)
IMG_SHAPE = IMAGE_SIZE + (1,)
.. .flow_from_directory(
DATASET_DIR,
color_mode='rgb', # < ------ ISSUE 1
target_size=IMAGE_SIZE,
batch_size=BATCH_SIZE,
class_mode="categorical",
subset="training"
)
mobielNetV2 = ..applications.MobileNetV2(
input_shape=IMG_SHAPE, # < ------ ISSUE 2
include_top=False,
weights='imagenet')
...
...
ValueError: The input must have 3 channels; Received `input_shape=(224, 224, 1)`
Solutions 1
If you don't care about the pretrained weight of ImageNet, then you need to change as follows in your setup:
.. .flow_from_directory(
DATASET_DIR,
color_mode='grayscale', # < ------ SOVLED ISSUE 1
...
)
mobielNetV2 = ...applications.MobileNetV2(
input_shape=IMG_SHAPE,
include_top=False,
weights=None) # < ------ SOVLED ISSUE 2
Solutions 2
If you want ImageNet weight and also you want your grayscale as an input at the same time, then there are two options to choose from.
Option a: (recommended)
Mapping the grayscale input to RGB with trainable layer followed by ImageNet model.
.. .flow_from_directory(
DATASET_DIR,
color_mode='grayscale', # < ------ SOVLED ISSUE 1
...
)
# rgb-imagenet-model
mobilenet = keras.applications.MobileNetV2(include_top=False,
weights='imagenet',
input_shape=(100, 100, 3))
# mapping grayscale to RGB
input_tensor = keras.Input(shape=(100, 100, 1))
x = keras.layers.Conv2D(3, (3, 3), padding='same')(input_tensor)
# followed by image-net model
x = mobilenet(x)
y = keras.layers.GlobalAveragePooling2D()(x)
y = ....
model = keras.Model(input_tensor, y)
Option b:
Mapping the grayscale input to RGB with non-trainable tensorflow operation followed by ImageNet model.
.. .flow_from_directory(
DATASET_DIR,
color_mode='grayscale', # < ------ SOVLED ISSUE 1
....
)
# rgb-imagenet-model
mobilenet = keras.applications.MobileNetV2(include_top=False,
weights='imagenet',
input_shape=(100, 100, 3))
# mapping grayscale to RGB
input_tensor = keras.Input(shape=(100, 100, 1))
gray_to_rgb = keras.layers.Lambda(lambda x:tf.image.grayscale_to_rgb(x),
output_shape=lambda x:x)
x = gray_to_rgb(input_tensor)
# followed by image-net model
x = mobilenet(x)
y = keras.layers.GlobalAveragePooling2D()(x)
model = keras.Model(input_tensor, y)
``

Let's assume you already have greyscale images and you want to convert them to rgb images to train your model:
import tensorflow as tf
import matplotlib.pyplot as plt
flowers = tf.keras.utils.get_file(
'flower_photos',
'https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz',
untar=True)
img_gen = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255)
ds = tf.data.Dataset.from_generator(
lambda: img_gen.flow_from_directory(flowers, batch_size=32, shuffle=False),
output_types=(tf.float32, tf.float32))
ds = ds.map(lambda x, y: (tf.image.rgb_to_grayscale(x), y))
images, _ = next(iter(ds.take(1)))
image = images[0]
print(image.shape)
plt.imshow(image.numpy()[:,:,0], cmap='gray')
(256, 256, 1)
Greyscale:
RGB:
ds = ds.map(lambda x, y: (tf.image.grayscale_to_rgb(x), y))
images, _ = next(iter(ds.take(1)))
image = images[0]
print(image.shape)
plt.imshow(image.numpy())
(256, 256, 3)
So, just use tf.image.grayscale_to_rgb combined with dataset.map and you should be good to go.
Update 1:
datagen = ImageDataGenerator(
validation_split=0.2,
rescale=1. / 255, # per processare più velocemente i dati
brightness_range=[1, 2]
)
train_generator = datagen.flow_from_directory(
DATASET_DIR,
target_size=IMAGE_SIZE,
batch_size=BATCH_SIZE,
class_mode="categorical",
subset="training"
)
ds = tf.data.Dataset.from_generator(
lambda: train_generator,
output_types=(tf.float32, tf.float32))

Related

UnimplementedError: Graph execution error: Fused conv implementation does not support grouped convolutions for now

I have checked to make sure that the number of channels in my model and imagedatagenerator match, and have rgb images that are passed into the model. I know this question is similar to another question that was posted but I tried those solutions and haven't been able to get past this error.
# Build model
num_channels = 1
image_size = 720
num_labels = 49
model1 = Sequential()
model1.add(Conv2D(32, (3,3), input_shape = (image_size, image_size, num_channels)))
model1.add(Activation('relu'))
model1.add(Conv2D(32, (3,3)))
model1.add(Activation('relu'))
model1.add(MaxPooling2D(pool_size=(2,2)))
model1.add(Conv2D(64, (3,3)))
model1.add(Activation('relu'))
model1.add(Conv2D(64, (3,3)))
model1.add(Activation('relu'))
model1.add(MaxPooling2D(pool_size=(2,2)))
model1.add(Flatten())
model1.add(Dense(200))
model1.add(Activation('relu'))
model1.add(Dense(200))
model1.add(Activation('relu'))
model1.add(Dense(num_labels))
model1.save_weights("ckpt")
model1.load_weights("ckpt")
model1.summary()
# load data into ImageDataGen for on the fly augmented imgs and fit into model[enter image description here][1]
CWD = os.getcwd()
# print(train_dir_file_list[0])
TRAINING_DATA_PATH = os.path.join(CWD, 'campaign_data/data/')
print(os.path.join(CWD, 'campaign_data/data/'))
IMAGE_SIZE = 720
IMG_SHAPE = (IMAGE_SIZE, IMAGE_SIZE, 1)
TRAIN_BATCH_SIZE = 32
train_datagen = tf.keras.preprocessing.image.ImageDataGenerator(
# rescale=1.0/127.5, # from various posts, if resnet50.preprocess_input is used, do not rescale
rotation_range=90.,
shear_range=0.2,
# for image data rescale as such
# rescale= 1.0/255,
zoom_range=[0.8,1.2],
horizontal_flip=True,
validation_split=0.2,
preprocessing_function=tf.keras.applications.resnet50.preprocess_input)
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# test_datagen = tf.keras.preprocessing.image.ImageDataGenerator(
# preprocessing_function=tf.keras.applications.resnet50.preprocess_input)
# Next we're going to take the images from our directory in batches and categorical classes:
#flow_from_directory
train_generator = train_datagen.flow_from_directory(TRAINING_DATA_PATH,
target_size=(IMAGE_SIZE, IMAGE_SIZE),
color_mode='rgb',
batch_size=TRAIN_BATCH_SIZE,
class_mode='categorical',
shuffle=True,
subset='training',
seed=42)
validation_generator = train_datagen.flow_from_directory(TRAINING_DATA_PATH,
target_size=(IMAGE_SIZE, IMAGE_SIZE),
color_mode='rgb',
batch_size=TRAIN_BATCH_SIZE,
class_mode='categorical',
shuffle=True,
subset='validation',
seed=42)
# confirm the scaling works
batchX, batchY = train_generator.next()
print('Batch shape=%s, min=%.3f, max=%.3f' % (batchX.shape, batchX.min(), batchX.max()))
labels = train_generator.class_indices
print('\nclass_indices = ', labels)
labels_dict = dict((v,k) for k, v in labels.items())
print('\nlabels_dict = ', labels_dict)
print(train_generator.filenames[0:5])
with open('labels_dict.json', 'w') as f:
json.dump(labels_dict, f)
METRICS = [
tf.keras.metrics.TruePositives(name='tp'),
tf.keras.metrics.FalsePositives(name='fp'),
tf.keras.metrics.TrueNegatives(name='tn'),
tf.keras.metrics.FalseNegatives(name='fn'),
tf.keras.metrics.BinaryAccuracy(name='accuracy'),
tf.keras.metrics.Precision(name='precision'),
tf.keras.metrics.Recall(name='recall'),
tf.keras.metrics.AUC(name='auc'),
tf.keras.metrics.AUC(name='prc', curve='PR') # precision-recall curve
]
model1.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=1e-4),
loss='categorical_crossentropy',
metrics=METRICS)
callbacks = [tf.keras.callbacks.TensorBoard(log_dir='./log/transer_learning_model', update_freq='batch'),
tf.keras.callbacks.EarlyStopping(patience=4)]
print('Training model...')
# print(train_generator)
history = model1.fit(train_generator,
steps_per_epoch=train_generator.samples//TRAIN_BATCH_SIZE,
epochs=25,
validation_data=validation_generator,
validation_steps=validation_generator.samples//TRAIN_BATCH_SIZE,
callbacks=callbacks)
Here is the exact error [1]: https://i.stack.imgur.com/cF2Sa.png
And at the bottom of the error is this text
Node: 'sequential_8/conv2d_34/Relu'
Fused conv implementation does not support grouped convolutions for now.
[[{{node sequential_8/conv2d_34/Relu}}]] [Op:__inference_train_function_70418]
I think you need to change the num_channels to 3 because the image has size 720x720x3.
Also you were able to train without the first layer since the input_shape does not need to be specified. It will just create {input_channel_size} * {filer_size} number of kernels.

Issue with shape on CNN with grayscale images

I made a CNN for classification with 10 classes.
input = 49000 grayscale pictures, all mixed (I mean training set and validation set)
train.csv contain the list of the images and their labels like this for example :
id,label
0.png,4
1.png,9
2.png,1
3.png,7
4.png,3
5.png,9
Here a part of the CNN:
traindf = pd.read_csv('train.csv', dtype=str)
datagen = ImageDataGenerator(rescale=1./255, validation_split=0.25, shear_range = 0.2, zoom_range = 0.2, horizontal_flip = True)
train_generator = datagen.flow_from_dataframe(dataframe = traindf,
directory='images',
target_size = (28, 28),
color_mode='grayscale',
x_col='id',
y_col='label',
subset='training',
batch_size = 32,
shuffle=True,
class_mode = 'categorical')
valid_generator = datagen.flow_from_dataframe(dataframe = traindf,
directory="images",
target_size=(28,28),
color_mode='grayscale',
x_col="id",
y_col="label",
subset="validation",
batch_size=32,
shuffle=True,
class_mode="categorical")
STEP_SIZE_TRAIN = train_generator.n//train_generator.batch_size
STEP_SIZE_VALID = valid_generator.n//valid_generator.batch_size
and the fit method:
classifier.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])
classifier.fit_generator(train_generator,
steps_per_epoch = STEP_SIZE_TRAIN,
epochs = 10,
validation_data = valid_generator,
validation_steps = STEP_SIZE_VALID)
for the sake of clarity I do not display the creation of the neural networks, but note that input_shape = (28,28,1)
Then I save the model:
filepath = './NumChar_model_01'
save_model(classifier, filepath)
In another program, I want to predict an image:
loaded_model = load_model(filepath,custom_objects=None, compile=True)
img = img.resize((28, 28))
img = image.img_to_array(img)
img = np.expand_dims(img, axis = 0)
result = loaded_model.predict(img)
And I got this error:
ValueError: Input 0 of layer sequential is incompatible with the layer: expected axis -1 of input shape to have value 1 but received input with shape [None, 28, 28, 3]
I know it's an issue with shape, but believe me, I read all the world topic about that...
I tried reshape on train_generator and valid_generator but it give me an error too ('DataFrameIterator' object has no attribute 'reshape')
SOLUTION:
img was gotten by
img = ImageGrab.grab((cx, cy, cx + cw, cy + ch))
It returns an RGB image, which throw the error. So I convert it into a grayscale image with:
img = img.convert('L')
and it works!

Is it same preprocessing method using Keras flow_from_directory and my method?

This is preprocessing using ImageDataGenerator and flow_from_directory to train my model in Keras.
train_datagen = ImageDataGenerator(rescale = 1./255)
train_dir = os.path.join(r'C:\Users\Admin\Desktop\deeplearning\ajou cat project resnet 18\data\trainset')
train_generator = train_datagen.flow_from_directory(train_dir, batch_size=16, target_size=(224, 224), color_mode='rgb')
# number of classes
K = 10
input_tensor = Input(shape=(224, 224, 3), dtype='float32', name='input')
#
# model architecture
#
x = conv1_layer(input_tensor)
x = conv2_layer(x)
x = conv3_layer(x)
x = conv4_layer(x)
x = conv5_layer(x)
x = GlobalAveragePooling2D()(x)
output_tensor = Dense(K, activation='softmax')(x)
resnet = Model(input_tensor, output_tensor)
resnet.compile(loss = 'categorical_crossentropy', optimizer = 'rmsprop', metrics = ['accuracy'])
resnet.fit(train_generator, steps_per_epoch = 11, epochs = 50)
And this is for preprocessing method I made to test my trained model with one picture.
target = (224, 224)
image = pilimg.open(r'C:\Users\Admin\Desktop\deeplearning\ajou cat project resnet 18\test\test.jpg')
image = image.resize(target)
image = img_to_array(image)
image = np.expand_dims(image, axis = 0)
image = image/255
Are they the same preprocessing?
Yes they are same but if you want to apply multiple processings and to be sure about the processing methods, ImageDataGenerator takes preprocessing_function argument.
You can define a preprocessing function and give it to the generator. Then while testing you can use the same function.

ValueError: Error when checking input: expected flatten_1_input to have shape (4, 4, 512) but got array with shape (128, 128, 3)

I have the following code for an image classification problem. And I keep running into this error:
ValueError: Error when checking input: expected flatten_1_input to have shape (4, 4, 512) but got array with shape (128, 128, 3)
I've seen a similar problem with someone who butchered their model loading process, but I'm not doing that. Here's my code:
def save_bottlebeck_features():`
datagen = ImageDataGenerator(rescale=1. / 255)
​
# build the VGG16 network
model = applications.VGG16(include_top=False, weights='imagenet')
​
generator = datagen.flow_from_directory(
train_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode=None,
shuffle=False)
bottleneck_features_train = model.predict_generator(
generator, nb_train_samples // batch_size)
np.save('bottleneck_features_train.npy', bottleneck_features_train)
​
generator = datagen.flow_from_directory(
validation_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode=None,
shuffle=False)
bottleneck_features_validation = model.predict_generator(
generator, nb_validation_samples // batch_size)
np.save('bottleneck_features_validation.npy',bottleneck_features_validation)
def train_top_model():
train_data = np.load('bottleneck_features_train.npy',"r+")
train_labels = np.array([0] * (nb_train_samples // 2) + [1] * (nb_train_samples // 2))
validation_data = np.load('bottleneck_features_validation.npy',"r+")
validation_labels = np.array([0] * (nb_validation_samples // 2) + [1] * (nb_validation_samples // 2))
model = Sequential()
model.add(Flatten(input_shape=train_data.shape[1:]))
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='rmsprop',
loss='binary_crossentropy', metrics=['accuracy'])
model.fit(train_data, train_labels,
epochs=epochs,
batch_size=batch_size,
validation_data=(validation_data, validation_labels))
model.save_weights(top_model_weights_path)
model.save('my_model.model')
save_bottlebeck_features()
train_top_model()
from keras.preprocessing import image
import numpy as np
from keras.models import load_model
import os
resnet_50 = load_model("my_model.model")
TEST_DIR = 'test/'
with open('better_score.csv','w') as f:
f.write('Id,Expected\n')
for x in range(1,7091):
mystr = "test_" + str(x) +".jpg"
path = os.path.join(TEST_DIR, mystr)
if (os.path.exists(path)):
img = image.load_img(path, target_size=(128, 128))
img = image.img_to_array(img)
img = np.expand_dims(img, axis=0)
model_out = resnet_50.predict(img/255)
f.write('{},{}\n'.format(mystr, model_out[0][0]))
I have printed the train_data shape and that is (2000, 4, 4, 512)
and validation_data shape is (800, 4, 4, 512). I am able to train my model, and save it. The problem occurs when I get to the line before last, when I'm trying to output my results to a csv file.
You first need to extract features of your input image using VGG model and then pass the features to resnet_50 model. So it would look like this:
model = applications.VGG16(include_top=False, weights='imagenet')
features = model.predict(img/255.0)
model_out = resnet_50.predict(features)
Don't forget that the input of your resent_50 model is the features of the image obtained by VGG model.

How to predict input image using trained model in Keras?

I trained a model to classify images from 2 classes and saved it using model.save(). Here is the code I used:
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras import backend as K
# dimensions of our images.
img_width, img_height = 320, 240
train_data_dir = 'data/train'
validation_data_dir = 'data/validation'
nb_train_samples = 200 #total
nb_validation_samples = 10 # total
epochs = 6
batch_size = 10
if K.image_data_format() == 'channels_first':
input_shape = (3, img_width, img_height)
else:
input_shape = (img_width, img_height, 3)
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=input_shape))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
# this is the augmentation configuration we will use for training
train_datagen = ImageDataGenerator(
rescale=1. / 255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
# this is the augmentation configuration we will use for testing:
# only rescaling
test_datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='binary')
validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='binary')
model.fit_generator(
train_generator,
steps_per_epoch=nb_train_samples // batch_size,
epochs=epochs,
validation_data=validation_generator,
validation_steps=5)
model.save('model.h5')
It successfully trained with 0.98 accuracy which is pretty good. To load and test this model on new images, I used the below code:
from keras.models import load_model
import cv2
import numpy as np
model = load_model('model.h5')
model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
img = cv2.imread('test.jpg')
img = cv2.resize(img,(320,240))
img = np.reshape(img,[1,320,240,3])
classes = model.predict_classes(img)
print classes
It outputs:
[[0]]
Why wouldn't it give out the actual name of the class and why [[0]]?
If someone is still struggling to make predictions on images, here is the optimized code to load the saved model and make predictions:
# Modify 'test1.jpg' and 'test2.jpg' to the images you want to predict on
from keras.models import load_model
from keras.preprocessing import image
import numpy as np
# dimensions of our images
img_width, img_height = 320, 240
# load the model we saved
model = load_model('model.h5')
model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
# predicting images
img = image.load_img('test1.jpg', target_size=(img_width, img_height))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
images = np.vstack([x])
classes = model.predict_classes(images, batch_size=10)
print classes
# predicting multiple images at once
img = image.load_img('test2.jpg', target_size=(img_width, img_height))
y = image.img_to_array(img)
y = np.expand_dims(y, axis=0)
# pass the list of multiple images np.vstack()
images = np.vstack([x, y])
classes = model.predict_classes(images, batch_size=10)
# print the classes, the images belong to
print classes
print classes[0]
print classes[0][0]
You can use model.predict() to predict the class of a single image as follows [doc]:
# load_model_sample.py
from keras.models import load_model
from keras.preprocessing import image
import matplotlib.pyplot as plt
import numpy as np
import os
def load_image(img_path, show=False):
img = image.load_img(img_path, target_size=(150, 150))
img_tensor = image.img_to_array(img) # (height, width, channels)
img_tensor = np.expand_dims(img_tensor, axis=0) # (1, height, width, channels), add a dimension because the model expects this shape: (batch_size, height, width, channels)
img_tensor /= 255. # imshow expects values in the range [0, 1]
if show:
plt.imshow(img_tensor[0])
plt.axis('off')
plt.show()
return img_tensor
if __name__ == "__main__":
# load model
model = load_model("model_aug.h5")
# image path
img_path = '/media/data/dogscats/test1/3867.jpg' # dog
#img_path = '/media/data/dogscats/test1/19.jpg' # cat
# load a single image
new_image = load_image(img_path)
# check prediction
pred = model.predict(new_image)
In this example, a image is loaded as a numpy array with shape (1, height, width, channels). Then, we load it into the model and predict its class, returned as a real value in the range [0, 1] (binary classification in this example).
keras predict_classes (docs) outputs A numpy array of class predictions. Which in your model case, the index of neuron of highest activation from your last(softmax) layer. [[0]] means that your model predicted that your test data is class 0. (usually you will be passing multiple image, and the result will look like [[0], [1], [1], [0]] )
You must convert your actual label (e.g. 'cancer', 'not cancer') into binary encoding (0 for 'cancer', 1 for 'not cancer') for binary classification. Then you will interpret your sequence output of [[0]] as having class label 'cancer'
That's because you're getting the numeric value associated with the class. For example if you have two classes cats and dogs, Keras will associate them numeric values 0 and 1. To get the mapping between your classes and their associated numeric value, you can use
>>> classes = train_generator.class_indices
>>> print(classes)
{'cats': 0, 'dogs': 1}
Now you know the mapping between your classes and indices. So now what you can do is
if classes[0][0] == 1:
prediction = 'dog'
else:
prediction = 'cat'
Forwarding the example by #ritiek, I'm a beginner in ML too, maybe this kind of formatting will help see the name instead of just class number.
images = np.vstack([x, y])
prediction = model.predict(images)
print(prediction)
i = 1
for things in prediction:
if(things == 0):
print('%d.It is cancer'%(i))
else:
print('%d.Not cancer'%(i))
i = i + 1

Categories