Issue
I'm trying to train a simple binary classification model using Keras
and Tensorflow
on a dataset of around 21,000 images. But when I run the training code, it throws this error:
Traceback (most recent call last):
File "train.py", line 83, in <module>
training_images = np.array([i[0] for i in training_data])
ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 3 dimensions. The detected shape was (21527, 300, 300) + inhomogeneous part.
I used this dataset and the training code before, so not sure what is causing the problem now. What is the issue? How to fix this?
Here is my simple training code that loads the dataset and tries training/fitting the model:
from keras.models import Sequential, load_model
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import BatchNormalization
from PIL import Image
from random import shuffle, choice
import numpy as np
import os
from keras.callbacks import ModelCheckpoint
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential, Model
from sklearn.model_selection import train_test_split
from keras import optimizers
IMAGE_SIZE = 300
epochs_num = 50
batch_size = 64
IMAGE_DIRECTORY = './data'
retrain_from_prior_model=True
def label_img(name):
if name == 'object': return np.array([1, 0])
elif name == 'none' : return np.array([0, 1])
def load_data():
print("Loading images...")
train_data = []
directories = next(os.walk(IMAGE_DIRECTORY))[1]
for dirname in directories:
print("Loading {0}".format(dirname))
file_names = next(os.walk(os.path.join(IMAGE_DIRECTORY, dirname)))[2]
for i in range(len(file_names)):
image_name = choice(file_names)
image_path = os.path.join(IMAGE_DIRECTORY, dirname, image_name)
label = label_img(dirname)
if "DS_Store" not in image_path:
try:
img = Image.open(image_path)
img = img.resize((IMAGE_SIZE, IMAGE_SIZE), Image.LANCZOS)
train_data.append([np.array(img), label])
except Exception as e:
print(f"Error processing image: {image_path}")
print(f"Error message: {str(e)}")
continue # Skip this image and continue with the next one
shuffle(train_data)
return train_data
def create_model():
channels = 3
model = Sequential()
#change first one to 64
model.add(Conv2D(32, kernel_size = (5, 5), activation='relu', input_shape=(IMAGE_SIZE, IMAGE_SIZE, channels)))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
model.add(Conv2D(64, kernel_size=(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
model.add(Conv2D(128, kernel_size=(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
model.add(Conv2D(256, kernel_size=(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
model.add(Conv2D(64, kernel_size=(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(BatchNormalization())
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(128, activation='relu'))
model.add(Dense(2, activation = 'softmax'))
return model
training_data = load_data()
training_images = np.array([i[0] for i in training_data])
training_labels = np.array([i[1] for i in training_data])
print(str(len(training_images)))
# Split the data
training_images, validation_images, training_labels, validation_labels = train_test_split(training_images, training_labels, test_size=0.2, shuffle= True)
print(str(len(training_images)))
print('creating model')
#========================
if retrain_from_prior_model == False:
model = create_model()
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
print('training model...model.count_params: '+str(model.count_params()) + '...model.count_layers: '+ str(len(model.layers)))
else:
model = load_model("model_0.989.h5")
model.compile(loss='binary_crossentropy', optimizer= optimizers.Adam(learning_rate=0.0001), metrics=['accuracy'])
filepath="./checkpoints/model_{epoch:03d}_{accuracy:.4f}_{val_accuracy:.4f}_{val_loss:.7f}.h5"
checkpoint = ModelCheckpoint(filepath, monitor=["accuracy"], verbose=1, mode='max', save_weights_only=False)
callbacks_list = [checkpoint]
# if you want data augmentation: rotation_range=20, width_shift_range=0.2, height_shift_range=0.2, brightness_range=[0.9,1.1]
datagen = ImageDataGenerator(zoom_range=0.2, horizontal_flip=True)
datagen.fit(training_images)
train_gen=datagen.flow(training_images, training_labels, batch_size=batch_size)
#validation
val_datagen = ImageDataGenerator(horizontal_flip=True)
val_datagen.fit(training_images)
val_gen=datagen.flow(validation_images, validation_labels, batch_size=batch_size)
model.fit(train_gen, validation_data=val_gen, epochs=epochs_num, verbose=1, callbacks=callbacks_list)
print('Training finished. Model saved.')
Solution
The problem was that apparently there are some grayscale images (1 channel) in my dataset that caused errors. So I added this line in load_data()
to make sure only 3-channel images are added and it fixed the problem:
if img.mode != 'RGB':
continue # Skip grayscale images if colored flag is True
Answered By - Mary
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.