Predicting a single observation is always showing same class - python

I'm trying to make an OCR for Bangla character. I have 168 different classes. For predicting each character my model is
model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3),
activation='relu',
input_shape=(42,28,1)))
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(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))
It performs well in my testing set. I'm trying to predict a single instance but for each different instance it's showing same class output. I read single image as following
from PIL import Image
#location for single image
location='Bangla-Compound-Character-Recognition/data/2/ka.jpg'
#image size = (42x28) grayscale
image=np.array(Image.open(location)).reshape(42,28,1)
image=np.expand_dims(image,axis=0)
single_image_cls=model.predict_classes(image)
print(single_image_cls)
Predicting a single instance of test set shows proper result and test accuracy is 90%
#predicting a single test instance
probablity=model.predict_classes(x_test[100:101])

When testing on new images, you have to apply the same normalization as the training set, normally dividing image pixels by 255:
single_image_cls=model.predict_classes(image / 255)

Related

Keras model always predicting the same class

I am working on a project where I have to classify genomic sequences as either positive or negative. So basically, I have sequences that are in the form 'accccttttttgggg...'
These sequences are 150 characters long consisting of a, c, t and g characters. I perform one hot encoding of the data and create a dataframe that contains 600 columns (150 x 4) for sequences plus one column for label (either 0 or 1). I then pass this data through CNN. The model performs well on the training and validation data but when I see the predictions on test data it always predicts a single label 0. Can anyone help me know why does this happen and what I am doing wrong here. This is the model that I have been using with epochs=50, learning_rate=0.00001 and batch_size=64
model = Sequential()
model.add(Conv1D(32, kernel_size=5, input_shape=(600, 1), activation='relu', padding='same'))
model.add(MaxPooling1D())
model.add(Conv1D(16, kernel_size=5, activation='relu', padding='same'))
model.add(MaxPooling1D())
model.add(Conv1D(8, kernel_size=5, activation='relu', padding='same'))
model.add(MaxPooling1D())
model.add(Flatten())
model.add(Dense(4, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
adam = Adam(learning_rate=learning_rate)
model.compile(loss='binary_crossentropy', optimizer=adam, metrics=['accuracy'])

Any suggestions to improve my CNN model (always the same low test accuracy)?

I am working on a project to detect the presence of a person in a painting. I have 4000 training images and 1000 test images resized to (256,256,3)
I tried a CNN model with 3 (Conv layers, MaxPool, BatchNormalization) and 2 fully connected layers.
model = Sequential()
model.add(Conv2D(32, kernel_size = (7, 7), activation='relu', input_shape=shape))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
model.add(Conv2D(64, kernel_size=(7,7), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
model.add(Conv2D(96, kernel_size=(5,5), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(32, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(1, activation = 'sigmoid'))
The train accuracy always converges to 1 (with just 20-50 epochs) and the test accuracy always remains constant around 0.67.
I tried the following:
I tried changing the size of the layers and adding more layers.
I tried data augmentation
I tried smaller images 128x128x3.
But I always have the same results.
I don't know if this is due to the few images I have, or if the architecture isn't big enough to learn from complex paintings.
I thought of trying Transfer Learning (But I don't know if this will help because it is my first time trying it). Also, do you have any idea where can I find trained models?
So, I am asking from some suggestions to improve my model.
It might be that you are overfitting on your training data, in that case you can use dropout.
The other thing is If you have not already normalized your data, you can do that. I am not sure whether that would be much help but give it a try with sth like:
X_training = X_training / X_training.max()
I tried using VGG16 (frozen) with 4 fully connected layers and the validation accuracy went up to 0.83. Also, I am using ImageDataGenerator.

How to properly set up a neural network for coloring grayscale images?

I am trying to color the bird images from the CIFAR-10 dataset.
Problem set-up:
X: (5000,32,32,1) where each entry is a grayscale version of the bird images
Y: (5000,4096) which is a one hot encode array. for example, the first pixel will have [0,0,1,0] where 1 implies which color to be used.
Y is simply the collapsed version of all the one-hot encoding per image.
I've followed many articles that implement coloring of gray-scale images, but my loss/accuracy continues to be high/low.
model = Sequential()
model.add(Convolution2D(32, (5, 5), strides=(1,1), input_shape=(32,32,1),padding='same', activation='relu'))
model.add(Dropout(0.2))
model.add(Convolution2D(32, (5, 5),activation='relu', padding='same' ))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Convolution2D(64, (5, 5), activation='relu', padding='same' ))
model.add(Flatten())
model.add(Dense(128))
model.add(Dense(4096, activation='softmax'))
# Compile model
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(Xtrain, Ytrain, validation_data=(val_data,Ytest),epochs=5, batch_size=32)
I'm expecting the accuracy to be improved as it progresses through the epochs, but it continues to get worse.
You'll have to put some work into architecture (which it sounds like you've been thinking about), but to simply black-box it, you can pump in the gray images and draw out the color images. Why not?
Use model.summary() to make sure your shapes are to your liking. (See below)
I haven't tested this code, but it should be pretty close...
model = Sequential()
model.add(InputLayer(input_shape=(32,32,1)))
model.add(Conv2D(32,(5,5),strides=(1,1), activation='relu', padding='same'))
model.add(SpatialDropout2D(rate=0.2)) # holla at this layer
model.add(Conv2D(32,(5,5), activation='relu', padding='same'))
model.add(MaxPool2D((2,2)))
model.add(Conv2D(64,(5,5),activation='relu',padding='same'))
model.add(Dense(128))
# have to upsample to get your height/width back from max pooling!
model.add(UpSampling2D((2,2)))
model.add(Conv2D(3,(2,2),activation='relu',padding='same'))
model.add(Activation('softmax'))
model.compile(optimizer='adam',loss='mse')
model.summary()
Here's the output of model.summary(). The output layer is (32,32,3); 32 height, 32 width, channels.
[1]
Now just train it with grayscales as X, and the color originals as Y. And post results, for the curious!

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