How can I use a GPU with Keras? - python

My problem is that I am trying to train a convolution neural network with Keras in google colab that is able to distinguish between dogs and cats, but at the time of passing to the training phase my model takes a long time to train and I wanted to know how I can use the GPU in the right way in order to make the training time take less time.
from keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
from keras.preprocessing.image import ImageDataGenerator
import tensorflow as tf
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('/content/drive/MyDrive/Colab Notebooks/files/dataset_CNN/training_set',
target_size = (64, 64),
batch_size = 32,
class_mode = 'binary')
test_set = test_datagen.flow_from_directory('/content/drive/MyDrive/Colab Notebooks/files/dataset_CNN/test_set',
target_size = (64, 64),
batch_size = 32,
class_mode = 'binary')
device_name = tf.test.gpu_device_name()
if device_name != '/device:GPU:0':
raise SystemError('GPU device not found')
with tf.device('/device:GPU:0'):#I tried to put this part that I found by researching on the internet
classifier = Sequential()
classifier.add(Conv2D(32, (3, 3), input_shape = (64, 64, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
classifier.add(Conv2D(32, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
classifier.add(Flatten())
classifier.add(Dense(units = 128, activation = 'relu'))
classifier.add(Dense(units = 1, activation = 'sigmoid'))
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
classifier.fit(training_set,
steps_per_epoch = 8000,
epochs = 25,
validation_data = test_set,
validation_steps = 2000)
Previously, I did not put this part of the code "with tf.device('/device:GPU:0')", I saw this part of the code in an example on the internet, but it is still slow when training. I already checked the Available GPUs using:
device_name = tf.test.gpu_device_name()
if device_name != '/device:GPU:0':
raise SystemError('GPU device not found')

To Select GPU in Google Colab -Select Edit - Notebook Setting - Hardware accelerator - GPU - Save
ImageDataGenerator is not recommended for new code. Instead you can use these augmentation features directly through layers in model training as below:
classifier = tf.keras.Sequential([
#data augmention layers
layers.Resizing(IMG_SIZE, IMG_SIZE),
layers.Rescaling(1./255),
layers.RandomFlip("horizontal"),
layers.RandomZoom(0.1),
#model building layers
layers.Conv2D(32, (3, 3), input_shape = (64, 64, 3), activation = 'relu'),
layers.MaxPooling2D(pool_size = (2, 2)),
layers.Conv2D(32, (3, 3), activation = 'relu'),
layers.MaxPooling2D(pool_size = (2, 2)),
layers.Flatten(),
layers.Dense(units = 128, activation = 'relu'),
layers.Dense(units = 1, activation = 'sigmoid')
])
Also, you should use image_dataset_from_directory to import the images dataset which generates a tf.data.Dataset from image files in a directory. Please refer to this gist of replicated code.
Note:
fit() automatically calculates Steps_per_epoch from the training set as per batch_size.Steps_per_epoch = len(training_dataset)//batch_size

Related

Image classification in python always getting same matching score [duplicate]

I want to predict the kind of 2 diseases but I get results as binary (like 1.0 and 0.0). How can I get accuracy of these (like 0.7213)?
Training code:
from keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
# Intialising the CNN
classifier = Sequential()
# Step 1 - Convolution
classifier.add(Conv2D(32, (3, 3), input_shape = (64, 64, 3), activation = 'relu'))
# Step 2 - Pooling
classifier.add(MaxPooling2D(pool_size = (2, 2)))
# Adding a second convolutional layer
classifier.add(Conv2D(32, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
# Step 3 - Flattening
classifier.add(Flatten())
# Step 4 - Full connection
classifier.add(Dense(units = 128, activation = 'relu'))
classifier.add(Dense(units = 1, activation = 'sigmoid'))
# Compiling the CNN
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
# Part 2 - Fitting the CNN to the images
import h5py
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('training_set',
target_size = (64, 64),
batch_size = 32,
class_mode = 'binary')
test_set = test_datagen.flow_from_directory('test_set',
target_size = (64, 64),
batch_size = 32,
class_mode = 'binary')
classifier.fit_generator(training_set,
steps_per_epoch = 100,
epochs = 1,
validation_data = test_set,
validation_steps = 100)
Single prediction code:
import numpy as np
from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img,image
test_image = image.load_img('path_to_image', target_size = (64, 64))
test_image = image.img_to_array(test_image)
test_image = np.expand_dims(test_image, axis = 0)
result = classifier.predict(test_image)
print(result[0][0]) # Prints 1.0 or 0.0
# I want accuracy rate for this prediction like 0.7213
The file structures is like:
test_set
benigne
benigne_images
melignant
melignant_images
training set
Training set structure is also the same as test set.
Update: As you clarified in the comments, you are looking for the probabilities of each class given one single test sample. Therefore you can use predict method. However, note that you must first preprocess the image the same way you have done in the training phase:
test_image /= 255.0
result = classifier.predict(test_image)
The result would be the probability of the given image belonging to class one (i.e. positive class).
If you have a generator for test data, then you can use evaluate_generator() to get the loss as well as the accuracy (or any other metric you have set) of the model on the test data.
For example, right after fitting the model, i.e. using fit_generator, you can use evaluate_generator on your test data generator, i.e. test_set:
loss, acc = evaluate_generator(test_set)

Loaded Keras model from .h5 file is not predicting correctly like the original one after training

I am new to ML and I am trying to play a little with this tutorial:
https://medium.com/#ferhat00/deep-learning-with-keras-classifying-cats-and-dogs-part-2-21b3b25bbe5c . Anyway, the CNN seems to work only in the case I don't save it in an h5 file after the training. More precisely:
from keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
from keras.layers import Dropout
from keras import optimizers
classifier = Sequential()
classifier.add(Conv2D(32, (3, 3), input_shape = (128, 128, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
classifier.add(Conv2D(32, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
classifier.add(Conv2D(64, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
classifier.add(Flatten())
classifier.add(Dense(units = 64, activation = 'relu'))
classifier.add(Dropout(0.5))
classifier.add(Dense(units = 1, activation = 'sigmoid'))
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
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('PetImages/training_set',
target_size = (128, 128),
batch_size = 32,
class_mode = 'binary')
test_set = test_datagen.flow_from_directory('PetImages/test_set',
target_size = (128, 128),
batch_size = 32,
class_mode = 'binary')
history = classifier.fit_generator(training_set,
steps_per_epoch = 8000/32,
epochs = 30,
validation_data = test_set,
validation_steps = 2000/32, workers=12, max_q_size=100)
///////////////////////////////////////
classifier.save("cnnPetsModel.h5")
print("saved model to disk")
///////////////////////////////////////
from keras.preprocessing import image
from keras.applications.vgg16 import preprocess_input
import numpy as np
img_path = 'PetImages/test_set/Dog/5000.jpg'
img = image.load_img(img_path, target_size=(128, 128))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
preds = classifier.predict(x)
training_set.class_indices
print(preds)
if preds[0][0] == 1:
prediction = 'dog'
else:
prediction = 'cat'
print(prediction)
img_path = 'PetImages/test_set/Cat/5000.jpg'
img = image.load_img(img_path, target_size=(128, 128))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
preds = classifier.predict(x)
training_set.class_indices
print(preds)
if preds[0][0] == 1:
prediction = 'dog'
else:
prediction = 'cat'
print(prediction)
If I remove the code between "////////", the two images are predicted correctly, while it becomes always "cat" in the case I save the model. Why this happens? I am only saving parameters, structure etc. in a file, at all...
Thanks in advance!
EDIT:
I moved the saving at the end of the code and the model predicts correctly. Anyway, if such a model is loaded from another python file and then used for predict(x) like above, it results in an untrained one which always returns "cat".

Keras returns binary results

I want to predict the kind of 2 diseases but I get results as binary (like 1.0 and 0.0). How can I get accuracy of these (like 0.7213)?
Training code:
from keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
# Intialising the CNN
classifier = Sequential()
# Step 1 - Convolution
classifier.add(Conv2D(32, (3, 3), input_shape = (64, 64, 3), activation = 'relu'))
# Step 2 - Pooling
classifier.add(MaxPooling2D(pool_size = (2, 2)))
# Adding a second convolutional layer
classifier.add(Conv2D(32, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
# Step 3 - Flattening
classifier.add(Flatten())
# Step 4 - Full connection
classifier.add(Dense(units = 128, activation = 'relu'))
classifier.add(Dense(units = 1, activation = 'sigmoid'))
# Compiling the CNN
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
# Part 2 - Fitting the CNN to the images
import h5py
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('training_set',
target_size = (64, 64),
batch_size = 32,
class_mode = 'binary')
test_set = test_datagen.flow_from_directory('test_set',
target_size = (64, 64),
batch_size = 32,
class_mode = 'binary')
classifier.fit_generator(training_set,
steps_per_epoch = 100,
epochs = 1,
validation_data = test_set,
validation_steps = 100)
Single prediction code:
import numpy as np
from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img,image
test_image = image.load_img('path_to_image', target_size = (64, 64))
test_image = image.img_to_array(test_image)
test_image = np.expand_dims(test_image, axis = 0)
result = classifier.predict(test_image)
print(result[0][0]) # Prints 1.0 or 0.0
# I want accuracy rate for this prediction like 0.7213
The file structures is like:
test_set
benigne
benigne_images
melignant
melignant_images
training set
Training set structure is also the same as test set.
Update: As you clarified in the comments, you are looking for the probabilities of each class given one single test sample. Therefore you can use predict method. However, note that you must first preprocess the image the same way you have done in the training phase:
test_image /= 255.0
result = classifier.predict(test_image)
The result would be the probability of the given image belonging to class one (i.e. positive class).
If you have a generator for test data, then you can use evaluate_generator() to get the loss as well as the accuracy (or any other metric you have set) of the model on the test data.
For example, right after fitting the model, i.e. using fit_generator, you can use evaluate_generator on your test data generator, i.e. test_set:
loss, acc = evaluate_generator(test_set)

Exporting keras model into tflite

I am trying to combine this two examples and create the tflite file for my android app.
https://medium.com/nybles/create-your-first-image-recognition-classifier-using-cnn-keras-and-tensorflow-backend-6eaab98d14dd
https://medium.com/#xianbao.qian/convert-keras-model-to-tflite-e2bdf28ee2d2
This is my code:
# Part 1 - Building the CNN
# Importing the Keras libraries and packages
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
import tensorflow as tf
from keras.models import load_model
# Initialising the CNN
classifier = Sequential()
# Step 1 - Convolution
classifier.add(Convolution2D(32, 3, 3, input_shape = (64, 64, 3), activation = 'relu'))
# Step 2 - Pooling
classifier.add(MaxPooling2D(pool_size = (2, 2)))
# Adding a second convolutional layer
classifier.add(Convolution2D(32, 3, 3, activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
# Step 3 - Flattening
classifier.add(Flatten())
# Step 4 - Full connection
classifier.add(Dense(output_dim = 128, activation = 'relu'))
classifier.add(Dense(output_dim = 1, activation = 'sigmoid'))
# Compiling the CNN
classifier.compile(optimizer = 'adam', loss = 'binary_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 = 'binary')
test_set = test_datagen.flow_from_directory('dataset/test_set',
target_size = (64, 64),
batch_size = 32,
class_mode = 'binary')
classifier.fit_generator(training_set,
samples_per_epoch = 80,
nb_epoch = 1,
validation_data = test_set,
nb_val_samples = 20)
output_names = [node.op.name for node in classifier.outputs]
sess = tf.keras.backend.get_session()
frozen_def = tf.graph_util.convert_variables_to_constants(sess, sess.graph_def, output_names)
tflite_model = tf.contrib.lite.toco_convert(frozen_def, [inputs], output_names)
with tf.gfile.GFile(tflite_graph, 'wb') as f:
f.write(tflite_model)
And at this line:
frozen_def = tf.graph_util.convert_variables_to_constants(sess, sess.graph_def, output_names)
I got an exception:
tensorflow.python.framework.errors_impl.FailedPreconditionError: Attempting to use uninitialized value conv2d_1/bias
[[Node: _retval_conv2d_1/bias_0_0 = _Retval[T=DT_FLOAT, index=0, _device="/job:localhost/replica:0/task:0/device:CPU:0"](conv2d_1/bias)]]
I am a beginner in the machine learning and absolutely have no idea what is this error about :-(
Can somebody explain to me what is wrong?
All that I need is processed several folders with many pics and make it possible to predict the relations of the new coming pictures to the certain folder.
Thank you.
It is possible to directly convert a keras-model to .tflite using the tf.lite.TFLiteConverter.from_session function. Place the following code after fit_generator to export it (tested with tensorflow 1.3.1)
with tf.keras.backend.get_session() as sess:
sess.run(tf.global_variables_initializer())
converter = tf.lite.TFLiteConverter.from_session(sess, model.inputs, model.outputs)
tflite_model = converter.convert()
with open("model.tflite", "wb") as f:
f.write(tflite_model)
A bit late to the party but here's how you do it:
converter = tf.lite.TFLiteConverter.from_keras_model(model)
tflite_model = converter.convert()
Source: https://www.tensorflow.org/lite/convert/python_api

How to predict from saved model in Keras ?

I have trained an image classifier using keras and it gave a very good accuracy. I've saved the model using the save()and saved it using the h5 format. How can I make a prediction using the model?
The code is:
from keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
classifier = Sequential()
classifier.add(Conv2D(32, (3, 3), input_shape = (64, 64, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
classifier.add(Conv2D(32, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
classifier.add(Flatten())
classifier.add(Dense(units = 128, activation = 'relu'))
classifier.add(Dense(units = 1, activation = 'sigmoid'))
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
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('training_set',
target_size = (64, 64),
batch_size = 32,
class_mode = 'binary')
test_set = test_datagen.flow_from_directory('test_set',
target_size = (64, 64),
batch_size = 32,
class_mode = 'binary')
classifier.fit_generator(training_set,
steps_per_epoch = 8000,
epochs = 5,
validation_data = test_set,
validation_steps = 2000)
classifier.save('classifier.h5')
Thanks in Advance..!!
The first step is to import your model using load_model method.
from keras.models import load_model
model = load_model('my_model.h5')
Then you have to compile the model in order to make predictions.
model.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
Now you can predict results for a new entry image.
from keras.preprocessing import image
test_image = image.load_img(imagePath, target_size = (64, 64))
test_image = image.img_to_array(test_image)
test_image = np.expand_dims(test_image, axis = 0)
#predict the result
result = model.predict(test_image)

Categories