-
Star
(310)
You must be signed in to star a gist -
Fork
(139)
You must be signed in to fork a gist
-
-
Save fchollet/7eb39b44eb9e16e59632d25fb3119975 to your computer and use it in GitHub Desktop.
| '''This script goes along the blog post | |
| "Building powerful image classification models using very little data" | |
| from blog.keras.io. | |
| It uses data that can be downloaded at: | |
| https://www.kaggle.com/c/dogs-vs-cats/data | |
| In our setup, we: | |
| - created a data/ folder | |
| - created train/ and validation/ subfolders inside data/ | |
| - created cats/ and dogs/ subfolders inside train/ and validation/ | |
| - put the cat pictures index 0-999 in data/train/cats | |
| - put the cat pictures index 1000-1400 in data/validation/cats | |
| - put the dogs pictures index 12500-13499 in data/train/dogs | |
| - put the dog pictures index 13500-13900 in data/validation/dogs | |
| So that we have 1000 training examples for each class, and 400 validation examples for each class. | |
| In summary, this is our directory structure: | |
| ``` | |
| data/ | |
| train/ | |
| dogs/ | |
| dog001.jpg | |
| dog002.jpg | |
| ... | |
| cats/ | |
| cat001.jpg | |
| cat002.jpg | |
| ... | |
| validation/ | |
| dogs/ | |
| dog001.jpg | |
| dog002.jpg | |
| ... | |
| cats/ | |
| cat001.jpg | |
| cat002.jpg | |
| ... | |
| ``` | |
| ''' | |
| from keras import applications | |
| from keras.preprocessing.image import ImageDataGenerator | |
| from keras import optimizers | |
| from keras.models import Sequential | |
| from keras.layers import Dropout, Flatten, Dense | |
| # path to the model weights files. | |
| weights_path = '../keras/examples/vgg16_weights.h5' | |
| top_model_weights_path = 'fc_model.h5' | |
| # dimensions of our images. | |
| img_width, img_height = 150, 150 | |
| train_data_dir = 'cats_and_dogs_small/train' | |
| validation_data_dir = 'cats_and_dogs_small/validation' | |
| nb_train_samples = 2000 | |
| nb_validation_samples = 800 | |
| epochs = 50 | |
| batch_size = 16 | |
| # build the VGG16 network | |
| model = applications.VGG16(weights='imagenet', include_top=False) | |
| print('Model loaded.') | |
| # build a classifier model to put on top of the convolutional model | |
| top_model = Sequential() | |
| top_model.add(Flatten(input_shape=model.output_shape[1:])) | |
| top_model.add(Dense(256, activation='relu')) | |
| top_model.add(Dropout(0.5)) | |
| top_model.add(Dense(1, activation='sigmoid')) | |
| # note that it is necessary to start with a fully-trained | |
| # classifier, including the top classifier, | |
| # in order to successfully do fine-tuning | |
| top_model.load_weights(top_model_weights_path) | |
| # add the model on top of the convolutional base | |
| model.add(top_model) | |
| # set the first 25 layers (up to the last conv block) | |
| # to non-trainable (weights will not be updated) | |
| for layer in model.layers[:25]: | |
| layer.trainable = False | |
| # compile the model with a SGD/momentum optimizer | |
| # and a very slow learning rate. | |
| model.compile(loss='binary_crossentropy', | |
| optimizer=optimizers.SGD(lr=1e-4, momentum=0.9), | |
| metrics=['accuracy']) | |
| # prepare data augmentation configuration | |
| train_datagen = ImageDataGenerator( | |
| rescale=1. / 255, | |
| shear_range=0.2, | |
| zoom_range=0.2, | |
| horizontal_flip=True) | |
| test_datagen = ImageDataGenerator(rescale=1. / 255) | |
| train_generator = train_datagen.flow_from_directory( | |
| train_data_dir, | |
| target_size=(img_height, img_width), | |
| batch_size=batch_size, | |
| class_mode='binary') | |
| validation_generator = test_datagen.flow_from_directory( | |
| validation_data_dir, | |
| target_size=(img_height, img_width), | |
| batch_size=batch_size, | |
| class_mode='binary') | |
| # fine-tune the model | |
| model.fit_generator( | |
| train_generator, | |
| samples_per_epoch=nb_train_samples, | |
| epochs=epochs, | |
| validation_data=validation_generator, | |
| nb_val_samples=nb_validation_samples) |
Hi,
How do you load a single image from the drive and do a prediction on it using the model produced by this script?
Thanks in advance
is there a place from which we can download the fc_model.h5 ? i have a small dataset for eeg data can i apply the same method for them?
thanks in advance
Hello sir,
I have 60 images for three classes (20 images for each class), can you please help me modify your code to suite my data. I will be very grateful.
my email is [email protected]
Thanks
Fine tuned models' Prediction code
This codes were checked by myself. They all worked fine.
- If someone want to predict image classes in same model script where model were trained, here is the code :
img_width, img_height = 224, 224
batch_size = 1
datagen = ImageDataGenerator(rescale=1. / 255)
test_generator = datagen.flow_from_directory(
test_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode=None,
shuffle=False)
test_generator.reset()
pred= model.predict_generator(test_generator, steps = no_of_images/batch_size)
predicted_class_indices=np.argmax(pred, axis =1 )
labels = (train_generator.class_indices)
labels = dict((v, k) for k, v in labels.items())
predictions = [labels[k] for k in predicted_class_indices]
print(predicted_class_indices)
print (labels)
print (predictions)
This code is inspired by stack overflow answer. click here
- If someone want to predict image classes in different script (separate from training script file), here is the code :
from tensorflow.python.keras.preprocessing.image import ImageDataGenerator
import json
import os
from tensorflow.keras.models import model_from_json
#Just give below lines parameters
best_weights = 'path to .h5 weight file'
model_json = 'path to saved model json file'
test_dir = 'path to test images'
img_width, img_height = 224, 224
batch_size = 1
nb_img_samples = #no of testing images
with open(model_json, 'r') as json_file:
json_savedModel= json_file.read()
model = tf.keras.models.model_from_json(json_savedModel)
model.summary()
model.load_weights(best_weights)
datagen = ImageDataGenerator(rescale=1. / 255)
test_generator = datagen.flow_from_directory(
folder_path,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode=None,
shuffle=False)
test_generator.reset()
pred= model.predict_generator(test_generator, steps = nb_img_samples/batch_size)
predicted_class_indices=np.argmax(pred,axis=1)
labels = {'cats': 0, 'dogs': 1} #if you have more classes, just add like this in correct order where your training folder order.
labels = dict((v,k) for k,v in labels.items())
predictions = [labels[k] for k in predicted_class_indices]
print(predicted_class_indices)
print (labels)
print (predictions)
@allanchua101 only you have to edit this directorys path according to your drive file paths.
@lokoprof09 you are welcome
Hi, I get the following error when fine tuning with classifier_from_little_data_script_3.py . Any idea anyone please help.
Traceback (most recent call last):
File "classifier3.py", line 35, in
top_model.add(Dense(256, activation='relu'))
File "/home/zhang/ENTER/lib/python3.8/site-packages/tensorflow/python/training/tracking/base.py", line 456, in _method_wrapper
result = method(self, *args, **kwargs)
File "/home/zhang/ENTER/lib/python3.8/site-packages/tensorflow/python/keras/engine/sequential.py", line 213, in add
output_tensor = layer(self.outputs[0])
File "/home/zhang/ENTER/lib/python3.8/site-packages/tensorflow/python/keras/engine/base_layer.py", line 897, in call
self._maybe_build(inputs)
File "/home/zhang/ENTER/lib/python3.8/site-packages/tensorflow/python/keras/engine/base_layer.py", line 2416, in _maybe_build
self.build(input_shapes) # pylint:disable=not-callable
File "/home/zhang/ENTER/lib/python3.8/site-packages/tensorflow/python/keras/layers/core.py", line 1154, in build
raise ValueError('The last dimension of the inputs to Dense '
ValueError: The last dimension of the inputs to Dense should be defined. Found None.
@fchollet I would really appreciate it if you can help me,
I got the same problem, the following line causes this error:
flatten = Flatten(name='flatten')(vgg16_output)
I changed this line with using GlobalAveragePooling2D(), then it worked.
flatten = GlobalAveragePooling2D()(vgg16_output)
ValueError: The last dimension of the inputs to Dense should be defined. Found None.
Sorry, I got a error like that The shape of the input to "Flatten" is not fully defined (got (None, None, 512). Make sure to pass a complete "input_shape" or "batch_input_shape" argument to the first layer in your model.
I cannot find the weight file to download, '../keras/examples/vgg16_weights.h5' Thanks
@KennethYCK Hi! I am unable to understand how to get the input shape for my first layer. Can you help?
How to determine the optimal number of layers to freeze, as a function of:
Intuitively the more similar between the pretrained model and your dataset, the fewer layers you would need to
set_trainable = False.But it is not obvious exactly how many to set to False.
Here we're setting the first 25 layers (up to the last conv block) to non-trainable (weights will not be updated)
But I ask: why 25? Why not 20? Why not 35? How is this number determined?
One would expect a more algorithmic way to determine how many layers to set as non-trainable (even say as a percentage of the total number of layers)?