I have a trained model, which has been trained to recognize different documents, I got the dataset from http://www.cs.cmu.edu/~aharley/rvl-cdip/.
Below is how I built my model
import numpy as np
from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img
import pickle
from keras.optimizers import SGD
from keras.models import Sequential, save_model
from keras.layers import Dense, Dropout, Flatten, Activation
from keras.layers.convolutional import Conv2D, MaxPooling2D
# Set image information
channels = 1
height = 1000
width = 754
model = Sequential()
# Add a Conv2D layer with 32 nodes to the model
model.add(Conv2D(32, (3, 3), input_shape=(1000, 754, 3)))
# Add the reLU activation function to the model
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(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten()) # this converts our 3D feature maps to 1D feature vectors
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('relu'))
model.compile(loss='categorical_crossentropy', # sparse_categorical_crossentropy
# Adam(lr=.0001) SGD variation with learning rate
optimizer='adam',
metrics=['accuracy'])
# Image data generator to import iamges from data folder
datagen = ImageDataGenerator()
# Flowing images from folders sorting by labels, and generates batches of images
train_it = datagen.flow_from_directory(
"data/train/", batch_size=16, target_size=(height, width), shuffle=True, class_mode='categorical')
test_it = datagen.flow_from_directory(
"data/test/", batch_size=16, target_size=(height, width), shuffle=True, class_mode='categorical')
val_it = datagen.flow_from_directory(
"data/validate/", batch_size=16, target_size=(height, width), shuffle=True, class_mode='categorical')
history = model.fit(
train_it,
epochs=2,
batch_size=16,
validation_data=val_it,
shuffle=True,
steps_per_epoch=2000 // 16,
validation_steps=800 // 16)
save_model(model, "./ComplexDocumentModel")
model.save("my_model", save_format='h5')
As in the last line, I saved my model in an h5 format.
I am trying now to use that trained model to predict on a single image, to see on which category it belongs with the below script.
from keras.models import load_model
import cv2
import numpy as np
import keras
from keras.preprocessing import image
model = load_model('my_model')
# First try
def prepare(file):
img_array = cv2.imread(file, cv2.IMREAD_GRAYSCALE)
new_array = cv2.resize(img_array, (1000, 754))
return new_array.reshape(3, 1000, 754, 1)
# Second try
img = image.load_img(
"/home/user1/Desktop/Office/image-process/test/0000113760.tif")
img = image.img_to_array(img)
img = np.expand_dims(img, axis=-1)
prediction = model.predict(
[prepare("/home/user1/Desktop/Office/image-process/test/0000113760.tif")])
print(prediction)
I tried predicting the image in two ways, but both give the error
ValueError: Input 0 of layer sequential is incompatible with the layer: expected axis -1 of input shape to have value 3 but received input with shape (None, 762, 3, 1)
I have also tried opening the image with PIL and converting it to NumPy array, an approach found on google. Unfortunately no other answer, blog, or video tutorial that I found, helped me.
You are trying to feed a grayscale image to a network that expects an image with 3 channels. You can stack the last channel 3 times to have a compatible shape, but it is possible that the prediction will be poor:
def prepare(file):
img_array = cv2.imread(file, cv2.IMREAD_GRAYSCALE)
new_array = cv2.resize(img_array, (1000, 754)) # shape is (1000,754)
# converting to RGB
array_color = cv2.cvtColor(new_array, cv2.COLOR_GRAY2RGB) # shape is (1000,754,3)
array_with_batch_dim = np.expand_dims(array_color, axis=0) # shape is (1,1000,754,3)
return array_with_batch_dim
Another solution is to not convert your image to grayscale when you read it, by omitting the flag cv2.IMREAD_GRAYSCALE. The default behaviour of opencv is to load an image with 3 channels.
def prepare(file):
img_array = cv2.imread(file)
new_array = cv2.resize(img_array, (1000, 754)) # shape is (1000,754, 3)
# converting to RGB
array_with_batch_dim = np.expand_dims(new_array, axis=0) # shape is (1,1000,754,3)
return array_with_batch_dim
Note: Depending on your preprocessing, you might need to normalize your image between 0 and 1 by dividing it by 255 before feeding it to the network.
Related
Python image classification using keras
Error is ValueError: setting an array element with a sequence.
help please
from pathlib import Path
import keras
import numpy as npenter code here
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D
from keras.preprocessing import image
# Path to folders with training data
Empty_Morning = Path("images") / "EmptyMorning"
not_Empty_Morning_Path = Path("images") / "PeoplePlayingMorning"
images = []
labels = []
# Not Plastic Bottles Images
for img in not_Empty_Morning_Path.glob("*.jpg"):
# load the image from disk
img = image.load_img(img)
# convert the image to a numpy array
img_array = image.img_to_array(img)
# Add the image to the list of images
images.append(img_array)
# for each 'not plastic bottle image, the expected value should be 0
labels.append(0)
# for all plastic bottles images
for img in Empty_Morning.glob("*.jpg"):
# Load the image from disk
img = image.load_img(img)
# convert the image to an array
img_array = image.img_to_array(img)
# add image to the list of images
images.append(img_array)
# for all plastic bottles image (because it is another class), the expected value should be 1
labels.append(1)
x_train = np.array(images)
y_train = np.array(labels)
x_train = x_train.astype('float34')
x_train /= 255
y_train = keras.utils.to_categorical(y_train, 2)
# Create a model and add layers
model = Sequential()
model.add(Conv2D(32, (3, 3), padding="same", activation="relu", input_shape=(190, 270, 3)))
model.add(Conv2D(32, (3, 3), activation="relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.15))
model.add(Conv2D(64, (3, 3), padding="same", activation="relu"))
model.add(Conv2D(64, (3, 3), activation="relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.15))
model.add(Flatten())
model.add(Dense(512, activation="relu"))
model.add(Dropout(0.5))
model.add(Dense(2, activation="softmax"))
# Compile the Model
model.compile(
loss="categorical_crossentropy",
optimizer="adam",
metrics=['accuracy']
)
# Train the model
model.fit(
x_train,
y_train,
batch_size=32,
epochs=30,
validation_data=(x_train, y_train),
shuffle=True
)
# save neutral network structure
model_structure = model.to_json()
p = Path("model_structure.json")
p.write_text(model_structure)
# save neutral network's trained weights
model.save_weights("model_weights.h5")
If you are trying to change the data-types of elements in a list to float:
X_train = list(map(float, X_train))
I am trying to build a model that can classify if a picture has an animal or not, but I am having trouble with the data. I try to run my code:
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Conv2D
from tensorflow.keras.layers import Activation, MaxPooling2D, Dropout, Flatten, Reshape
from tensorflow.keras.optimizers import RMSprop
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from matplotlib import pyplot
from matplotlib.image import imread
import tensorflow as tf
import os
import numpy as np
base = '/home/jose/Programming/aiml/Data/naturewatch'
# Directory of all the pictures with an animal
critter = base + '/critter/'
# Directory of all the pictures without an animal
no_critter = base + '/no_critter/'
def load_data():
data = []
labels = []
for raw in os.listdir(critter):
# The array of values
image = np.array(imread(critter + raw))
data.append(image)
# 1 for yes critter
labels.append(1)
# image.shape = (1088, 1920, 3)
for raw in os.listdir(no_critter):
# load image pixels
image = np.array(imread(no_critter + raw))
data.append(image)
# 0 for no critter
labels.append(0)
# image.shape = (1088, 1920, 3)
data = np.array(data)
labels = np.array(labels)
return data, labels
data, labels = load_data()
# (2308,)
print(data.shape)
print(labels.shape)
X_train, X_test, y_train, y_test = train_test_split(data, labels, test_size=0.2, random_state=101)
print(X_train.shape) # (1846,)
print(X_test.shape)
print(y_train.shape) # (462,)
print(y_test.shape)
# Plot 9 images
for i, image in enumerate(X_train[:9]):
# define subplot
pyplot.subplot(330 + 1 + i)
pyplot.imshow(image)
print('image', image.shape, 'label', y_train[i])
# show the figure
pyplot.show()
dropout = 0.2
model = Sequential()
# Reshape image to a much smaller size
model.add(Reshape((272, 480, 3)))
model.add(Conv2D(32, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(dropout))
model.add(Conv2D(64, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(dropout))
model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(dropout))
model.add(Dense(2))
model.add(Activation('softmax'))
# initiate RMSprop optimizer
opt = RMSprop(lr=0.0001, decay=1e-6)
# Let's train the model using RMSprop
model.compile(loss='categorical_crossentropy',
optimizer=opt,
metrics=['accuracy'])
model.fit(X_train, y_train) # Causes error
But it raises the error: ValueError: Failed to convert a NumPy array to a Tensor (Unsupported object type numpy.ndarray). on the line model.fit(X_train, y_train). Any ideas on why this might be happening?
I've looked at this post Tensorflow - ValueError: Failed to convert a NumPy array to a Tensor (Unsupported object type float) but the solutions don't work for me, namely converting the train and test like this np.asarray(X).astype(np.float32) (which raises another error ValueError: setting an array element with a sequence.)
Since the error is complaining about not being able to convert an np.array into a tensor, I tried using the tf.convert_to_tensor() function but that results in another error: ValueError: Can't convert non-rectangular Python sequence to Tensor.
Does anyone know what exactly is happening here?
OK, I figured it out.
First of all, an image of size (1088, 1920) was wayyy to big. For testing purposes, I reshaped it to (68, 120) with cv2.resize() (I got rid of that Reshape() layer). That somehow fixed my dimension issues. For example, X_train was no longer (1846,) but (1846, 68, 120, 3).
Since I got rid of that Reshape() layer, I specified the first Conv2D layer with an input_size of (68, 120, 3), and now it works!
I learned to implement an image classifier from a code which i got from a post and it was very helpful,but i don't know how to predict on an image.I tried but its giving a Value Error.I am still a beginner
Keras Code:-
from __future__ import print_function
from keras.datasets import cifar10
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Convolution2D, MaxPooling2D
from keras.optimizers import SGD, Adam
from keras.utils import np_utils
import numpy as np
#seed = 7
#np.random.seed(seed)
batch_size = 50
nb_classes = 10
nb_epoch = 150
data_augmentation = False
# input image dimensions
img_rows, img_cols = 32, 32
# the CIFAR10 images are RGB
img_channels = 3
# the data, shuffled and split between train and test sets
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
print('X_train shape:', X_train.shape)
print(X_train.shape[0], 'train samples')
print(X_test.shape[0], 'test samples')
# convert class vectors to binary class matrices
Y_train = np_utils.to_categorical(y_train, nb_classes)
Y_test = np_utils.to_categorical(y_test, nb_classes)
model = Sequential()
model.add(Convolution2D(32, 3, 3, border_mode='same',
input_shape=X_train.shape[1:]))
model.add(Activation('relu'))
model.add(Convolution2D(32, 3, 3, border_mode='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Convolution2D(64, 3, 3, border_mode='same'))
model.add(Activation('relu'))
model.add(Convolution2D(64, 3, 3, border_mode='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(nb_classes))
model.add(Activation('softmax'))
# let's train the model using SGD + momentum (how original).
#sgd = SGD(lr=0.001, decay=1e-6, momentum=0.9, nesterov=True)
sgd= Adam(lr=0.0001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)
model.compile(loss='categorical_crossentropy',
optimizer=sgd,
metrics=['accuracy'])
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
X_train /= 255
X_test /= 255
if not data_augmentation:
print('Not using data augmentation.')
model.fit(X_train, Y_train,
batch_size=batch_size,
nb_epoch=nb_epoch,
validation_data=(X_test, Y_test),
shuffle=True)
else:
print('Using real-time data augmentation.')
# this will do preprocessing and realtime data augmentation
datagen = ImageDataGenerator(
featurewise_center=False, # set input mean to 0 over the dataset
samplewise_center=False, # set each sample mean to 0
featurewise_std_normalization=False, # divide inputs by std of the dataset
samplewise_std_normalization=False, # divide each input by its std
zca_whitening=False, # apply ZCA whitening
rotation_range=0, # randomly rotate images in the range (degrees, 0 to 180)
width_shift_range=0.1, # randomly shift images horizontally (fraction of total width)
height_shift_range=0.1, # randomly shift images vertically (fraction of total height)
horizontal_flip=True, # randomly flip images
vertical_flip=False) # randomly flip images
# compute quantities required for featurewise normalization
# (std, mean, and principal components if ZCA whitening is applied)
datagen.fit(X_train)
# fit the model on the batches generated by datagen.flow()
model.fit_generator(datagen.flow(X_train, Y_train,
batch_size=batch_size),
samples_per_epoch=X_train.shape[0],
nb_epoch=nb_epoch,
validation_data=(X_test, Y_test))
model.save('CIFAR10.h5')
My Prediction Code:-
from __future__ import print_function
from keras.models import load_model
from keras.utils import np_utils
import numpy as np
import cv2
img_rows, img_cols = 32, 32
model = load_model('CIFAR10.h5')
img = cv2.imread('D:/Study_Material/Python_3_Tutorial/PythonScripts/Machine_Learning/Project/Images/Deer.jpg')
img = cv2.resize(img,(img_rows,img_cols))
Image = np.array(img)
print(model.predict(Image))
Error:-
Warning (from warnings module):
File "C:\Users\Na462\AppData\Local\Programs\Python\Python35\lib\site-packages\h5py\__init__.py", line 36
from ._conv import register_converters as _register_converters
FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.
Using TensorFlow backend.
Traceback (most recent call last):
File "D:\Study_Material\Python_3_Tutorial\PythonScripts\Machine_Learning\Project\Keras(Prediction).py", line 12, in <module>
print(model.predict(Image))
File "C:\Users\Na462\AppData\Local\Programs\Python\Python35\lib\site-packages\keras\models.py", line 1025, in predict
steps=steps)
File "C:\Users\Na462\AppData\Local\Programs\Python\Python35\lib\site-packages\keras\engine\training.py", line 1817, in predict
check_batch_axis=False)
File "C:\Users\Na462\AppData\Local\Programs\Python\Python35\lib\site-packages\keras\engine\training.py", line 113, in _standardize_input_data
'with shape ' + str(data_shape))
ValueError: Error when checking : expected conv2d_1_input to have 4 dimensions, but got array with shape (32, 32, 3)
Please Tell me the right way to Predict in Keras so that i can implement it on different test cases.
The error you are getting is because all the frameworks assume an image input is a batch of images making it a 4d tensor, instead of one image (3d tensor). To just do single image batches, expand the input to be of size (1, 32, 32, 3), the 1 in the beginning being the batch size of 1.
I do not know keras specifically very well, but since you are passing in a numpy array, you can modify your 'Image' object like so (see second to last line):
img_rows, img_cols = 32, 32
model = load_model('CIFAR10.h5')
img = cv2.imread('D:/Study_Material/Python_3_Tutorial/PythonScripts/Machine_Learning/Project/Images/Deer.jpg')
img = cv2.resize(img,(img_rows,img_cols))
Image = np.expand_dims(np.array(img), axis=0)
print(model.predict(Image))
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
I am working through this great tutorial on creating an image classifier using Keras. Once I have trained the model, I save it to a file and then later reload it into a model in a test script shown below.
I get the following exception when I evaluate the model using a new, never-before-seen image:
Error:
Traceback (most recent call last):
File "test_classifier.py", line 48, in <module>
score = model.evaluate(x, y, batch_size=16)
File "/Library/Python/2.7/site-packages/keras/models.py", line 655, in evaluate
sample_weight=sample_weight)
File "/Library/Python/2.7/site-packages/keras/engine/training.py", line 1131, in evaluate
batch_size=batch_size)
File "/Library/Python/2.7/site-packages/keras/engine/training.py", line 959, in _standardize_user_data
exception_prefix='model input')
File "/Library/Python/2.7/site-packages/keras/engine/training.py", line 108, in standardize_input_data
str(array.shape))
Exception: Error when checking model input: expected convolution2d_input_1 to have shape (None, 3, 150, 150) but got array with shape (1, 3, 150, 198)`
Is the problem with the model that I have trained or with how I am invoking the evaluate method?
Code:
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Convolution2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img
import numpy as np
img_width, img_height = 150, 150
train_data_dir = 'data/train'
validation_data_dir = 'data/validation'
nb_train_samples = 2000
nb_validation_samples = 800
nb_epoch = 5
model = Sequential()
model.add(Convolution2D(32, 3, 3, input_shape=(3, img_width, img_height)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Convolution2D(32, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Convolution2D(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'])
model.load_weights('first_try.h5')
img = load_img('data/test2/ferrari.jpeg')
x = img_to_array(img) # this is a Numpy array with shape (3, 150, 150)
x = x.reshape( (1,) + x.shape ) # this is a Numpy array with shape (1, 3, 150, 150)
y = np.array([0])
score = model.evaluate(x, y, batch_size=16)`
The problem is due to wrong size of test images. For me,
train_datagen.flow_from_directory(
'C:\\Users\\...\\train', # this is the target directory
target_size=(150, 150), # all images will be resized to 150x150
batch_size=32,
class_mode='binary')
was not working properly. So I used a matlab command to resize all the test images and it worked fine
The issue was two-fold:
The test image was the wrong size. It was 150 x 198, and needed to be 150 x 150.
I had to change the dense layer from model.add(Dense(10)) to model.add(Dense(1)).
I don't yet understand how to get the model to give me the prediction, but at least now, the model evaluation runs.
I have same problem and use this function:
All images in target folder (.jpg and .png) will be resized to height and width. And divided by 255. Plus added 1 more dimension (required input shape).
from scipy import misc
import os
def readImagesAsNumpyArrays(targetPath, i_height, i_width):
files = os.listdir(targetPath)
npList = list()
for file in files:
if ".jpg" or ".png" in str(file):
path = os.path.join(targetPath, file)
img = misc.imread(path)
img = misc.imresize(img, (i_height, i_width))
img = img * (1. / 255)
img = img[None, :, :,: ]
npList.append(img)
return npList