Created
June 22, 2017 07:25
-
-
Save ragvri/6a28b08b9ad844bc66b90db7d7cebb17 to your computer and use it in GitHub Desktop.
Dog/cat classifier including prediction on a new image
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Using the concept of transfer learning to improve accuracy. VGG16 is a CNN that has been trained on ImageNet data. | |
We first load this model upto the first fully connected layer. | |
""" | |
import numpy as np | |
from keras.preprocessing.image import ImageDataGenerator, img_to_array, load_img | |
from keras.models import Sequential | |
from keras.layers import Dense, Flatten, Dropout | |
from keras import applications | |
img_width, img_ht = 150, 150 | |
top_model_wt_path = "bottleneck_fc_model.h5" | |
train_dir = "/home/raghav/Desktop/data_image/train" | |
validation_dir = "/home/raghav/Desktop/data_image/validate" | |
test_dir = "/home/raghav/Desktop/data_image/test" | |
no_train_samples = 2000 | |
no_validation_samples = 800 | |
epochs = 50 | |
batch_size = 16 | |
def save_bottleneck_features(): | |
datagen = ImageDataGenerator(rescale=1 / 255) | |
# build the vgg16 model | |
model = applications.VGG16(include_top=False, weights='imagenet') | |
generator = datagen.flow_from_directory(train_dir, target_size=(img_width, img_ht), shuffle=False, class_mode=None, | |
batch_size=batch_size) # class_mode=None means our data will only yield | |
# batches of data, no labels, shuffle=False means our data will be in order so first 1000 images will be cats and | |
# next 1000 dogs | |
# generates predication for a generator. Steps: total no of batches. Returns a numpy array of predictions | |
bottleneck_features_train = model.predict_generator(generator=generator, steps=no_train_samples // batch_size) | |
# saves an array to a binary file | |
np.save(file="bottleneck_features_train.npy", arr=bottleneck_features_train) | |
generator = datagen.flow_from_directory(validation_dir, target_size=(img_width, img_ht), batch_size=batch_size, | |
class_mode=None, shuffle=False) | |
bottleneck_features_validation = model.predict_generator(generator, no_validation_samples // batch_size) | |
np.save(file="bottleneck_features_validate.npy", arr=bottleneck_features_validation) | |
def train_top_model(): | |
train_data = np.load(file="bottleneck_features_train.npy") | |
train_labels = np.array([0] * (no_train_samples // 2) + [1] * (no_train_samples // 2)) | |
validation_data = np.load(file="bottleneck_features_validate.npy") | |
validation_labels = np.array([0] * (no_validation_samples // 2) + [1] * (no_validation_samples // 2)) | |
model = Sequential() | |
model.add(Flatten(input_shape=train_data.shape[1:])) # don't need to tell batch size in input shape | |
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_wt_path) | |
def predict_image_class(file): | |
model = applications.VGG16(include_top=False, weights='imagenet') | |
x = load_img(file, target_size=(img_width,img_ht)) | |
x = img_to_array(x) | |
x = np.expand_dims(x, axis=0) | |
array = model.predict(x) | |
model = Sequential() | |
model.add(Flatten(input_shape=array.shape[1:])) | |
model.add(Dense(256, activation='relu')) | |
model.add(Dropout(0.5)) | |
model.add(Dense(1, activation='sigmoid')) | |
model.load_weights(top_model_wt_path) | |
class_predicted = model.predict_classes(array) | |
if class_predicted==1: | |
print("dogs") | |
else: | |
print("cat") | |
""" | |
save_bottleneck_features() | |
train_top_model() | |
""" | |
predict_image_class(test_dir + "/cat/cat.3120.jpg") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hey @ragvri :)
I have 2 questions for this code and i hope that you could be of assistance!
I have 5 classes in my problem, and hence i made the necessary changes, including changing 'binary' to categorical and readjusting the labels correctly (example: [1,0,0,0,0] for 1 class and [0,1,0,0,0] for another...). The training and validation accuracies seem to be good as well (89% more or less).
1- how can i rearrange the class predictions for the 5 classes?
2- how can i get the predictions of several images at the same time? i wrote the following code for this particular matter and go only a 30% testing accuracy. So i am wondering whether or not what i coded makes sense :)
import numpy as np
import cv2
from keras.models import load_model
from keras.preprocessing.image import img_to_array, load_img
bottleneck_features_testing = np.load(open('bottleneck_features_testing_5_classes.npy', "rb"))
model2 = load_model('my_model_5_classes.h5')
model2.compile(optimizer='adam',
loss='categorical_crossentropy', metrics=['accuracy'])
testing_labels = np.array([1,0,0,0,0] * 1523 + [0,1,0,0,0] * 1343 + [0,0,1,0,0] * 1557 + [0,0,0,1,0] * 1365 + [0,0,0,0,1] * 5492)
testing_labels = testing_labels.reshape(11280,5)
bottleneck_features_testing_ev = model2.evaluate(bottleneck_features_testing, testing_labels, verbose=0)
print(bottleneck_features_testing_ev)
note that the numbers in the labels refer to how many samples i have for each class in my testing database.
Thank you for your time :)
Maher