Keypoints detection implementation - tensorflow

I am working on keypoint detection, specifically identifying the left eye, right eye, and mouth of a cat.
For example, there is a 64x64 image of a cat.
And I created an image with circles on the left eye, right eye, and mouth of the cat.
I have created ImageDataGenerators for normal images:
train_datagen = ImageDataGenerator(
featurewise_center=False,
featurewise_std_normalization=False,
width_shift_range=0.1,
height_shift_range=0.1,
zoom_range=0.2)
train_generator = train_datagen.flow_from_directory(
train_path,
target_size=(64, 64),
batch_size=32,
seed=1,
subset='training')
validation_generator = train_datagen.flow_from_directory(
val_path,
target_size=(64, 64),
batch_size=32,
seed=1,
subset='validation')
Also for images with keypoints:
heatmap_train_datagen = ImageDataGenerator(
featurewise_center=False,
featurewise_std_normalization=False,
width_shift_range=0.1,
height_shift_range=0.1,
zoom_range=0.2)
heatmap_train_generator = heatmap_train_datagen.flow_from_directory(
heatmap_train_path,
target_size=(img_height, img_width),
batch_size=32,
seed=1,
subset='training')
heatmap_validation_generator = heatmap_train_datagen.flow_from_directory(
heatmap_val_path,
target_size=(img_height, img_width),
batch_size=32,
seed=1,
subset='validation')
Then zipped them together:
zipped_train_generator = zip(train_generator, heatmap_train_generator)
I have this model:
Layer (type) Output Shape Param #
input_1 (InputLayer) [(None, 64, 64, 3)] 0
block1_conv1 (Conv2D) (None, 64, 64, 64) 1792
block1_conv2 (Conv2D) (None, 64, 64, 64) 36928
block1_pool (MaxPooling2D) (None, 32, 32, 64) 0
block2_conv1 (Conv2D) (None, 32, 32, 128) 73856
block2_conv2 (Conv2D) (None, 32, 32, 128) 147584
bottleneck_1 (Conv2D) (None, 32, 32, 160) 5243040
bottleneck_2 (Conv2D) (None, 32, 32, 160) 25760
upsample_1 (Conv2DTranspose) (None, 64, 64, 3) 1920
Total params: 5,530,880
Trainable params: 5,530,880
Non-trainable params: 0
I am training the model:
history = model.fit((pair for pair in zipped_train_generator),
epochs=30,
validation_data = (validation_generator,heatmap_validation_generator)
)
It is working for more than 1 hour and it seems never ends:
Is this the right way to detect keypoints? If no, where I am doing wrong? How should I implement it?

Related

ValueError: `logits` and `labels` must have the same shape, received ((None, 10) vs (None, 1))

I am running an Involution Model (based of this example), and I am constantly running into errors during the training stage. This is my error:
ValueError: `logits` and `labels` must have the same shape, received ((None, 10) vs (None, 1)).
Below is the relevant code for dataset loading:
train_datagen = ImageDataGenerator(
rescale=1./255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
test_datagen = ImageDataGenerator(rescale=1./255)
train_ds = train_datagen.flow_from_directory(
'data/train',
target_size=(150, 150),
batch_size=128,
class_mode='binary')
test_ds = test_datagen.flow_from_directory(
'data/test',
target_size=(150, 150),
batch_size=64,
class_mode='binary')`
And this is the code for training:
print("building the involution model...")
inputs = keras.Input(shape=(224, 224, 3))
x, _ = Involution(channel=3, group_number=1, kernel_size=3, stride=1, reduction_ratio=2, name="inv_1")(inputs)
x = keras.layers.ReLU()(x)
x = keras.layers.MaxPooling2D((2, 2))(x)
x, _ = Involution(
channel=3, group_number=1, kernel_size=3, stride=1, reduction_ratio=2, name="inv_2")(x)
x = keras.layers.ReLU()(x)
x = keras.layers.MaxPooling2D((2, 2))(x)
x, _ = Involution(
channel=3, group_number=1, kernel_size=3, stride=1, reduction_ratio=2, name="inv_3")(x)
x = keras.layers.ReLU()(x)
x = keras.layers.Flatten()(x)
x = keras.layers.Dense(64, activation="relu")(x)
outputs = keras.layers.Dense(10)(x)
inv_model = keras.Model(inputs=[inputs], outputs=[outputs], name="inv_model")
print("compiling the involution model...")
inv_model.compile(
optimizer="adam",
loss=keras.losses.BinaryCrossentropy(from_logits=True),
metrics=["accuracy"],
)
print("inv model training...")
inv_hist = inv_model.fit(train_ds, epochs=20, validation_data=test_ds)`
The model itself the same used by Keras, and I have not changed anything except to use my own dataset instead of the CIFAR dataset (model works for me with this dataset). So I am sure there is an error in my data loading, but I am unable to identify what that is.
Model Summary:
Model: "inv_model"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_14 (InputLayer) [(None, 224, 224, 3)] 0
inv_1 (Involution) ((None, 224, 224, 3), 26
(None, 224, 224, 9, 1,
1))
re_lu_39 (ReLU) (None, 224, 224, 3) 0
max_pooling2d_26 (MaxPoolin (None, 112, 112, 3) 0
g2D)
inv_2 (Involution) ((None, 112, 112, 3), 26
(None, 112, 112, 9, 1,
1))
re_lu_40 (ReLU) (None, 112, 112, 3) 0
max_pooling2d_27 (MaxPoolin (None, 56, 56, 3) 0
g2D)
inv_3 (Involution) ((None, 56, 56, 3), 26
(None, 56, 56, 9, 1, 1)
)
re_lu_41 (ReLU) (None, 56, 56, 3) 0
flatten_15 (Flatten) (None, 9408) 0
dense_26 (Dense) (None, 64) 602176
dense_27 (Dense) (None, 10) 650
=================================================================
When you called the train_datagen.flow_from_directory() function, you used class_mode='binary' which means you will have the labels of your images as 0 and 1 only, whereas you are have total 10 predictions i.e. 10 neurons in your final output layer. Hence the labels and logits dosen't match.
Solution: Use class_mode='categorical' which means that there will be as many labels as the number of classes. Do the same in test_datagen as well.

why can't I split my image dataset to 8:1:1?

I try to split my dataset to 8:1:1 and my dataset is in a directory, at first I try this code
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
dir,
validation_split=0.2,
subset="training",
seed=123,
image_size=(img_height, img_width),
batch_size=batch_size)
val_ds = tf.keras.preprocessing.image_dataset_from_directory(
dir,
validation_split=0.1,
subset="validation",
seed=123,
image_size=(img_height, img_width),
batch_size=batch_size)
But it doesn't do that job and just split my directory to val_ds and test_ds
after this, I use this code
# create a data generator
datagen = ImageDataGenerator()
# load and iterate training dataset
train_it = datagen.flow_from_directory(dir, target_size=(32, 32), color_mode='grayscale', class_mode='binary', batch_size=32, shuffle=True, follow_links=False, subset=None, interpolation='nearest')
# load and iterate validation dataset
val_it = datagen.flow_from_directory(dir, target_size=(32, 32), color_mode='grayscale', class_mode='binary', batch_size=32, shuffle=True, follow_links=False, subset=None, interpolation='nearest')
# load and iterate test dataset
test_it = datagen.flow_from_directory(dir, target_size=(32, 32), color_mode='grayscale', class_mode='binary', batch_size=32, shuffle=True, follow_links=False, subset=None, interpolation='nearest')
This code also has a problem with my model so when I use this code My model summary will be like this
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
rescaling_1 (Rescaling) (None, None, None, None) 0
_________________________________________________________________
conv2d_3 (Conv2D) (None, None, None, 32) 320
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, None, None, 32) 0
_________________________________________________________________
conv2d_4 (Conv2D) (None, None, None, 32) 9248
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, None, None, 32) 0
_________________________________________________________________
conv2d_5 (Conv2D) (None, None, None, 32) 9248
_________________________________________________________________
max_pooling2d_5 (MaxPooling2 (None, None, None, 32) 0
_________________________________________________________________
dropout_1 (Dropout) (None, None, None, 32) 0
_________________________________________________________________
flatten_1 (Flatten) (None, None) 0
_________________________________________________________________
dense_2 (Dense) (None, 128) 16512
_________________________________________________________________
dense_3 (Dense) (None, 26) 3354
=================================================================
Total params: 38,682
Trainable params: 38,682
Non-trainable params: 0
_________________________________________________________________
and this is my model
num_classes = 26
model = tf.keras.Sequential([
tf.keras.layers.experimental.preprocessing.Rescaling(1./255),
tf.keras.layers.Conv2D(32, 3, activation='relu'),
tf.keras.layers.MaxPooling2D(),
tf.keras.layers.Conv2D(32, 3, activation='relu'),
tf.keras.layers.MaxPooling2D(),
tf.keras.layers.Conv2D(32, 3, activation='relu'),
tf.keras.layers.MaxPooling2D(),
layers.Dropout(0.2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(num_classes)
])
model.compile(
optimizer='adam',
loss=tf.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
So I need to know How can I split my data without any problem?
You can do the following
import glob # To get the whole path for all the images
'''
Let's consider that your images lie inside 2 folders - 'a' and 'b' which are inside your 'dir' folder. To get paths to each of those images you can use
the below code
'''
image_paths_a = glob.glob('./dir/a/*.jpg') # .jpg if the files ends with jpg
image_paths_b = glob.glob('./dir/b/*.jpg') # to get images from b
images_total = image_paths_a + image_paths_b
# In case you have other folders you can also do this
# to get all images inside all folder in 'dir' folder.
images_total = glob.glob('./dir/*/*.jpg')
# Now get the labels corresponding to these images
# If you have labeled as folder names then you can do it like this
image_labels = [i.split('/')[-2] for i in images_total]
'''
After doing the above you have 2 lists -> 1) Image paths 2) corresponding labels and now you can just use the 'sklearn.model_selection.train_test_split' to get your splits
'''
from sklearn.model_selection import train_test_split
# To set train data and get rest 20% for further split
xtrain, xtest, ytrain, ytest = trian_test_split(images_total,
image_labels,
stratify=image_labels,
random_state=1234,
test_size=0.2)
# get 10%-10% of original data
xvalid, xtest, yvalid, ytest= trian_test_split(xtest,
ytest,
stratify=ytest,
random_state=1234,
test_size=0.5)
'''
Now you can just create a dataset but before that you will create a function to read images from image paths.
'''
def read_img(path, label):
file = tf.io.read_file(path)
img = tf.image.decode_png(file)
# dim1 and dim2 are your desired dimensions
img = tf.image.resize(img, (dim1, dim2))
return img, label
train_dataset = tf.data.Dataset.from_tensor_slices((xtrain, ytrain))
train_dataset = train_dataset.map(read_img).batch(batch_size)
valid_dataset = tf.data.Dataset.from_tensor_slices((xvalid, yvalid))
valid_dataset = valid_dataset.map(read_img).batch(batch_size)
test_dataset = tf.data.Dataset.from_tensor_slices((xtest, ytest))
test_dataset = test_dataset.map(read_img).batch(batch_size)
# Now you just need to train your model
model.fit(train_dataset, epochs=5, validation_data=valid_dataset)

Run time connection loss while trainig VGG 16 model on Google Collaboratory

I'm Training the VGG16 model in colab while running it some time disconnects and reconnect again and sometimes while reaching 20, 21/35 epochs all connection loss and when I reconnect drive mounting restart due to this I lost all outputs, so I have to re-run all code. how can this problem be solved?
Even I'm using only 3000 images dataset for this which is divided into valid, train and test dataset
the code which I Run is
vgg16_model = tf.keras.applications.vgg16.VGG16()
vgg16_model.summary()
model = Sequential()
for layer in vgg16_model.layers[:-1]:
model.add(layer)
for layer in model.layers:
layer.trainable = False
model.add(Dense(units=2, activation='softmax'))
model.summary()
model.compile(optimizer = Adam(learning_rate=0.0001), loss = 'categorical_crossentropy', metrics = ['accuracy'])
model.fit(x=train_batches,
steps_per_epoch=len(train_batches),
validation_data=valid_batches,
validation_steps=len(valid_batches),
epochs=35,
verbose=2
)
I was able to execute sample code using VGG16 without any issues. Please refer working code as shown below
import os
import numpy as np
import tensorflow as tf
from tensorflow.keras.applications import vgg16
from keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.layers import Dense, Dropout, Flatten
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.models import Sequential
from google.colab import drive
drive.mount('/content/drive')
train_dir = '/content/drive/My Drive/Dogs_Vs_Cats/train'
valid_dir = '/content/drive/My Drive/Dogs_Vs_Cats/test'
img_width, img_height = 224, 224
input_shape = (img_width, img_height, 3)
batch_size = 32
train_datagen = ImageDataGenerator(
rescale = 1. /255,
horizontal_flip = True)
valid_datagen = ImageDataGenerator(
rescale = 1. /255)
train_batches = train_datagen.flow_from_directory(
train_dir,
target_size = (img_width, img_height),
batch_size = batch_size,
class_mode = 'binary')
valid_batches = valid_datagen.flow_from_directory(
valid_dir,
target_size = (img_width, img_height),
class_mode = 'binary')
vgg16_model = vgg16.VGG16()
model = Sequential()
for layer in vgg16_model.layers[:-1]:
model.add(layer)
for layer in model.layers:
layer.trainable = False
model.add(Dense(units=1, activation='softmax'))
model.summary()
model.compile(optimizer = Adam(learning_rate=0.0001), loss = 'binary_crossentropy', metrics = ['accuracy'])
model.fit(
train_batches,
steps_per_epoch = 10,
epochs = 2,
validation_data = valid_batches,
verbose = 1,
validation_steps = 32)
Output:
Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount("/content/drive", force_remount=True).
Found 2000 images belonging to 2 classes.
Found 1018 images belonging to 2 classes.
Model: "sequential_2"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
block1_conv1 (Conv2D) (None, 224, 224, 64) 1792
_________________________________________________________________
block1_conv2 (Conv2D) (None, 224, 224, 64) 36928
_________________________________________________________________
block1_pool (MaxPooling2D) (None, 112, 112, 64) 0
_________________________________________________________________
block2_conv1 (Conv2D) (None, 112, 112, 128) 73856
_________________________________________________________________
block2_conv2 (Conv2D) (None, 112, 112, 128) 147584
_________________________________________________________________
block2_pool (MaxPooling2D) (None, 56, 56, 128) 0
_________________________________________________________________
block3_conv1 (Conv2D) (None, 56, 56, 256) 295168
_________________________________________________________________
block3_conv2 (Conv2D) (None, 56, 56, 256) 590080
_________________________________________________________________
block3_conv3 (Conv2D) (None, 56, 56, 256) 590080
_________________________________________________________________
block3_pool (MaxPooling2D) (None, 28, 28, 256) 0
_________________________________________________________________
block4_conv1 (Conv2D) (None, 28, 28, 512) 1180160
_________________________________________________________________
block4_conv2 (Conv2D) (None, 28, 28, 512) 2359808
_________________________________________________________________
block4_conv3 (Conv2D) (None, 28, 28, 512) 2359808
_________________________________________________________________
block4_pool (MaxPooling2D) (None, 14, 14, 512) 0
_________________________________________________________________
block5_conv1 (Conv2D) (None, 14, 14, 512) 2359808
_________________________________________________________________
block5_conv2 (Conv2D) (None, 14, 14, 512) 2359808
_________________________________________________________________
block5_conv3 (Conv2D) (None, 14, 14, 512) 2359808
_________________________________________________________________
block5_pool (MaxPooling2D) (None, 7, 7, 512) 0
_________________________________________________________________
flatten (Flatten) (None, 25088) 0
_________________________________________________________________
fc1 (Dense) (None, 4096) 102764544
_________________________________________________________________
fc2 (Dense) (None, 4096) 16781312
_________________________________________________________________
dense_2 (Dense) (None, 1) 4097
=================================================================
Total params: 134,264,641
Trainable params: 4,097
Non-trainable params: 134,260,544
_________________________________________________________________
Epoch 1/2
10/10 [==============================] - 503s 54s/step - loss: 0.6935 - accuracy: 0.4292 - val_loss: 0.6861 - val_accuracy: 0.4912
Epoch 2/2
10/10 [==============================] - 506s 55s/step - loss: 0.6856 - accuracy: 0.4669 - val_loss: 0.6748 - val_accuracy: 0.4912
Note: To debug your code try with 5 epoch first.
If you are facing session timeout, you can refer solutions discussed in Google Colab session timeout.

Trying to run inference on VGG16 model: InvalidArgumentError: Value for attr 'N' of 1 must be at least minimum 2

Trying to do binary image classification using VGG16 for transfer learning. This is my code for training:
import tensorflow as tf
from tensorflow import keras
from keras.models import Sequential
from keras.layers import Activation, Dense
from keras.optimizers import Adam
from keras.preprocessing.image import ImageDataGenerator
import os
cwd = os.getcwd()
vgg16_model = tf.keras.applications.VGG16(
include_top=True,
weights="imagenet",
input_tensor=None,
input_shape=None,
pooling=None,
classes=1000,
classifier_activation="softmax",
)
vgg16_model._layers.pop()
model = Sequential()
for layer in vgg16_model.layers:
model.add(layer)
for layer in model.layers:
layer.trainable = False
model.add(Dense(4096, activation='relu'))
model.add(Dense(2, activation='softmax'))
model.summary()
model.compile(optimizer=Adam(lr=.0001), loss='binary_crossentropy', metrics=['accuracy'])
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(
cwd + '/images/dd_notadd/train',
target_size=(224, 224),
batch_size=32,
class_mode='binary')
validation_generator = test_datagen.flow_from_directory(
cwd + '/images/dd_notadd/validation',
target_size=(224, 224),
batch_size=32,
class_mode='binary')
model.fit(
train_generator,
steps_per_epoch=10,
epochs=20,
validation_data=validation_generator,
validation_steps=10)
model.save("ddornot.h5")
Then this is my code for inference:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun Mar 7 11:12:16 2021
#author: lennartkonst
"""
import tensorflow as tf
from tensorflow import keras
from keras.models import Sequential
from keras.layers import Activation, Dense
from keras.optimizers import Adam
from keras.preprocessing.image import ImageDataGenerator
import os
import numpy as np
import cv2
cwd = os.getcwd()
vgg16_model = tf.keras.applications.VGG16(
include_top=True,
weights="imagenet",
input_tensor=None,
input_shape=None,
pooling=None,
classes=1000,
classifier_activation="softmax",
)
vgg16_model._layers.pop()
model = Sequential()
for layer in vgg16_model.layers:
model.add(layer)
for layer in model.layers:
layer.trainable = False
model.add(Dense(4096, activation='relu'))
model.add(Dense(2, activation='softmax'))
model.summary()
model.compile(optimizer=Adam(lr=.0001), loss='binary_crossentropy', metrics=['accuracy'])
model.load_weights("ddornot.h5")
testimagefilename = cwd + '/images/dd_notadd/testimage/testimage.jpeg'
img = cv2.imread(testimagefilename)
img = cv2.resize(img,(224,224))
img = np.expand_dims(img, axis=0)
print(img.shape)
img_class = model.predict(img, batch_size=1)
I get the following output on this inference script:
Model: "sequential_29"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
block1_conv1 (Conv2D) (None, 224, 224, 64) 1792
_________________________________________________________________
block1_conv2 (Conv2D) (None, 224, 224, 64) 36928
_________________________________________________________________
block1_pool (MaxPooling2D) (None, 112, 112, 64) 0
_________________________________________________________________
block2_conv1 (Conv2D) (None, 112, 112, 128) 73856
_________________________________________________________________
block2_conv2 (Conv2D) (None, 112, 112, 128) 147584
_________________________________________________________________
block2_pool (MaxPooling2D) (None, 56, 56, 128) 0
_________________________________________________________________
block3_conv1 (Conv2D) (None, 56, 56, 256) 295168
_________________________________________________________________
block3_conv2 (Conv2D) (None, 56, 56, 256) 590080
_________________________________________________________________
block3_conv3 (Conv2D) (None, 56, 56, 256) 590080
_________________________________________________________________
block3_pool (MaxPooling2D) (None, 28, 28, 256) 0
_________________________________________________________________
block4_conv1 (Conv2D) (None, 28, 28, 512) 1180160
_________________________________________________________________
block4_conv2 (Conv2D) (None, 28, 28, 512) 2359808
_________________________________________________________________
block4_conv3 (Conv2D) (None, 28, 28, 512) 2359808
_________________________________________________________________
block4_pool (MaxPooling2D) (None, 14, 14, 512) 0
_________________________________________________________________
block5_conv1 (Conv2D) (None, 14, 14, 512) 2359808
_________________________________________________________________
block5_conv2 (Conv2D) (None, 14, 14, 512) 2359808
_________________________________________________________________
block5_conv3 (Conv2D) (None, 14, 14, 512) 2359808
_________________________________________________________________
block5_pool (MaxPooling2D) (None, 7, 7, 512) 0
_________________________________________________________________
flatten (Flatten) (None, 25088) 0
_________________________________________________________________
fc1 (Dense) (None, 4096) 102764544
_________________________________________________________________
fc2 (Dense) (None, 4096) 16781312
_________________________________________________________________
dense_58 (Dense) (None, 4096) 16781312
_________________________________________________________________
dense_59 (Dense) (None, 2) 8194
=================================================================
Total params: 151,050,050
Trainable params: 16,789,506
Non-trainable params: 134,260,544
_________________________________________________________________
(1, 224, 224, 3)
WARNING:tensorflow:7 out of the last 7 calls to <function Model.make_predict_function.<locals>.predict_function at 0x7fb1487b9280> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating #tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your #tf.function outside of the loop. For (2), #tf.function has experimental_relax_shapes=True option that relaxes argument shapes that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/tutorials/customization/performance#python_or_tensor_args and https://www.tensorflow.org/api_docs/python/tf/function for more details.
Traceback (most recent call last):
File "/Users/lennartkonst/Documents/Twitterbots/Pythonbots/DreamDestinationsBot/ML/ddornotinference.py", line 60, in <module>
img_class = model.predict(img, batch_size=1)
File "/opt/anaconda3/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py", line 130, in _method_wrapper
return method(self, *args, **kwargs)
File "/opt/anaconda3/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py", line 1614, in predict
all_outputs = nest.map_structure_up_to(batch_outputs, concat, outputs)
File "/opt/anaconda3/lib/python3.8/site-packages/tensorflow/python/util/nest.py", line 1135, in map_structure_up_to
return map_structure_with_tuple_paths_up_to(
File "/opt/anaconda3/lib/python3.8/site-packages/tensorflow/python/util/nest.py", line 1234, in map_structure_with_tuple_paths_up_to
results = [func(*args, **kwargs) for args in zip(flat_path_list,
File "/opt/anaconda3/lib/python3.8/site-packages/tensorflow/python/util/nest.py", line 1234, in <listcomp>
results = [func(*args, **kwargs) for args in zip(flat_path_list,
File "/opt/anaconda3/lib/python3.8/site-packages/tensorflow/python/util/nest.py", line 1137, in <lambda>
lambda _, *values: func(*values), # Discards the path arg.
File "/opt/anaconda3/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py", line 2673, in concat
return array_ops.concat(tensors, axis=axis)
File "/opt/anaconda3/lib/python3.8/site-packages/tensorflow/python/util/dispatch.py", line 201, in wrapper
return target(*args, **kwargs)
File "/opt/anaconda3/lib/python3.8/site-packages/tensorflow/python/ops/array_ops.py", line 1654, in concat
return gen_array_ops.concat_v2(values=values, axis=axis, name=name)
File "/opt/anaconda3/lib/python3.8/site-packages/tensorflow/python/ops/gen_array_ops.py", line 1207, in concat_v2
_ops.raise_from_not_ok_status(e, name)
File "/opt/anaconda3/lib/python3.8/site-packages/tensorflow/python/framework/ops.py", line 6843, in raise_from_not_ok_status
six.raise_from(core._status_to_exception(e.code, message), None)
File "<string>", line 3, in raise_from
InvalidArgumentError: Value for attr 'N' of 1 must be at least minimum 2
; NodeDef: {{node ConcatV2}}; Op<name=ConcatV2; signature=values:N*T, axis:Tidx -> output:T; attr=N:int,min=2; attr=T:type; attr=Tidx:type,default=DT_INT32,allowed=[DT_INT32, DT_INT64]> [Op:ConcatV2] name: concat
I don't fully understand what the problem is, I tried several different shapes but I figure the input shape should be just 1,224,224,3.
Any help would be greatly appreciated.
Your generators specify class_mode as binary and you specify the loss as 'binary_crossentropy'. Therefore your dense layer at the top of the model should have a single neuron and the activation='sigmoid. Why do you bother to recreate the whole model for inference since you saved the entire model just load it with
model= keras.models.load_model("ddornot.h5")
You are reading in your test image using cv2. In that case if you have a color image it is in BGR format. Your model was trained on RGB images so you have to convert it with
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
Note in your code for vgg16 you should have set
image_shape=(224,224,3)
Also you can try this for your model
base_model=tf.keras.applications.VGG19( include_top=False, input_shape=(224,224,3), pooling='max', weights='imagenet' )
for layer in base_model.layers:
layer.trainable=False
x=base_model.output
x=tf.keras.layers.BatchNormalization(axis=-1, momentum=0.99, epsilon=0.001 )(x)
x= tf.keras.layers.Dense(1024, activation='relu)(x)
x= tf.keras.layers.Dropout(.2)(x)
predictions=tf.keras.layers.Deense(1, activation='sigmoid)(x)
model=Model(inputs=base_model.input, outputs=predictions)
model.compile(optimizer=Adam(lr=.0001), loss='binary_crossentropy', metrics=['accuracy'])
I finally found a workaround the error. It's still not preferable off course so a good answer where I can just use model.predict() would be awesome.
import tensorflow as tf
from tensorflow import keras
# from keras.models import Sequential
# from keras.layers import Activation, Dense
# from keras.optimizers import Adam
from keras.preprocessing.image import ImageDataGenerator
import os
# import numpy as np
# import cv2
cwd = os.getcwd()
model= keras.models.load_model("ddornot.h5")
model.summary()
validation_datagen = ImageDataGenerator(rescale=1/255)
# Flow validation images in batches of 19 using valid_datagen generator
validation_generator = validation_datagen.flow_from_directory(
cwd + '/images/dd_notadd/testimage', # This is the source directory for validation images
classes = ['dd', 'notadd'],
target_size=(224, 224), # All images will be resized to 200x200
batch_size=1,
# Use binary labels
class_mode='binary',
shuffle=False)
STEP_SIZE_TEST=validation_generator.n//validation_generator.batch_size
validation_generator.reset()
preds = model.predict(validation_generator,
verbose=1)
print(preds)
# testimagefilename = cwd + '/images/dd_notadd/testimage/testimage.jpeg'
# img = cv2.imread(testimagefilename)
# img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
# img = cv2.resize(img,(224,224))
# img = np.expand_dims(img, axis=0)
# print(img.shape)
# img_class = model.predict(img)

Sci-kit Learn Confusion Matrix: Found input variables with inconsistent numbers of samples

I'm trying to plot a confusion matrix between the predicted test labels and the actual ones, but I'm getting this error
ValueError: Found input variables with inconsistent numbers of samples: [1263, 12630]
Dataset: GTSRB
Code used
Image augmentation
train_datagen = ImageDataGenerator(rescale=1./255,
rotation_range=20,
horizontal_flip=True,
width_shift_range=0.1,
height_shift_range=0.1,
shear_range=0.01,
zoom_range=[0.9, 1.25],
brightness_range=[0.5, 1.5])
test_datagen = ImageDataGenerator(rescale=1./255)
train_generator and test_generator
batch_size = 10
train_generator = train_datagen.flow_from_directory(
directory=train_path,
target_size=(224, 224),
color_mode="rgb",
batch_size=batch_size,
class_mode="categorical",
shuffle=True,
seed=42
)
test_generator = test_datagen.flow_from_directory(
directory=test_path,
target_size=(224, 224),
color_mode="rgb",
batch_size=batch_size,
class_mode="categorical",
shuffle=False,
seed=42
)
Output of that code
Found 39209 images belonging to 43 classes.
Found 12630 images belonging to 43 classes.
Then, I used a VGG-16 model and replaced the latest Dense layer with a Dense(43, activation='softmax')
Model summary
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
block1_conv1 (Conv2D) (None, 224, 224, 64) 1792
_________________________________________________________________
block1_conv2 (Conv2D) (None, 224, 224, 64) 36928
_________________________________________________________________
block1_pool (MaxPooling2D) (None, 112, 112, 64) 0
_________________________________________________________________
block2_conv1 (Conv2D) (None, 112, 112, 128) 73856
_________________________________________________________________
block2_conv2 (Conv2D) (None, 112, 112, 128) 147584
_________________________________________________________________
block2_pool (MaxPooling2D) (None, 56, 56, 128) 0
_________________________________________________________________
block3_conv1 (Conv2D) (None, 56, 56, 256) 295168
_________________________________________________________________
block3_conv2 (Conv2D) (None, 56, 56, 256) 590080
_________________________________________________________________
block3_conv3 (Conv2D) (None, 56, 56, 256) 590080
_________________________________________________________________
block3_pool (MaxPooling2D) (None, 28, 28, 256) 0
_________________________________________________________________
block4_conv1 (Conv2D) (None, 28, 28, 512) 1180160
_________________________________________________________________
block4_conv2 (Conv2D) (None, 28, 28, 512) 2359808
_________________________________________________________________
block4_conv3 (Conv2D) (None, 28, 28, 512) 2359808
_________________________________________________________________
block4_pool (MaxPooling2D) (None, 14, 14, 512) 0
_________________________________________________________________
block5_conv1 (Conv2D) (None, 14, 14, 512) 2359808
_________________________________________________________________
block5_conv2 (Conv2D) (None, 14, 14, 512) 2359808
_________________________________________________________________
block5_conv3 (Conv2D) (None, 14, 14, 512) 2359808
_________________________________________________________________
block5_pool (MaxPooling2D) (None, 7, 7, 512) 0
_________________________________________________________________
flatten (Flatten) (None, 25088) 0
_________________________________________________________________
fc1 (Dense) (None, 4096) 102764544
_________________________________________________________________
fc2 (Dense) (None, 4096) 16781312
_________________________________________________________________
predictions (Dense) (None, 1000) 4097000
_________________________________________________________________
dense_1 (Dense) (None, 43) 43043
=================================================================
Total params: 138,400,587
Trainable params: 43,043
Non-trainable params: 138,357,544
_________________________________________________________________
Compile the model
my_sgd = SGD(lr=0.01)
model.compile(
optimizer=my_sgd,
loss='categorical_crossentropy',
metrics=['accuracy']
)
Train the model
STEP_SIZE_TRAIN=train_generator.n//train_generator.batch_size
epochs=10
model.fit_generator(generator=train_generator,
steps_per_epoch=STEP_SIZE_TRAIN,
epochs=epochs,
verbose=1
)
Predictions
STEP_SIZE_TEST=test_generator.n//test_generator.batch_size
test_generator.reset()
predictions = model.predict_generator(test_generator, steps=STEP_SIZE_TEST, verbose=1)
Output
1263/1263 [==============================] - 229s 181ms/step
Predictions shape
print(predictions.shape)
(12630, 43)
Getting the test_data and test_labels
test_data = []
test_labels = []
batch_index = 0
while batch_index <= test_generator.batch_index:
data = next(test_generator)
test_data.append(data[0])
test_labels.append(data[1])
batch_index = batch_index + 1
test_data_array = np.asarray(test_data)
test_labels_array = np.asarray(test_labels)
Shape of test_data_array and test_labels_array
test_data_array.shape
(1263, 10, 224, 224, 3)
test_labels_array.shape
(1263, 10, 43)
Confusion Matrix
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(test_labels_array, predictions)
I get the output
ValueError: Found input variables with inconsistent numbers of samples: [1263, 12630]
I understand that this error is because the test_labels_array size isn't equal to the predictions; 1263 and 12630 respectively, but I don't really know what I'm doing wrong.
Any help would be much appreciated.
PS: If anyone has any tips on how to increase the training accuracy while we're at it, that would be brilliant.
Thanks!
You should reshape test_data_array and test_labels_array as follows:
data_count, batch_count, w, h, c = test_data_array.shape
test_data_array=np.reshape(test_data_array, (data_count*batch_count, w, h, c))
test_labels_array = np.reshape(test_labels_array , (data_count*batch_count, -1))
the way you are appending the results of test_generator is the reason. In fact the first call of your test_generator will generate 10 data with shape of (224, 224, 3). For the next call again your test_generator will generate 10 data with shape of (224, 224, 3). So now you should have 20 data of shape (224, 224, 3) while the way you are appending the results would cause that you came up with 2 data of shape (10, 224, 224, 3). which is not what you are expecting.