Checking input con2d - python-3.x

I am new to ML I receive the error when I try to fit my model. I am trying to train a cat classifier.
Defining the new model
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(150, 150, 3)),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(128, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(128, (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(1, activation='sigmoid')
])
model.compile(loss='binary_crossentropy',
optimizer=RMSprop(lr=1e-4),
metrics=['acc'])
# All images will be rescaled by 1./255
train_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)
# Flow training images in batches of 20 using train_datagen generator
train_generator = train_datagen.flow_from_directory(
train_dir, # This is the source directory for training images
target_size=(250, 250), # All images will be resized to 150x150
batch_size=20,
# Since we use binary_crossentropy loss, we need binary labels
class_mode='binary')
Flow validation images in batches of 20 using test_datagen generator
validation_generator = test_datagen.flow_from_directory(
validation_dir,
target_size=(250, 250),
batch_size=20,
class_mode='binary')
Fir the model on data
history = model.fit_generator(
train_generator,
steps_per_epoch=100, # 2000 images = batch_size * steps
epochs=100,
validation_data=validation_generator,
validation_steps=50, # 1000 images = batch_size * steps
verbose=2)
Here I am trying to fit the model but I end up with an error of input. Please check where did I went wrong.

This error can be removed if you do 2 changes at your code here:
target_size=(150, 150) even your comment say so. So why you are trying to use 250 I don't understand

Related

ValueError when using keras ImageDataGenerator

I'm trying to run this code from: https://gist.github.com/fchollet/0830affa1f7f19fd47b06d4cf89ed44d
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras import backend as K
# dimensions of our images.
img_width, img_height = 150, 150
train_data_dir = './data/train'
validation_data_dir = './data/validation'
nb_train_samples = 2000
nb_validation_samples = 800
epochs = 50
batch_size = 16
if K.image_data_format() == 'channels_first':
input_shape = (3, img_width, img_height)
else:
input_shape = (img_width, img_height, 3)
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'))
model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
# this is the augmentation configuration we will use for training
train_datagen = ImageDataGenerator(
rescale=1. / 255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
# this is the augmentation configuration we will use for testing:
# only rescaling
test_datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='binary')
validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='binary')
model.fit_generator(
train_generator,
steps_per_epoch=nb_train_samples // batch_size,
epochs=epochs,
validation_data=validation_generator,
validation_steps=nb_validation_samples // batch_size)
model.save_weights('first_try.h5')
I've tried using a few different version of python3, even tried it in a ubuntu virtualbox but I still keep getting this error...
C:\Users\David\Desktop\ai\dcgan_cp.py:70: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.
model.fit_generator(
Traceback (most recent call last):
File "C:\Users\David\Desktop\ai\dcgan_cp.py", line 70, in <module>
model.fit_generator(
File "C:\python3\lib\site-packages\keras\engine\training.py", line 2016, in fit_generator
return self.fit(
File "C:\python3\lib\site-packages\keras\utils\traceback_utils.py", line 67, in error_handler
raise e.with_traceback(filtered_tb) from None
File "C:\python3\lib\site-packages\keras_preprocessing\image\iterator.py", line 54, in __getitem__
raise ValueError('Asked to retrieve element {idx}, '
ValueError: Asked to retrieve element 0, but the Sequence has length 0
I can easily fix the warning by removing _generator but I can't get this code to work. Can anyone help fix this issue? Is there a way to test the directory iterator to see if that is the problem?
This above error ValueError: Asked to retrieve element 0, but the Sequence has length 0 is because there is no images folder defined inside these folders.
train_data_dir = './data/train'
validation_data_dir = './data/validation'
You need to create 2 folders(Cats,Dogs) inside train and 2 folders(Cats,Dogs) inside validation folder and
keep all the training
Cats images inside /data/train/Cats/*.jpg and
Dogs images inside /data/train/Dogs/*.jpg.
and same way all the validation
Cats images inside /data/validation/Cats/*.jpg and
Dogs images inside /data/validation/Dogs/*.jpg.
You can download the dataset from this link.
Make sure your training images are atleast 2000 images and validation image count are atleast 800 images to satisfy this below code for further use:
nb_train_samples = 2000
nb_validation_samples = 800

How do I display metrics after fitting a Keras model

I am learning about neural networks with Kaggle tutorials. I have made a neural net to predict concrete strength and I want to display the MSE (for starters) metric after fitting the model. I have failed both with print(metrics) and plotting the metrics (displays an empty graph).
df = concrete.copy()
df_train = df.sample(frac=0.7, random_state=0)
df_valid = df.drop(df_train.index)
X_train = df_train.drop('CompressiveStrength', axis=1)
X_valid = df_valid.drop('CompressiveStrength', axis=1)
y_train = df_train['CompressiveStrength']
y_valid = df_valid['CompressiveStrength']
model = keras.Sequential([
layers.BatchNormalization(),
layers.Dense(512, activation='relu', input_shape=input_shape),
layers.BatchNormalization(),
layers.Dense(512, activation='relu'),
layers.Dropout(rate=0.3), # apply 30% dropout to the next layer
layers.Dense(512, activation='relu'),
layers.BatchNormalization(),
layers.Dense(512, activation='relu'),
layers.BatchNormalization(),
layers.Dense(1),
])
model.compile(
optimizer='sgd', # SGD is more sensitive to differences of scale
loss='mse',
metrics=[tf.keras.metrics.MeanSquaredError()]
)
history = model.fit(
X_train, y_train,
validation_data=(X_valid, y_valid),
batch_size=64,
epochs=100,
verbose=0,
callbacks=[early_stopping],
)
print(history)
pyplot.plot(history.history['mean_squared_error'])

Keras CNN model always return [0.5 0.5]

Can anyone help me with this issue? My model always return 1 class. The source code is below:
I want to classify images (binary). The model generated good accuracy. Now, I need to test the model which new images, I loaded the model and try to predict the class but it always return 0.
batch_size = 30
epochs = 50
IMG_HEIGHT = 224
IMG_WIDTH = 224
image_gen_train = ImageDataGenerator(
rotation_range=15,
width_shift_range=0.01,
height_shift_range=0.01,
rescale=1./255,
shear_range=0.1,
fill_mode='nearest',
validation_split=0.2)
train_data_gen = image_gen_train.flow_from_directory(batch_size=batch_size,
directory=dataset_dir,
shuffle=True,
target_size=(IMG_HEIGHT, IMG_WIDTH),
subset='training',
class_mode='binary') # set as training data
val_data_gen = image_gen_train.flow_from_directory(batch_size=batch_size,
directory=dataset_dir,
shuffle=False,
target_size=(IMG_HEIGHT, IMG_WIDTH),
subset='validation',
class_mode='binary') # set as validation data
sample_training_images, _ = next(train_data_gen)
# This function will plot images in the form of a grid with 1 row and 5 columns where images are placed in each column.
def plotImages(images_arr):
fig, axes = plt.subplots(1, 4, figsize=(20,20))
axes = axes.flatten()
for img, ax in zip( images_arr, axes):
ax.imshow(img)
ax.axis('off')
plt.tight_layout()
plt.savefig('xray_new.png')
plt.clf()
plotImages(sample_training_images[:4])
#the model
model = Sequential()
model.add(Conv2D(64, kernel_size= (3,3), input_shape=(IMG_HEIGHT, IMG_WIDTH, 3),padding='same'))
model.add(BatchNormalization(momentum=0.5, epsilon=1e-5, gamma_initializer="uniform"))
model.add(LeakyReLU(alpha=0.1))
model.add(Conv2D(64, kernel_size=(3,3), padding='same'))
model.add(BatchNormalization(momentum=0.1, epsilon=1e-5, gamma_initializer="uniform"))
model.add(LeakyReLU(alpha=0.1))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.35))
model.add(Conv2D(128, kernel_size =(3,3),padding='same'))
model.add(BatchNormalization(momentum=0.2, epsilon=1e-5, gamma_initializer="uniform"))
model.add(LeakyReLU(alpha=0.1))
model.add(BatchNormalization(momentum=0.1, epsilon=1e-5, gamma_initializer="uniform"))
model.add(LeakyReLU(alpha=0.1))
model.add(Conv2D(128,(3,3), padding='same' ))
model.add(BatchNormalization(momentum=0.1, epsilon=1e-5, gamma_initializer="uniform"))
model.add(LeakyReLU(alpha=0.1))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.35))
model.add(Conv2D(256, kernel_size = (3,3), padding='same'))
model.add(BatchNormalization(momentum=0.2, epsilon=1e-5, gamma_initializer="uniform"))
model.add(LeakyReLU(alpha=0.1))
model.add(Conv2D(256, kernel_size= (3,3) ,padding='same'))
model.add(BatchNormalization(momentum=0.1, epsilon=1e-5, gamma_initializer="uniform"))
model.add(LeakyReLU(alpha=0.1))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.35))
model.add(Flatten())
model.add(Dense(256))
model.add(LeakyReLU(alpha=0.1))
model.add(BatchNormalization())
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])
#model.summary()
model.save("model.h5")
history = model.fit_generator(
train_data_gen,
steps_per_epoch= train_data_gen.samples // batch_size,
epochs=epochs,
validation_data=val_data_gen,
validation_steps= val_data_gen.samples // batch_size,verbose=1)
But when I test the model, it always output 1 class:
filepath = 'model.h5'
model = load_model(filepath,compile=True)
def test(model,image_path):
test_image = image.load_img(image_path, target_size=(IMG_HEIGHT, IMG_WIDTH))
test_image = image.img_to_array(test_image)
test_image = np.expand_dims(test_image, axis=0)
# predict the result
prediction = model.predict(test_image)
print(prediction)
if prediction[0][0] == 1:
my = 'Normal'
else:
my = 'Asthma'
print(my)
prediction = np.argmax(prediction)
labels = (train_data_gen.class_indices)
labels = dict((v,k) for k,v in labels.items())
return labels[prediction]
I really appreciate your help!
I think you forgot to divide your input image by 255. in your test part.
After finding the prediction value don't check it against 1. model.predict() always returns a value between 0 and 1.
So you can change your if condition to the following:
if prediction[0][0] > 0.5: my = 'Normal'
else: my = 'asthama'
I think this should solve your problem.

Multiclass Dataset Imbalance

from tensorflow.keras.preprocessing.image import ImageDataGenerator
import tensorflow as tf
train_path = 'Skin/Train'
test_path = 'Skin/Test'
train_gen = ImageDataGenerator(rescale=1./255)
train_generator = train_gen.flow_from_directory(train_path,target_size=
(300,300),batch_size=30,class_mode='categorical')
model = tf.keras.models.Sequential([
# Note the input shape is the desired size of the image 300x300 with 3 bytes color
# This is the first convolution
tf.keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(600, 450, 3)),
tf.keras.layers.MaxPooling2D(2, 2),
# The second convolution
tf.keras.layers.Conv2D(32, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
# The third convolution
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
# The fourth convolution
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
# The fifth convolution
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
# Flatten the results to feed into a DNN
tf.keras.layers.Flatten(),
# 512 neuron hidden layer
tf.keras.layers.Dense(512, activation='relu'),
tf.keras.layers.Dense(9, activation='softmax')
])
from tensorflow.keras.optimizers import RMSprop
model.compile(loss='categorical_crossentropy',
optimizer=RMSprop(lr=0.001),
metrics=['acc'])
history = model.fit_generator(
train_generator,
steps_per_epoch=8,
epochs=15,
verbose=2, class_weight = ? )
I have issue in achieving accuracy, I am training a 9 classes dataset, in which class 1 , 4, and 5 have only 100, 96, 90 images while the remaining classes are having above 500 images. Due to which I am unable to achieve higher accuracy as the weights are skewed toward images which are higher in number. I want that during training all classes are considered equal i.e 500. Would be appreciated if I could upsample the classes via tensorflow or any keras function code. rather than manually upsampling or downsampling the images in folders.
You can, instead, use a class_weight argument in your fit method.
For upsampling, you need a lot of manual work, that's inevitable.
Assuming you have an output with shape (anything, 9), and you know the totals of each class:
totals = np.array([500,100,500,500,96,90,.......])
totalMean = totals.mean()
weights = {i: totalMean / count for i, count in enumerate(totals)}
model.fit(....., class_weight = weights)

LSTM Grid Search

I have a code below which implements an architecture (in grid search), to yield appropriate parameters for input, nodes, epochs, batch size and differenced time series input.
The challenge I have is to convert the neural network from just having one LSTM hidden layer, to multiple LSTM hidden layers.
At the moment, I could only run the code with Dense-type hidden layers, without having any errors thrown, otherwise I get dimension errors, tuple errors and so on.
The problem is only persistent in the neural network architecture section.
Original code that works:
def model_fit(train, config):
# unpack config
n_input, n_nodes, n_epochs, n_batch, n_diff = config
# Data
if n_diff > 0:
train = difference(train, n_diff)
# Time series to supervised format
data = series_to_supervised(train, n_in=n_input)
train_x, train_y = data[:, :-1], data[:, -1]
# Reshaping input data into [samples, timesteps, features]
n_features = 1
train_x = train_x.reshape((train_x.shape[0], train_x.shape[1], n_features))
# Define model for (Grid search architecture)
model = Sequential()
model.add(LSTM(n_nodes, activation='relu', input_shape=(n_input, n_features)))
model.add(Dense(n_nodes, activation='relu'))
model.add(Dense(n_nodes, activation='relu'))
model.add(Dense(n_nodes, activation='relu'))
model.add(Dense(1))
# Compile model (Grid search architecture)
model.compile(loss='mse', optimizer='adam')
# fit model
model.fit(train_x, train_y, epochs=n_epochs, batch_size=n_batch, verbose=0)
return model
Modified LSTM-hidden layer code, that fails to run:
# Define model for (Grid search architecture)
model = Sequential()
model.add(LSTM(n_nodes, activation='relu', input_shape=(n_input, n_features), return_sequences=True))
model.add(LSTM(n_nodes, activation='relu', return_sequences=True))
model.add(LSTM(n_nodes, activation='relu', return_sequences=True))
model.add(LSTM(n_nodes, activation='relu', return_sequences=True))
model.add(TimeDistributed(Dense(1)))
Another variant that also threw an error - ValueError: Error when checking target: expected time_distributed_4 to have 3 dimensions, but got array with shape (34844, 1)
model = Sequential()
model.add(LSTM(n_nodes, activation='relu', input_shape=(n_input, n_features), return_sequences=True))
model.add(LSTM(n_nodes, activation='relu', return_sequences=False))
model.add(RepeatVector(n_input))
model.add(LSTM(n_nodes, activation='relu', return_sequences=True))
model.add(LSTM(n_nodes, activation='relu', return_sequences=True))
model.add(TimeDistributed(Dense(n_features)))
Could anyone with any suggestion please help me ?
Try to set return_sequences=False at the last layer.

Resources