Getting very poor accuracy on stanford_dogs dataset - python

I'm trying to train a model on the stanford_dogs dataset to classify 120 dog breeds but my code is acting strange.
I downloaded the image data from http://vision.stanford.edu/aditya86/ImageNetDogs/images.tar
Then ran the following code to split each folder of the breeds into training and testing folders:
dataset_dict = {}
source_path = 'C:/Users/visha/Downloads/stanford_dogs/dataset'
dir_root = os.getcwd()
dataset_folders = [x for x in os.listdir(os.path.join(dir_root, source_path)) if os.path.isdir(os.path.join(dir_root, source_path, x))]
for category in dataset_folders:
dataset_dict[category] = {'source_path': os.path.join(dir_root, source_path, category),
'train_path': create_folder(new_path='C:/Users/visha/Downloads/stanford_dogs/train',
folder_type='train',
data_class=category),
'validation_path': create_folder(new_path='C:/Users/visha/Downloads/stanford_dogs/validation',
folder_type='validation',
data_class=category)}
dataset_folders = [x for x in os.listdir(os.path.join(dir_root, source_path)) if os.path.isdir(os.path.join(dir_root, source_path, x))]
for key in dataset_dict:
print("Splitting Category {} ...".format(key))
split_data(source_path=dataset_dict[key]['source_path'],
train_path=dataset_dict[key]['train_path'],
validation_path=dataset_dict[key]['validation_path'],
split_size=0.7)
I fed the images through the network after some image augmentation and used sigmoid activation in the final layer and categorical_crossentropy loss.
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.optimizers import RMSprop
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(16, (3, 3), activation='relu', input_shape=(150, 150, 3)),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Conv2D(32, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(512, activation='relu'),
tf.keras.layers.Dense(120, activation='softmax')
])
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
TRAINING_DIR = 'C:/Users/visha/Downloads/stanford_dogs/train'
train_datagen = ImageDataGenerator(rescale=1./255,rotation_range=40,width_shift_range=0.2,height_shift_range=0.2,
shear_range=0.2,zoom_range=0.2,horizontal_flip=True,fill_mode='nearest')
train_generator = train_datagen.flow_from_directory(TRAINING_DIR,
batch_size=10,
class_mode='categorical',
target_size=(150, 150))
VALIDATION_DIR = 'C:/Users/visha/Downloads/stanford_dogs/validation'
validation_datagen = ImageDataGenerator(rescale=1./255, rotation_range=40,width_shift_range=0.2, height_shift_range=0.2,
shear_range=0.2,zoom_range=0.2,horizontal_flip=True,fill_mode='nearest')
validation_generator = validation_datagen.flow_from_directory(VALIDATION_DIR,
batch_size=10,
class_mode='categorical',
target_size=(150, 150))
history = model.fit(train_generator,
epochs=10,
verbose=1,
validation_data=validation_generator)
But the code is not working as intended. The val_accuracy after 10 epochs is something like 4.756.

For validation data you should not do any image augmentation, just do rescale. In validation flow_from_directory set shuffle=False. Be advised that the Stanford Dog Data set is very difficult. To achieve a reasonable degree of accuracy you will need a much more complex model. I recommend you consider transfer learning using the Mobilenet model. The code below shows how to do that.
base_model=tf.keras.applications.mobilenet.MobileNet( include_top=False,
input_shape=(150,150,3) pooling='max', weights='imagenet',dropout=.4)
x=base_model.output
x=keras.layers.BatchNormalization(axis=-1, momentum=0.99, epsilon=0.001 )(x)
x = Dense(1024, activation='relu')(x)
x=Dropout(rate=.3, seed=123)(x)
output=Dense(120, activation='softmax')(x)
model=Model(inputs=base_model.input, outputs=output)
model.compile(Adamax(lr=.001),loss='categorical_crossentropy',metrics=
['accuracy'] )
I forgot to mention that Mobilenet was trained on Images with pixel values in the range -1 to +1. So in ImageDataGenerator include the code
preprocessing_function=tf.keras.applications.mobilenet.preprocess_input
this scales the pixels so you do not need the code
rescale=1./255
or alternatively set
rescale=1/157.5-1
which will rescale the values between -1 and +1

Related

Tensor model accuracy - machine learning based on images

I am trying to build a software that can trade for me based in machine learning.
So I extracted bunch of data, generated charts with some indicators that I use and separate them in BUY, SELL and NOT_DEFINED. and I am using SELL and BUY to train.
Unfortunately the accuracy is not increasing. In certain level I made the accuracy achieve 0.82 but the final model.evaluate(test_set) always gives me a randonmic number around 0.50 . Even the prediction code I build is give me the same result.
Now not even during training the accuracy increase. Can somebody give me ideas how to make some progress?
import tensorflow as tf
from tensorflow import keras
import os
from keras.preprocessing.image import ImageDataGenerator
# Carregando as imagens
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:/Users/Adriano/PycharmProjects/machineLearningChatGPT/data/150_reduzido/train',
target_size = (150, 150),
batch_size = 64,
class_mode = 'categorical',
shuffle=False)
test_set = test_datagen.flow_from_directory('C:/Users/Adriano/PycharmProjects/machineLearningChatGPT/data/150_reduzido/validation',
target_size = (150, 150),
batch_size = 64,
class_mode = 'categorical',
shuffle=False)
# Construindo e treinando o modelo
model = keras.Sequential([
keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(150, 150, 3)),
keras.layers.MaxPooling2D((2, 2)),
keras.layers.Conv2D(64, (3, 3), activation='relu'),
keras.layers.MaxPooling2D((2, 2)),
# keras.layers.Conv2D(64, (3, 3), activation='relu'),
# keras.layers.MaxPooling2D((2, 2)),
# keras.layers.Conv2D(128, (3, 3), activation='relu'),
# keras.layers.MaxPooling2D((2, 2)),
keras.layers.Flatten(),
keras.layers.Dense(128, activation='relu'),
keras.layers.Dense(2, activation='softmax')
])
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(training_set, epochs=20)
# Avaliando o modelo
test_loss, test_acc = model.evaluate(test_set)
# Salvando o modelo e os pesos
model.save("redmodelFalse.h5")
model.save_weights("redweightFalse.h5")
I tried lots of things I saw other people doing. changed the number of epochs, batch_size, add shuffle = false in the training set, add layers, change activation and of course the set of images I am using.

Wrong Confusion Matrix Display - CCN Image Keras model

am new to Deep Learning and using CNNs. I am trying to predict the quality of coffee seeds using images where good quality is Coffee AA and the other is Poor Quality. I built the model tried to evaluate its performance by using a Confusion Matrix on a test data(test_ds) but it seems to give me a one column prediction instead of a diagonal form. I don't know where the issue is coming from whether its how i built the model or how am trying to build the confusion matrix. Kindly help. The rest of the code is here https://colab.research.google.com/drive/1cNgAbCy8e4lG-dCepVxIpFx1Wfeof5wb?usp=sharing
Here is part of the Code:
data = tf.keras.preprocessing.image_dataset_from_directory(
"/data/train2 cofi",
shuffle=True,
image_size= (IMAGE_SIZE,IMAGE_SIZE),
batch_size= BATCH_SIZE)
img_height = 256
img_width = 256
batch_size = 32
test_ds = tf.keras.preprocessing.image_dataset_from_directory(
"/data/test2 cofi",
image_size=(img_height, img_width),
batch_size=batch_size)
#preparing the model layers
input_shape = (BATCH_SIZE, IMAGE_SIZE, IMAGE_SIZE, CHANNELS)
n_classes = 1
model = models.Sequential([
resize_and_rescale,
data_augmentation,
layers.Conv2D(32, (3,3), activation='relu', input_shape = input_shape), # 32-layers, (3,3)-filter size,activation function
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, kernel_size = (3,3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Flatten(),
layers.Dense(64, activation='relu'),
layers.Dense(n_classes, activation='sigmoid') # softmax helps to normalize the probabilities in the dense layer
])
model.build(input_shape=input_shape)
#Training the model
metrics = [TruePositives(name='TruePov'), FalsePositives(name='FalsePov'),
TrueNegatives(name='TrueNeg'), FalseNegatives(name='FalseNeg'),
BinaryAccuracy(name='accuracy'), Precision(name='Precision'), Recall(name='recall'), AUC(name='auc')]
# Using the adam optimizer to track the gradient descent in the training process
model.compile(
optimizer= Adam(learning_rate = 0.01),
loss = BinaryCrossentropy(),
metrics=metrics
)
history = model.fit(
train_ds,
epochs=EPOCHS,
batch_size=BATCH_SIZE,
verbose=1,
validation_data=val_ds
)
# Building a Confusion Matrix
from sklearn.metrics import confusion_matrix, classification_report
import seaborn as sns
sns.set_style('darkgrid')
classes=test_ds.class_names # ordered list of class names
class_names = ['Arabica AA', 'Poor Arabica Quality']
ytrue=[]
for images, label in test_ds:
for e in label:
ytrue.append(classes[e]) # list of class names associated with each image file in test dataset
ypred=[]
errors=0
count=0
preds=model.predict(test_ds, verbose=1) # predict on the test data
for i, p in enumerate(preds):
count +=1
index=np.argmax(p) # get index of prediction with highest probability
klass=classes[index]
ypred.append(klass)
if klass != ytrue[i]:
errors +=1
acc= (count-errors)* 100/count
msg=f'there were {count-errors} correct predictions in {count} tests for an accuracy of {acc:6.2f} % '
print(msg)
ypred=np.array(ypred)
ytrue=np.array(ytrue)
if len(classes)<= 2: # if more than 30 classes plot is not useful to cramed
# create a confusion matrix
cm = confusion_matrix(ytrue, ypred )
length=len(classes)
if length<8:
fig_width=5
fig_height=5
else:
fig_width= int(length * .4)
fig_height= int(length * .4)
plt.figure(figsize=(fig_width, fig_height))
sns.heatmap(cm, annot=True, vmin=0, fmt='g', cmap='Blues', cbar=False)
plt.xticks(np.arange(length)+.3, classes, rotation= 90)
plt.yticks(np.arange(length)+.3, classes, rotation=0)
plt.xlabel("Predicted")
plt.ylabel("Actual")
plt.title("Confusion Matrix")
plt.show()
clr = classification_report(ytrue, ypred, target_names=class_namz)
print("Classification Report:\n----------------------\n", clr)
The output of the Confusion Matrix
enter image description here

How to improve my CNN ? high and constant validation error

I am working on a problem for predicting a score of how fat cows are, based on images of cows.
I applied a CNN to estimate the value which is between 0-5 ( the dataset i have, contains only values between 2.25 and 4 )
I am using 4 CNN layers and 3 Hidden layers.
I actualy have 2 problems :
1/ I got 0.05 training error, but after 3-5 epochs the validation error remains at about 0.33.
2/ The value predicted by my NN are between 2.9 and 3.3 which is too narrow compared with the dataset range. Is it normal ?
How can i improve my model ?
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(512, 424,1)),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Conv2D(32, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Conv2D(32, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Flatten(input_shape=(512, 424)),
tf.keras.layers.Dense(256, activation=tf.nn.relu),
tf.keras.layers.Dense(128, activation=tf.nn.relu),
tf.keras.layers.Dense(64, activation=tf.nn.relu),
tf.keras.layers.Dense(1, activation='linear')
])
Learning Curve:
Prediction:
This seems to be the case of Overfitting. You can
Shuffle the Data, by using shuffle=True in cnn_model.fit. Code is shown below:
history = cnn_model.fit(x = X_train_reshaped,
y = y_train,
batch_size = 512,
epochs = epochs, callbacks=[callback],
verbose = 1, validation_data = (X_test_reshaped, y_test),
validation_steps = 10, steps_per_epoch=steps_per_epoch, shuffle = True)
Use Early Stopping. Code is shown below
callback = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=15)
Use Regularization. Code for Regularization is shown below (You can try l1 Regularization or l1_l2 Regularization as well):
from tensorflow.keras.regularizers import l2
Regularizer = l2(0.001)
cnn_model.add(Conv2D(64,3, 3, input_shape = (28,28,1), activation='relu', data_format='channels_last',
activity_regularizer=Regularizer, kernel_regularizer=Regularizer))
cnn_model.add(Dense(units = 10, activation = 'sigmoid',
activity_regularizer=Regularizer, kernel_regularizer=Regularizer))
You can try using BatchNormalization.
Perform Image Data Augmentation using ImageDataGenerator. Refer this link for more info about that.
If the Pixels are not Normalized, Dividing the Pixel Values with 255 also helps.
Finally, if there still no change, you can try using Pre-Trained Models like ResNet or VGG Net, etc..

How to fix 'ValueError: Empty Training Data' error in tensorflow

I am new to tensorflow and keras. I am trying to train a model to identify different images for rock paper and scissors. I am using an online tutorial for that and they have provided me with a google collab worksheet. When I train the model on google collab everything works fine but if I try training the model on my machine, it gives me this error:
ValueValueError: Empty training data
I have tried changing the batch size and also tried tried changing the amount of images in the dataset but it doesnt help(And it shouldn't).
Here is my code:
###### ROCK PAPER SISSORS #######
import os
import numpy as np
import cv2
import tensorflow as tf
import keras_preprocessing
from keras_preprocessing import image
from keras_preprocessing.image import ImageDataGenerator
import matplotlib.pyplot as plt
# import matplotlib.image as mpimg
# Provide the path to the directory of the classes
rock_dir = os.path.join('/media/visheshchanana/New Volume/Projects/datasets/RPS/rps/rock')
paper_dir = '/media/visheshchanana/New Volume/Projects/datasets/RPS/rps/paper'
scissors_dir = '/media/visheshchanana/New Volume/Projects/datasets/RPS/rps/scissors'
rock_files = os.listdir(rock_dir)
# print(rock_files[:10])
# ​
paper_files = os.listdir(paper_dir)
# print(paper_files[:10])
# ​
scissors_files = os.listdir(scissors_dir)
# # print(scissors_files[:10])
# Use the augmentation tool to change the augmentation of the images so that we can have a better classifier
TRAINING_DIR = "/media/visheshchanana/New Volume/Projects/datasets/RPS/rps"
training_datagen = ImageDataGenerator(
rescale = 1./255,
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest')
# Provide the path to the validation dataset
VALIDATION_DIR = "/media/visheshchanana/New Volume/Projects/datasets/RPS/RPS_validation"
validation_datagen = ImageDataGenerator(rescale = 1./255)
train_generator = training_datagen.flow_from_directory(
TRAINING_DIR,
target_size=(150,150),
class_mode='categorical'
)
validation_generator = validation_datagen.flow_from_directory(
VALIDATION_DIR,
target_size=(150,150),
class_mode='categorical'
)
model = tf.keras.models.Sequential([
# Note the input shape is the desired size of the image 150x150 with 3 bytes color
# This is the first convolution
tf.keras.layers.Conv2D(64, (3,3), activation='relu', input_shape=(150, 150, 3)),
tf.keras.layers.MaxPooling2D(2, 2),
# The second convolution
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
# The third convolution
tf.keras.layers.Conv2D(128, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
# The fourth convolution
tf.keras.layers.Conv2D(128, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
# Flatten the results to feed into a DNN
tf.keras.layers.Flatten(),
tf.keras.layers.Dropout(0.5),
# 512 neuron hidden layer
tf.keras.layers.Dense(512, activation='relu'),
tf.keras.layers.Dense(3, activation='softmax')
])
model.summary()
model.compile(loss = 'categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
history = model.fit_generator(train_generator, epochs=5, validation_data = validation_generator, verbose = 1)
The dataset is the same as used in the google collab. I can't figure out the reason behind this error.
There might be other reasons for this error, but I realized that I had a batch size that was greater than my sample size.
I had the same problem. My model trains and gives this error (ValueValueError: Empty training data) at the end of the first epoch. I figured out that it was because there was no data in the validation path.
Check if steps_per_epoch is not set to 0 (e.g. because of integer division)

wifi gesture recognition,dl,ml, python, cnn,

I have dataset look like this
(7500, 200, 30, 3)
which 7500 samples (there are a tensor of shape 200,30,3) which is related to CSI data (kind of wifi data for gesture recognition) It has 150 different labels (gestures) the aim is to classify
I used a CNN by keras to classify, I faced with huge overfitting
def create_DL_model():
# input layer
csi = Input(shape=(200,30,3))
# first feature extractor
x = Conv2D(64, kernel_size=3, activation='relu',name='layer1-01')(csi)
x=BatchNormalization()(x)
x = MaxPooling2D(pool_size=(2, 2),name='layer1-02')(x)
x = Conv2D(64, kernel_size=3, activation='relu',name='layer1-03')(x)
x=BatchNormalization()(x)
x = MaxPooling2D(pool_size=(2, 2),name='layer1-04')(x)
x=BatchNormalization()(x)
x = Conv2D(64, kernel_size=3, activation='relu',name='layer1-05',padding='same')(x)
x=Conv2D(32, kernel_size=3, activation='relu',name='layer1-06',padding='same')(x)
x=Conv2D(64, (3,3),padding='same',activation='relu',name='layer-01')(x)
x=BatchNormalization()(x)
x=MaxPool2D(pool_size=(2, 2,),name='layer-02')(x)
x=Conv2D(32, (3,3),padding="same",activation='relu',name='layer-03')(x)
x=BatchNormalization()(x)
x=MaxPool2D(pool_size=(2, 2),name='layer-04')(x)
x=Flatten()(x)
x=Dense(16,activation='relu')(x)
keras.layers.Dropout(.50, seed=1)
probability=Dense(150,activation='softmax')(x)
model= Model(inputs=csi, outputs=probability)
model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
return model
as you see, I used drop out for dense layer, early stopping and batch normalization for fight with overfitting, as you see still, there is the problem
after cross validation, I have accuracy around 70 (some papers got 90 pecent accuracy however we have 150 labels and it seems 90 pecent it is really grear result, they used meta-learning which I could not use), is there any way that you can recommend
many thanks
The accuracy vs epoch graph signals the over fitting issue present in your model. This is due to few training samples (7500/150 = 50 per class). One possible solution could be applying Data Augmentation which allows you to build a powerful image classifier using only very few training examples.
Data structure
Store your data according to the following structure
data/
train/
class1/
class1_img001.jpg
class1_img002.jpg
class2/
class2_img001.jpg
class2_img002.jpg
...
class150/
class150_img001.jpg
class150_img002.jpg
...
validation/
class1/
class1_img001.jpg
class1_img002.jpg
class2/
class2_img001.jpg
class2_img002.jpg
...
class150/
class150_img001.jpg
class150_img002.jpg
...
You can do:
def create_DL_model(img_height, img_width, channel):
# input layer
csi = Input(shape=(img_height, img_width, channel))
# first feature extractor
x = Conv2D(64, kernel_size=3, activation='relu',name='layer1-01')(csi)
x=BatchNormalization()(x)
x = MaxPooling2D(pool_size=(2, 2),name='layer1-02')(x)
x = Conv2D(64, kernel_size=3, activation='relu',name='layer1-03')(x)
x=BatchNormalization()(x)
x = MaxPooling2D(pool_size=(2, 2),name='layer1-04')(x)
x=BatchNormalization()(x)
x = Conv2D(64, kernel_size=3, activation='relu',name='layer1-05',padding='same')(x)
x=Conv2D(32, kernel_size=3, activation='relu',name='layer1-06',padding='same')(x)
x=Conv2D(64, (3,3),padding='same',activation='relu',name='layer-01')(x)
x=BatchNormalization()(x)
x=MaxPool2D(pool_size=(2, 2,),name='layer-02')(x)
x=Conv2D(32, (3,3),padding="same",activation='relu',name='layer-03')(x)
x=BatchNormalization()(x)
x=MaxPool2D(pool_size=(2, 2),name='layer-04')(x)
x=Flatten()(x)
x=Dense(16,activation='relu')(x)
keras.layers.Dropout(.50, seed=1)
probability=Dense(150,activation='softmax')(x)
model= Model(inputs=csi, outputs=probability)
return model
from keras.preprocessing.image import ImageDataGenerator
batch_size = 32
img_height = 200
img_width = 30
channel = 3
model = create_DL_model(img_height, img_width, channel)
# this is the augmentation configuration we will use for training
train_datagen = ImageDataGenerator(
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
rescale=1./255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest')
# this is the augmentation configuration we will use for testing:
# only rescaling
test_datagen = ImageDataGenerator(rescale=1./255)
# this is a generator that will read pictures found in
# subfolers of 'data/train', and indefinitely generate
# batches of augmented image data
train_generator = train_datagen.flow_from_directory(
'data/train', # this is the target directory
target_size=(img_height , img_width ), # all images will be resized
batch_size=batch_size,
class_mode='categorical_crossentropy')
# this is a similar generator, for validation data
validation_generator = test_datagen.flow_from_directory(
'data/validation',
target_size=(img_height , img_width ),
batch_size=batch_size,
class_mode='categorical_crossentropy')
model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
model.fit_generator(
train_generator,
steps_per_epoch=7500// batch_size,
epochs=50,
validation_data=validation_generator,
validation_steps=YOUR_VALIDATION_SIZE// batch_size) # use YOUR_VALIDATION_SIZE as per your validation data
model.save('model-e50-b32.h5') # always save your weights after training or during training
The number of CNN layers can be decreased and accuracy-loss can be monitored since we are only feeding 7500 training images.
The above code is not tested. Please share your errors for further advice.
More about data augmentation and how to apply is here.

Categories

Resources