How to compare performance among different keras models - python

I have three different keras models namely multi-scale CNN, single-scale CNN, shallow CNN performing same task. I want to compare performance of these models. Almost every model achieved same accuracy in same time as I can see those graphs from model.history parameters like acc, val-acc. Now I want to specifically point out some differences among these models. Is there any way to observe the performance in much more detailed manner? and I want to make these graphs and I don't know how to plot them.
Model accuracy vs time
Model accuracy vs no.of input batches (my batch size is 5)
My CNN code is like this
def Single_Scale_Model():
model = Sequential()
model.add(Conv2D(20, (1, 3), activation='relu', kernel_initializer='glorot_uniform', data_format='channels_first', input_shape=(19, 1, 50)))
model.add(MaxPooling2D((1, 2), data_format='channels_first'))
model.add(Conv2D(40, (1, 3), activation='tanh', kernel_initializer='glorot_uniform', data_format='channels_first'))
model.add(MaxPooling2D((1, 2), data_format='channels_first'))
model.add(Conv2D(60, (1, 3), activation='relu', kernel_initializer='glorot_uniform', data_format='channels_first'))
model.add(MaxPooling2D((1, 3), data_format='channels_first'))
model.add(Flatten(data_format='channels_first'))
model.add(Dense(100, activation='relu'))
model.add(Dense(4, activation='softmax'))
#print(model.summary())
model.compile(optimizer='sgd', loss='categorical_crossentropy', metrics=['accuracy'])
return model
other two models are also like this but with a slight change in terms of number of layers
Plots look same for both models(Model is meant to achieve 100% accuracy very fast.)

Related

Your input ran out of data; interrupting training. Make sure that your dataset or generator can generate at least `steps_per_epoch

When i am training my self-driving car model it is giving me error in the first epoch. although when i reduced the batch_size it is working fine. But that is not giving me accuracy as i want.
I am trainning my model in Google Collab.
tensorflow version 2.3.1
Error:
WARNING:tensorflow:Your input ran out of data; interrupting training. Make sure that your dataset or generator can generate at least `steps_per_epoch * epochs` batches (in this case, 20000 batches). You may need to use the repeat() function when building your dataset.
My code:
def modified_model():
model = Sequential()
model.add(Conv2D(60, (5, 5), input_shape=(32, 32, 1), activation='relu'))
model.add(Conv2D(60, (5, 5), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(30, (3, 3), activation='relu'))
model.add(Conv2D(30, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(500, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(43, activation='softmax'))
model.compile(Adam(lr = 0.001), loss='categorical_crossentropy', metrics=['accuracy'])
return model
model = modified_model()
print(model.summary())
history = model.fit_generator(datagen.flow(X_train, y_train, batch_size=50),
steps_per_epoch=2000,
epochs=10,
validation_data=(X_val, y_val), shuffle = 1)
When using generators, let the model figure out how many steps are practically there to cover a epoch otherwise you'll have to calculate steps_per_epoch=(data_samples/batch_size). Try running without the step_per_epoch parameter

Why is the training accuracy fluctuating?

I'm working with a video classification of 5 classes and using TimeDistributed CNN model in Google Colab platform. The training dataset contains 80 videos containing 5 frames each. The validation dataset contains 20 videos containing 5 frames each. The batch size I used is 64. So, in total, I'm working with 100 videos. I compiled the model using Adam optimizer and categorical cross_entropy loss.
model = Sequential()
input_shape=(5, 128, 128, 3)
model.add(TimeDistributed(Conv2D(32, (3, 3), strides=(1, 1),
activation='relu', padding='same'), input_shape=input_shape))
model.add(TimeDistributed(MaxPooling2D((2, 2))))
model.add(TimeDistributed(Conv2D(64, (3, 3), strides=(1, 1),
activation='relu', padding='same')))
model.add(TimeDistributed(Conv2D(128, (3, 3), strides=(1, 1),
activation='relu', padding='same')))
model.add(TimeDistributed(BatchNormalization()))
model.add(TimeDistributed(MaxPooling2D((2, 2))))
model.add(TimeDistributed(Flatten()))
model.add(GRU(64, return_sequences=False))
model.add(BatchNormalization())
model.add((Dense(128, activation='relu')))
model.add(Dense(5, activation='softmax'))
from tensorflow.keras.optimizers import Adam
model.compile(loss='categorical_crossentropy',
optimizer=Adam(lr=0.0001),
metrics=['accuracy'])
But, after fitting this model with the dataset, the training accuracy curve is fluctuating like this:
Can anyone help me out to understand the reason behind this fluctuation?
You can try one or two things to stabilize the training:
You can try different batch sizes of 4, 8, 16, 32, 64. You can generate different plots. Have a look at this link. It'll generate mini plots for each batch size.
You can also alter the learning rate. You can apply Learning Rate scheduler or Reduce LR on plateau by directly calling keras callbacks. Alternatively, there is Cyclic LR that try to finds out the optimal learning rate. paper Github

Is there an architecture for multiclass-classification with large amount of classes?

I'm pretty new to deep learning, doing hobby projects. Right now i'm doing multiclass image classification with 200 classes. Is there a tutorial or an actual architecture i can take a look on?
So far i tried basic Dense and CNN nets, but i could never reach better accuracy than 5%.
So far my very basic CNN looks like this.
model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3),
activation='relu',
input_shape=input_shape,
data_format='channels_first'))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(128, (4, 4), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(256, (5, 5), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.5))
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))
model.compile(loss=keras.losses.categorical_crossentropy,
optimizer=keras.optimizers.Adam(),
metrics=['accuracy'])
I looked up for solutions but could never find any project with such large amount of classes(besides VGG-19 or other SOTA CNNs, but i would try write my own, since this is for learning purposes). Is anybody had similar projects or have some tutorial or any advise on such problem?
Thanks in advance.
200 classes is literally few.
Try
from keras.applications.resnet50 import ResNet50
model = ResNet50(weights=None, classes=200)
model.compile(loss=keras.losses.categorical_crossentropy,
optimizer=keras.optimizers.Adam(),
metrics=['accuracy'])
This model(ResNet50) should be good enough for most task.
Every models in keras.applications are trained to have 1000 classes, if your task is some real-world image you can use the trained weights by
from keras.applications.resnet50 import ResNet50
from keras.layers import Dense
from keras.models import Model
model = ResNet50(weights='imagenet')
x = model.get_layer('avg_pool').output
x = Dense(200, activation='softmax')(x)
model = Model(model.input, x)

Keras Image Classification Problems

I'm working on an image classification model for a multiclass problem. I get the model up and running, but when I try to predict/test the model, it appears only to be able to recognise 1 of 4 image types (it's the same class no matter how I change the model). My dataset per class is pretty small, but I do use imagegenerator to increase the amount of data. The model should be able to recognise the images with some added noise on the picture.
My challenges can be boiled down to this:
Small amount of data. I have < 100 images per class.
My model is not supposed to find specific figures, but more overall patterns in the picture (areas with a certain colour and such).
Many of the pictures contain a lot of white and text. Do I need any image preprocessing to help the model.
My model looks like this:
model = Sequential()
model.add(Conv2D(32, (3, 3), padding='same', activation='relu', input_shape=(s1,s2,3), data_format = "channels_first"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(50, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(4, activation='softmax'))
model.compile(loss='categorical_crossentropy',
optimizer='Adam',
metrics=['accuracy'])
And has img size of 250,250, and batch size 16.
Check acc and loss curves
acc curve
loss curve
Do you guys have any advice?
Thanks in advance!
This is classical overfitting. You need to severely restrain your model and/or use transfer learning to combat this behavior. For restraining options you can increase dropout and add l2 regularization. In my experience l2 regularization really makes the problem hard for a NN. For the transfer learning you can use a resnet and just train the last 2-3 layers.
However, nothing beats having more data points though.

Building Convolutional Neural Network for Bull's eye rash recognition

I need to build a Bull's eye rash recognition system.
I chose to work with Tensorflow+Keras for this. I've batch downloaded about 300 images of bull's eye rash, and same amount of other skin diseases&clean skin images. Here is my model:
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'))
In the process (30 epochs) it does give 90%+ accuracy, however, the system shows only about 65% accuracy on the test set.
Then I tried to crop all the rash images so that they fill the entire image. The result was disappointing, again, I don't know why, but it showed about 55% accuracy on the test set.
Can you give me some suggestions on what to do? Is the model wrong or inefficient? Do I have to use some other ML techniques for this?
Examples of images from my dataset: here, here and here
Examples of cropped pictures I used for the second attempt: here, here and here
Well, hard to start with this information.
1) have you tried pre-processing your images?
2) have you tried to load in a pre trained VGG16 network (looks close to yours), then you only need to train the dense layers.
base_model = VGG16(weights='imagenet', include_top=False, input_shape=target_shape)
model_top = Sequential()
model_top.add(Flatten(name='flatten', input_shape=base_model.output_shape[1:]))
model_top.add(Dense(4096, activation='relu', name='fc1'))
model_top.add(Dense(4096, activation='relu', name='fc2'))
model_top.add(Dropout(0.5))
model_top.add(Dense(nr_classes, activation='softmax', name='predictions'))
model_full = Model(inputs=base_model.input, outputs=model_top(base_model.output))
# set the first 25 layers (up to the last convolution block)
# to non-trainable (weights will not be updated)
for layer in model_full.layers[:-5]:
layer.trainable = False
model_full.compile(loss='categorical_crossentropy',
optimizer=optimizers.Adam(lr=1e-7))
model_full.summary()
3) Create a validation set to see if you overfit the network (validation accuracy decreases, but training accuracy increases).

Categories