Error on number of arguments for keras fit_generator - python

I am having difficulty debugging, running this training model and then saving the weights.
The code:
#Part 1 - Building the CNN
#Importing the Keras libraries and packages
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
#Initialising the CNN
classifier = Sequential()
#Step 1 - Convolution
#classifier.add(Conv2D(32, (3, 3), input_shape = (64, 64, 3), activation = 'relu'))
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(128, activation = 'relu'))
classifier.add(Dense(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('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,
validation_data = test_set,
validation_steps = 2000,
steps_per_epoch = 8000,
epochs = 25)
classifier.save("weights.h5")
Problem #1: I am getting the following error:
Found 8005 images belonging to 2 classes.
Found 2023 images belonging to 2 classes.
-----------------------------------------------------------------------TypeError Traceback (most recent call last) in ()
58 validation_steps = 2000,
59 steps_per_epoch = 8000,
---> 60 epochs = 25)
61
62
TypeError: fit_generator() takes at least 4 arguments (3 given)
Problem #2: I want to save the trained weights so that I don't need to keep running it over and over again.
I ran classifier.save("weights.h5") separately, and an empty file (since it's unable to train) was created with the below message. How can I save the model weights?
Error! /Users/xx/xx/xx/cnn_050518/model_weights.h5 is not UTF-8 encoded Saving disabled. See Console for more details.
versions of tools used (by entering print tool.version) keras: 1.1.1 tensorflow: 0.11.orc2 python:2.7 Macbook version 10.13.2

Related

How to use a trained model on new inputs?

I have created a CNN model that can be used to differentiate DOGS and CATS. During the training process my model was showing an training accuracy of 99% and testing accuracy of 81% by the end of 4/25 epoch.
Is this normal? or is there any problem that might occur after completion of all the epoch's?
So I need to use this CNN model to my new inputs that do not belong to my training of test set. How do I use my model to predict some new photos?
I have not used classifier.save( ), so after the training can I just use that command so that model gets saved? or do I have to recompile everything with clssifier.save() at the end?
# Part 1 - Building the CNN
# Importing the Keras libraries and packages
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
# Initialising 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
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,
steps_per_epoch = 8000,
epochs = 25,
validation_data = test_set,
validation_steps = 2000)
The model has a save method that exports the architecture and training configuration of the model to a file which can be later extracted and used. The documentation for the same can be found here.
After importing the model, you can use the model on any data sets that you want to. About the accuracy of the model, it is possible to achieve the same. There is still a huge difference between the train and test accuracy so at the moment it is over-fitting the data. Also, try to randomize the data and train using them to make sure it is not an exceptional case.

Bounding box prediction on CNN multiple class image classification in python

I have the training set and test of 4 types of specific objects. I also have the bound box conditions / Area of interest coordinates (x,y,w,h) in csv format.
Main aim of the project is to predict the class of test image along with bounding box around the area of interest along with printing the name of the class on the image.
I have applied CNN model based on keras library. which classifies the given images of test set. what should i change in order to predict the bounding box coordinates of the given test image ?
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
#CNN initializing
classifier= Sequential()
#convolutional layer
classifier.add(Convolution2D(filters = 32, kernel_size=(3,3), data_format= "channels_last", input_shape=(64, 64, 3), activation="relu"))
#Pooling
classifier.add(MaxPooling2D(pool_size=(2,2)))
#addition of second convolutional layer
classifier.add(Convolution2D(filters = 32, kernel_size=(3,3), data_format= "channels_last", activation="relu"))
classifier.add(MaxPooling2D(pool_size=(2,2)))
#step 3 - FLatttening
classifier.add(Flatten())
#step 4 - Full connection layer
classifier.add(Dense(128, input_dim = 11, activation = 'relu'))
#output layer
classifier.add(Dense(units = 4, activation = 'sigmoid'))
#compiling the CNN
classifier.compile(optimizer='adam',loss="categorical_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/Train',
target_size = (64, 64),
batch_size = 32,
class_mode = 'categorical')
test_set = test_datagen.flow_from_directory('dataset/Test',
target_size = (64, 64),
batch_size = 32,
class_mode = 'categorical')
classifier.fit_generator(training_set,
steps_per_epoch =4286/32,
epochs = 25,
validation_data = test_set,
validation_steps = 44/32)
The task you described is object detection, which usually requires a more complicated CNN model. Check https://github.com/fizyr/keras-retinanet for one of the famous neural network architectures.

How to fix the 'ValueError: input tensor must have rank 4'?

Currently I'm trying to run a CNN in combination with an LSTM model for a video classification, but after a search on Google and Stackoverflow I wasn't able to find the solution for my problem
Below is the whole code:
#Importing libraries
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, LSTM, TimeDistributed
from keras.layers import Activation, Dropout, Flatten, Dense
from keras import backend as K
#Shape of the image, based on 1920x1080
img_width, img_height = 224, 135
#Location of the frames split in a train and test folder
train_data_dir = './train'
validation_data_dir = './test'
#Data information
nb_train_samples = 46822
nb_validation_samples = 8994
timesteps = 1
epochs = 10
batch_size = 30
input_shape = (img_width, img_height, 3)
model = Sequential()
# define CNN model
model.add(TimeDistributed(Conv2D(132, (3, 3), input_shape=input_shape, activation='relu')))
model.add(TimeDistributed(MaxPooling2D(pool_size = (2, 2))))
model.add(TimeDistributed(Flatten()))
# define LSTM model
model.add(LSTM(132, return_sequences=True))
model.add(LSTM(132, return_sequences=True))
model.add(LSTM(132, return_sequences=True))
model.add(LSTM(132, return_sequences=True))
model.add(Dense(3, activation='softmax'))
model.build(input_shape)
model.summary()
model.compile(loss ='categorical_crossentropy', optimizer ='rmsprop', metrics =['accuracy'])
model.fit_generator(train_generator, steps_per_epoch = nb_train_samples // batch_size, epochs = epochs, validation_data = validation_generator, validation_steps = nb_validation_samples // batch_size)
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_width, img_height), batch_size = batch_size, class_mode ='categorical')
validation_generator = test_datagen.flow_from_directory(validation_data_dir, target_size =(img_width, img_height), batch_size = batch_size, class_mode ='categorical')
The error that occures when running this is:
Traceback (most recent call last):
File "CNNLSTM.py", line 36, in
model.build(input_shape)
......
ValueError: input tensor must have rank 4
I've added the model.build(input_shape) to avoid this error:
ValueError: This model has not yet been built. Build the model first by calling build() or calling fit() with some data. Or specify input_shape or batch_input_shape in the first layer for automatic build.
But as is visible in the code, I've applied input_shape in the first line of the model.
Hopefully someone here can point out what I'm doing wrong.
There are three points you should consider:
You mentioned you are doing video classification. Therefore, the input of the model is a set of images/frames. So the input shape (i.e. one sample's shape) is:
input_shape = (n_frames, img_width, img_height, 3)
The first layer of your model is TimeDistributed wrapper which wraps the Conv2D layer. Therefore, you must set the input_shape argument for this layer instead:
model.add(TimeDistributed(Conv2D(132, (3, 3), activation='relu'), input_shape=input_shape))
The build method expects the batch shape as argument, not the shape of a single input sample. Therefore, you should write:
model.build((None,) + input_shape)
However, if you address the point #2 then you DON'T need to call build method at all.
As you can see in the error message model.build expects a 4D tensor as input and your input shape is input_shape = (img_width, img_height, 3) 3D. Tensorflow usually expects input in the following shape: (N, H, W, C), where N is the batch size, H and W are height and width respectively and C is the number of channels. If you have a single image, you could change the input shape to input_shape = (1, img_width, img_height, 3) but in general it is more efficient to work on batches of images.

ValueError: Error when checking target: expected dense_3 to have shape (1,) but got array with shape (5,)

How to Fix this error? I tried visiting all the forums searching for answers to rectify this issue. There are 5 classes in train_set and test_Set.
from keras.models import Sequential
from keras.preprocessing.image import ImageDataGenerator
from keras.layers import Convolution2D, MaxPooling2D, Flatten, Dense
classifier=Sequential()
#1st Convolution Layer
classifier.add(Convolution2D(32, 3, 3, input_shape=(64,64,3),activation="relu"))
#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)))
# Flattening
classifier.add(Flatten())
classifier.add(Dense(output_dim = 128, activation = 'relu'))
classifier.add(Dense(output_dim = 64, activation = 'relu'))
classifier.add(Dense(output_dim = 1, activation = 'softmax'))
classifier.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])
print(classifier.summary())
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('flowers/train_set',
target_size=(64,64),
batch_size=32,
class_mode='categorical')
test_set= test_datagen.flow_from_directory('flowers/test_set',
target_size=(64,64),
batch_size=32,
class_mode='categorical')
classifier.fit_generator(training_set,
samples_per_epoch = 3000,
nb_epoch = 25,
validation_data = test_set,
nb_val_samples=1000)
Here i have attached the image of the error for review.
error
in your code , the following line is wrong
classifier.add(Dense(output_dim = 1, activation = 'softmax'))
change it to
classifier.add(Dense(output_dim = 5, activation = 'softmax'))
why?
its because, your final layer is of 5 dimension. How did i know that output dimension is 5? because, you used categorical_crossentropy and also, it looks like the dataset's labels have 5 categories(based on the first line of the output in the image)

How to handle false predictions in a neural network built and trained with Keras?

I am very new to neural networks and I tried a typical first example with help of some Internet-Blogs: Image Classification of cats or dogs. After training the neural network below I tried to identify some random pictures of cats/dogs which I found on Google and which are neither in my training_set nor in my test_set… I found out, that sometimes the network gives a right prediction (recognizing a dog when showing a dog) and unfortunately sometimes a false prediction i.e. I showed a picture of a cat and the network predicts a ‘dog’. How do I handle such mistakes?
Adding all wrong pictures to the training_set or test_set and do the whole training process again? Or is there any other option to tell the network that it has made a false prediction and should adapt its weights?
#Part 1 - Import
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
#Part 2 – Build Network
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'])
#Part 3 - Training
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('C:/…/KNNDaten/training_set', target_size = (64, 64), batch_size = 32, class_mode = 'binary')
test_set = test_datagen.flow_from_directory('C:/…/KNNDaten/test_set', target_size = (64, 64), batch_size = 32, class_mode = 'binary')
classifier.fit_generator(training_set, steps_per_epoch = 8000, epochs = 25, validation_data = test_set, validation_steps = 2000)
#Part 4 – Saving Model and weights
model_json = classifier.to_json()
with open("model1.json", "w") as json_file:
json_file.write(model_json)
classifier.save_weights("model1.h5")
# Part 5 - Making new predictions
import numpy as np
from keras.preprocessing import image
test_image = image.load_img('C:/… /KNNDaten/single_prediction/cat_or_dog_1.jpg', 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)
training_set.class_indices
if result[0][0] == 1:
prediction = 'dog'
else:
prediction = 'cat'
print("Image contains: " + prediction);
At the moment my training process looks like:
Results of my training process: accuracy, ...
Thank you very much for your help!
The usual process is to add the incorrectly predicted images to the training data set and retrain the network with random weights or using the weights obtained previously with the new images and the old ones.
When training a network you don't need to initiate with random weitghs, you could use the previous weights, this is sometimes called Transfer Learning. It is important if you try to do this to also include the original images used to train the model, or at least a part of it, if you don't want to overfit the model.
As Dascienz comments using data augmentation techniques can also be very useful to get a better generalization, for example adding the new images and variation of them: rotations, translation, symmetries and rescaling.

Categories

Resources