how implement cross validation with flower dataset? - tensorflow

I hope you are all doing well ^_^
how implement cross validation with flower dataset? the dataset contains 3670 images in 5 folders ['daisy', 'dandelion', 'roses', 'sunflowers', 'tulips'] i want to use vgg16 or any model and Cross-Validation to improve my accuracy, right now it's between 84-86%.
.I'm a noob in this field, i have tested transfer learning models with the flower dataset, i read some article about cross validation and i want to test it with this dataset. but the dataset does not contain csv file.
link to the dataset : https://www.kaggle.com/rajmehra03/flower-recognition-cnn-keras/data
----------------------------------------code------------------------------------------------------
import matplotlib.pyplot as plt
import numpy as np
import os
import PIL
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense,Conv2D,MaxPool2D,Dropout,Flatten
import pathlib
dataset_url =
"https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz"
data_dir = tf.keras.utils.get_file('flower_photos', origin=dataset_url, untar=True)
data_dir = pathlib.Path(data_dir)
image_count = len(list(data_dir.glob('*/*.jpg')))
print(image_count)
batch_size = 32
img_height = 224
img_width = 224
train_ds = tf.keras.utils.image_dataset_from_directory(
data_dir,
validation_split=0.2,
subset="training",
seed=123,
image_size=(img_height, img_width),
batch_size=batch_size)
val_ds = tf.keras.utils.image_dataset_from_directory(
data_dir,
validation_split=0.2,
subset="validation",
seed=123,
image_size=(img_height, img_width),
batch_size=batch_size)
class_names = train_ds.class_names
print(class_names)
for image_batch, labels_batch in train_ds:
print(image_batch.shape)
print(labels_batch.shape)
break
AUTOTUNE = tf.data.AUTOTUNE
train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)
normalization_layer = layers.Rescaling(1./255)
normalized_ds = train_ds.map(lambda x, y: (normalization_layer(x), y))
image_batch, labels_batch = next(iter(normalized_ds))
first_image = image_batch[0]
# Notice the pixel values are now in `[0,1]`.
print(np.min(first_image), np.max(first_image))
num_classes = len(class_names)
vgg16_model = keras.applications.vgg16.VGG16()
model = Sequential()
for layer in vgg16_model.layers:
model.add(layer)
print(len(model.layers))
model.summary()
#model.pop()
print(len(model.layers))
for layer in model.layers:
layer.trainable = False
model.add(Dense(1000, activation = 'softmax'))
model.add(Dense(5, activation = 'softmax'))
print(len(model.layers))
model.summary()
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
epochs=10
history = model.fit(
train_ds,
validation_data=val_ds,
epochs=epochs
)
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs_range = range(epochs)
plt.figure(figsize=(8, 8))
plt.subplot(1, 2, 1)
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()

Related

TypeError: Singleton array cannot be considered a valid collection

Tried using k-cross validation from this link but with my own dataset and I got this error:
TypeError: Singleton array array(<BatchDataset element_spec=(TensorSpec(shape=(None, 180, 180, 3), dtype=tf.float32, name=None), TensorSpec(shape=(None,), dtype=tf.int32, name=None))>,
dtype=object) cannot be considered a valid collection.
Here is my code:
import numpy as np
import PIL
import tensorflow as tf
import os
from sklearn.model_selection import KFold
import numpy as np
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.models import Sequential
import pathlib
num_folds = 10
acc_per_fold = []
loss_per_fold = []
tf.get_logger().setLevel('ERROR')
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
dataset_path = "data"
fullPath = os.path.abspath("./" + dataset_path)
#data_dir = tf.keras.utils.get_file('photos', origin='file://'+dataset_path, extract=True)
data_dir = pathlib.Path(fullPath)
image_count = len(list(data_dir.glob('*/*.jpg')))+len(list(data_dir.glob('*/*.png')))
print(image_count)
#man = list(data_dir.glob('man/*'))
#im = PIL.Image.open(str(man[28]))
#im.show()
batch_size = 32
img_height = 180
img_width = 180
train_ds = tf.keras.utils.image_dataset_from_directory(
data_dir,
labels='inferred',
validation_split=0.2,
subset="training",
seed=123,
image_size=(img_height, img_width),
batch_size=batch_size)
val_ds = tf.keras.utils.image_dataset_from_directory(
data_dir,
labels='inferred',
validation_split=0.2,
subset="validation",
seed=123,
image_size=(img_height, img_width),
batch_size=batch_size)
class_names = train_ds.class_names
print(class_names)
normalization_layer = layers.Rescaling(1./255)
# Define the K-fold Cross Validator
kfold = KFold(n_splits=num_folds, shuffle=True, random_state=42)
fold_no = 1
for train, test in kfold.split(train_ds, val_ds):
# Define the model architecture
model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dense(128, activation='relu'))
model.add(Dense(no_classes, activation='softmax'))
# Compile the model
model.compile(loss=loss_function,
optimizer=optimizer,
metrics=['accuracy'])
# Generate a print
print('------------------------------------------------------------------------')
print(f'Training for fold {fold_no} ...')
# Fit data to model
history = model.fit(inputs[train], targets[train],
batch_size=batch_size,
epochs=no_epochs,
verbose=verbosity)
# Generate generalization metrics
scores = model.evaluate(inputs[test], targets[test], verbose=0)
print(f'Score for fold {fold_no}: {model.metrics_names[0]} of {scores[0]}; {model.metrics_names[1]} of {scores[1]*100}%')
acc_per_fold.append(scores[1] * 100)
loss_per_fold.append(scores[0])
# Increase fold number
fold_no = fold_no + 1
# == Provide average scores ==
print('------------------------------------------------------------------------')
print('Score per fold')
for i in range(0, len(acc_per_fold)):
print('------------------------------------------------------------------------')
print(f'> Fold {i+1} - Loss: {loss_per_fold[i]} - Accuracy: {acc_per_fold[i]}%')
print('------------------------------------------------------------------------')
print('Average scores for all folds:')
print(f'> Accuracy: {np.mean(acc_per_fold)} (+- {np.std(acc_per_fold)})')
print(f'> Loss: {np.mean(loss_per_fold)}')
print('------------------------------------------------------------------------')

Model not learning with tf.keras.preprocessing.image_dataset_from_directory

I tried to make a simple model to recognize images of animals (3 classes),
with the function tf.keras.preprocessing.image_dataset_from_directory, when i fit the model with the train and validation dataset, it seems to work, but on evaluate and predict, it find always the same class, I dont know why, here is my code :
import matplotlib.pyplot as plt
import numpy as np
import PIL
import tensorflow as tf
from tensorflow.keras.layers import Dense, Flatten
from tensorflow.keras.models import Sequential
from tensorflow.keras.optimizers import Adam
from tensorflow import keras
import os
i = 0
def fast_scandir(dirname):
subfolders= [f.path for f in os.scandir(dirname) if f.is_dir()]
for dirname in list(subfolders):
subfolders.extend(fast_scandir(dirname))
return subfolders
classnames = fast_scandir("/home/someone/Documents/machinelearning/path/testimage")
for name in classnames:
classnames[i] = classnames[i].replace("/home/someone/Documents/machinelearning/path/images/","")
i+=1
i=0
classesnum = len(classnames)
#print(classesnum)
img_height = 256
img_width = 256
batch_size = 16
IMAGE_SIZE = 256
data_dir = "/home/someone/Documents/machinelearning/path/testimage"
test_dir = "/home/someone/Documents/machinelearning/path/testimage"
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
data_dir,
validation_split=0.2,
subset="training",
label_mode="categorical",
seed=123,
shuffle=False,
image_size=(img_height, img_width),
batch_size=batch_size,
color_mode='rgb')
print(train_ds)
'''
test_ds = tf.keras.preprocessing.image_dataset_from_directory(
test_dir,
label_mode="categorical",
seed=123,
shuffle=False,
image_size=(img_height, img_width),
batch_size=batch_size,
color_mode='rgb')
'''
val_ds = tf.keras.preprocessing.image_dataset_from_directory(
data_dir,
validation_split=0.2,
subset="validation",
label_mode="categorical",
seed=123,
shuffle=False,
image_size=(img_height, img_width),
batch_size=batch_size,
color_mode='rgb')
'''
#####debug######
for images,labels in train_ds.take(1):
for i in range(len(labels)):
img = plt.imshow(images[i].numpy().astype("uint8"))
plt.title(str(labels[i]))
plt.show()
'''
#tf.data.experimental.cardinality(train_ds)
#print(val_ds)
#print(np.shape(val_ds))
#print(type(val_ds))
import matplotlib.pyplot as plt
pretrained_model= tf.keras.applications.ResNet50(include_top=False,
input_shape=(img_width,img_height,3),
pooling='avg',classes=classesnum,
weights='imagenet')
for layer in pretrained_model.layers:
layer.trainable=False
from tensorflow.keras.layers import Conv2D, MaxPooling2D
from tensorflow.keras.layers import Dense, Flatten
from tensorflow.keras import optimizers
model = Sequential()
model.add(Conv2D(32,(3,3),input_shape=(IMAGE_SIZE,IMAGE_SIZE,3),activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(64,(3,3),activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(96,(3,3),activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(128,(3,3),activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Flatten())
model.add(Dense(512,activation='relu'))
model.add(Dense(3,activation='softmax'))
model.summary()
model.compile(loss='categorical_crossentropy',
optimizer=keras.optimizers.Adam(learning_rate=3e-4),
metrics=['accuracy'])
history = model.fit(train_ds, validation_data=val_ds, epochs=10)
fig1 = plt.gcf()
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.axis(ymin=0.4,ymax=1)
plt.grid()
plt.title('Model Accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epochs')
plt.legend(['train', 'validation'])
plt.show()
model.save("/home/someone/Documents/machinelearning/path/model.h5")
'''
evaluation = model.evaluate(test_ds, return_dict=True)
for name, value in evaluation.items():
print(f"{name}: {value:.4f}")
'''
I think its something that is set wrong like a bad number of classes somewhere..
It seems that setting shuffle=True in the dataset, resolved the issue, because somehow just a part of the dataset is used in my model.

I am trying to run a tensorflow visual recognitiontraining on a m1 MacBook Pro but get always the same error

'''import numpy as np
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense, GlobalAveragePooling2D
from keras.preprocessing.image import ImageDataGenerator
from keras.callbacks import ModelCheckpoint, EarlyStopping
from tensorflow.keras.optimizers import Adam
from keras.applications.inception_resnet_v2 import InceptionResNetV2
import glob
n_data = len(glob.glob("raw_data\*"))*64
n_epoch = 50
n_batch = 32
datagen = ImageDataGenerator(
rotation_range=20,
brightness_range=[0.8, 1.2],
shear_range=0.2,
zoom_range=0.2,
fill_mode='nearest',
horizontal_flip=True,
rescale=1. /255,
data_format=None,
validation_split=0.2
)
train_gen = datagen.flow_from_directory(
'./dataset',
target_size = (400, 400),
class_mode = 'categorical',
color_mode = 'rgb',
batch_size = n_batch,
subset="training",
shuffle=True
)
val_gen = datagen.flow_from_directory(
'./dataset',
target_size = (400, 400),
class_mode = 'categorical',
color_mode = 'rgb',
batch_size = n_batch,
subset="validation",
shuffle=True
)
model = Sequential()
base_model = InceptionResNetV2(weights='imagenet', include_top=False, input_shape=(400,400,3))
model.add(base_model)
model.add(GlobalAveragePooling2D())
model.add(Dense(units = 1024, activation="relu"))
#model.add(Dropout(0.2))
#model.add(Dense(units = 1024, activation="relu"))
model.add(Dense(units=13, activation="softmax"))
base_total = len(base_model.layers)
for layer in base_model.layers[:base_total]:
layer.trainable=False
for layer in model.layers[base_total:]:
layer.trainable=True
for layer in model.layers[1:]:
layer.trainable = True
opt = Adam(learning_rate=0.0001)
model.compile(optimizer=opt, loss="categorical_crossentropy", metrics=['accuracy'], run_eagerly=True)
model.summary()
checkpoint = ModelCheckpoint("chess_check.h5", monitor="val_acc", verbose=1, save_bes_only=True, save_weights_onlny=False, mode="auto", period=1)
early = EarlyStopping(monitor="val_acc", min_delta=0, patience=10, verbose=1, mode="auto", restore_best_weights=True)
hist = model.fit_generator(steps_per_epoch = int((0.8*n_data)//n_batch), generator = train_gen, validation_data = val_gen, validation_steps = int((0.2*n_data)//n_batch), epochs=n_epoch, verbose=1, callbacks=[checkpoint, early])
model.save_weights('chess.h5')'''
this is the terminal output:
File "/Users/Coden/.Trash/vs-r/tutorial-en/lib/python3.10/site-packages/keras/engine/training.py", line 1420, in fit
raise ValueError('Unexpected result of train_function '
ValueError: Unexpected result of train_function (Empty logs). Please use Model.compile(..., run_eagerly=True), or tf.config.run_functions_eagerly(True) for more information of where went wrong, or file a issue/bug to tf.keras.
these are the installed packages:
'''
absl-py==1.1.0
astunparse==1.6.3
cachetools==5.2.0
certifi==2022.6.15
charset-normalizer==2.0.12
flatbuffers==1.12
gast==0.4.0
google-auth==2.8.0
google-auth-oauthlib==0.4.6
google-pasta==0.2.0
grpcio==1.46.3
h5py==3.7.0
idna==3.3
keras==2.9.0
Keras-Preprocessing==1.1.2
libclang==14.0.1
Markdown==3.3.7
numpy==1.22.4
oauthlib==3.2.0
opt-einsum==3.3.0
packaging==21.3
Pillow==9.1.1
protobuf==3.19.4
pyasn1==0.4.8
pyasn1-modules==0.2.8
pyparsing==3.0.9
requests==2.28.0
requests-oauthlib==1.3.1
rsa==4.8
scipy==1.8.1
six==1.16.0
tensorboard==2.9.1
tensorboard-data-server==0.6.1
tensorboard-plugin-wit==1.8.1
tensorflow-estimator==2.9.0
tensorflow-macos==2.9.2
termcolor==1.1.0
typing_extensions==4.2.0
urllib3==1.26.9
Werkzeug==2.1.2
wrapt==1.14.1
'''
the code works on a weak windows laptop

Keras model failed to learn anything after changing to use tf.data api

I was trying to convert a simple Keras model to use tf.data api for data loading, but somehow the accuracy remains about 10% during the whole 10 epochs.
In comparison, the original code without using tf.data api can easily achieve about 98% accuracy. Did I do anything wrong?
The version using tf.data api
import math
import tensorflow as tf
import numpy as np
batch_size = 32
def load_data():
mnist = tf.keras.datasets.mnist
(train_data, train_label), (validation_data, validation_label) = mnist.load_data()
train_data, validation_data = train_data / 255.0, validation_data / 255.0
train_label = train_label.astype(np.float32)
return train_data, train_label
def build_model():
class MyModel(tf.keras.Model):
def __init__(self):
super(MyModel, self).__init__(name='my_model')
self.flatten = tf.keras.layers.Flatten()
self.dense_1 = tf.keras.layers.Dense(512, activation=tf.nn.relu)
self.dropout = tf.keras.layers.Dropout(0.2)
self.dense_2 = tf.keras.layers.Dense(10, activation=tf.nn.softmax)
def call(self, inputs):
x = self.flatten(inputs)
x = self.dense_1(x)
x = self.dropout(x)
y = self.dense_2(x)
return y
model = MyModel()
model.compile(optimizer=tf.train.AdamOptimizer(),
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
return model
train_data, train_label = load_data()
train_sample_count = len(train_data)
train_dataset = tf.data.Dataset.from_tensor_slices((train_data, train_label))
train_dataset = train_dataset.batch(batch_size)
train_dataset = train_dataset.repeat()
model = build_model()
model.fit(
train_dataset,
epochs=10,
steps_per_epoch=math.ceil(train_sample_count/batch_size)
)
The version without using tf.data api
# load_data and build_model are exactly same as those in the tf.data api version
train_data, train_label = load_data()
model = build_model()
model.fit(
train_data,
train_label,
epochs=10
)

Why my Keras Image classification prediction always return one value...?

I am using CNN to classify multiple people. People's number is 114 and each has about 120 image dataset.
I use keras and model that is used in dog vs cat classification.
It works well in Dogs and Cat classification.
But this is only return same value in different person image.
It says accuracy 99.12 but not work.
this is my train code
# coding: utf-8
# In[1]:
import os
import cv2
import numpy as np
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OneHotEncoder
from sklearn.cross_validation import train_test_split
from keras import backend as K
from keras import layers, models, optimizers
from keras.preprocessing.image import ImageDataGenerator, img_to_array, array_to_img
from keras.applications.resnet50 import preprocess_input
from keras.utils import np_utils
from numpy import array
# In[2]:
TRAIN_DIR = './Dataset'
train_folder_list = array(os.listdir(TRAIN_DIR))
# In[13]:
X = []
Y = []
# In[14]:
label_encoder = LabelEncoder()
integer_encoded = label_encoder.fit_transform(train_folder_list)
onehot_encoder = OneHotEncoder(sparse=False)
integer_encoded = integer_encoded.reshape(len(integer_encoded), 1)
onehot_encoded = onehot_encoder.fit_transform(integer_encoded)
for idx, index in enumerate(range(len(train_folder_list))):
path = os.path.join(TRAIN_DIR, train_folder_list[index])
path = path + '/'
img_list = os.listdir(path)
for img in img_list:
img_path = os.path.join(path, img)
img = cv2.imread(img_path)
if img is not None:
img = cv2.resize(img, (100, 100))
img = img_to_array(img)
X.append(img)
Y.append(idx)
X = np.array(X, dtype="float") / 255.0
# In[15]:
(X_train, X_test, Y_train, Y_test) = train_test_split(X,Y,test_size=0.2, random_state = 42)
Y_train = np_utils.to_categorical(Y_train, len(train_folder_list))
Y_test = np_utils.to_categorical(Y_test, len(train_folder_list))
print(X_train[0])
# In[17]:
nb_train_samples = len(X_train)
nb_valivation_samples = len(X_test)
batch_size = 32
# In[18]:
print(K.image_data_format())
# In[19]:
model = models.Sequential()
model.add(layers.Conv2D(32, (3,3), input_shape=(100, 100, 3)))
model.add(layers.Activation('relu'))
model.add(layers.MaxPooling2D(pool_size=(2, 2)))
model.add(layers.Conv2D(32, (3, 3)))
model.add(layers.Activation('relu'))
model.add(layers.MaxPooling2D(pool_size=(2, 2)))
model.add(layers.Conv2D(64, (3, 3)))
model.add(layers.Activation('relu'))
model.add(layers.MaxPooling2D(pool_size=(2, 2)))
model.add(layers.Flatten())
model.add(layers.Dense(500))
model.add(layers.Activation('relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(114))
model.add(layers.Activation('softmax'))
model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
model.summary()
# In[20]:
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')
test_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')
# In[21]:
train_generator = train_datagen.flow(X_train, Y_train, batch_size=batch_size)
test_generator = test_datagen.flow(X_test , Y_test, batch_size=batch_size)
print(train_generator)
# In[ ]:
history = model.fit_generator(
train_generator,
steps_per_epoch=nb_train_samples // batch_size,
epochs=3,
validation_data=test_generator,
validation_steps=nb_valivation_samples // batch_size
)
model.save_weights('model_weights.h5')
model.save('model_keras.h5')
and my test code
from keras.models import load_model
import cv2
from keras.applications.resnet50 import preprocess_input
import numpy as np
model = load_model('model_keras.h5')
img = cv2.imread('input_test.jpg')
if img is not None:
img = cv2.resize(img, (100,100), interpolation=cv2.INTER_CUBIC)
img = np.reshape(img,[1,100,100,3])
img = preprocess_input(img)
classes = model.predict_classes(img)
print(classes)
Replace binary_crossentropy with categorical_crossentropy like this:
model.compile(loss='categorical_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])