CNN-LSTM Data Preprocessing Issue - python

I am trying to take my CNN model and add a LSTM layer. It would be beneficial to do so given my images are ordered in time series. I've loaded each of my images using ImageDataGenerator and flow_from_directory. I am unable to add a TimeDistributed layer to make my model work. Any help would be greatly appreciated!
model = Sequential()
model.add(TimeDistributed(Conv2D(16, (3,3), padding='same', strides=(2,2),
activation='relu', input_shape = (224,224,3))))
model.add(TimeDistributed(MaxPooling2D(pool_size=(2, 2))))
model.add(Dropout(0.5))
model.add(TimeDistributed(Conv2D(32, (3,3), padding='same', strides=(2,2),
activation='relu')))
model.add(TimeDistributed(MaxPooling2D(pool_size=(2, 2))))
model.add(Dropout(0.5))
model.add(TimeDistributed(Conv2D(64, (3,3), padding='same', strides=(2,2),
activation='relu')))
model.add(TimeDistributed(MaxPooling2D(pool_size=(2, 2))))
model.add(Dropout(0.5))
model.add(TimeDistributed(Flatten()))
model.add(LSTM(units=128, return_sequences=False))
model.add(LSTM(units=64, return_sequences=False))
model.add(Dense(32))
model.add(Dense(2, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
filenames = os.listdir("train/")
categories = []
for f_name in filenames:
decision = f_name.split('.')[0]
if decision == 'cat':
categories.append(0)
if decision == 'dog':
categories.append(1)
dataset = pd.DataFrame({
'filename':filenames,
'category':categories
})
dataset["category"] = dataset["category"].replace({0: 'cat', 1: 'dog'})
train_df,validate_df = train_test_split(dataset, test_size=0.20,random_state=42)
train_df = train_df.reset_index(drop=True)
validate_df = validate_df.reset_index(drop=True)
total_train = train_df.shape[0]
total_validate = validate_df.shape[0]
train_datagen = ImageDataGenerator(
rescale=1./255,
horizontal_flip=False)
train_generator = train_datagen.flow_from_directory(train_df,
"train/",
x_col='filename',
y_col='category',
target_size=img_size,
color_mode='rgb',
class_mode='categorical',
shuffle=True,
batch_size=batch_size)
validation_datagen = ImageDataGenerator(
rescale=1./255,
horizontal_flip=False)
validation_generator = validation_datagen.flow_from_directory(
validate_df,
"train/",
x_col='filename',
y_col='category',
target_size=img_size,
color_mode='rgb',
class_mode='categorical',
shuffle=False,
batch_size=batch_size
)
model.fit_generator(
train_generator,
epochs=epochs,
validation_data=validation_generator,
validation_steps=total_validate//batch_size,
steps_per_epoch=total_train//batch_size,
callbacks=callbacks,
class_weight=class_weight
)

Related

Keras, Google colab freezes on the last step of first epoch

The code :
from google.colab import drive
import tensorflow as tf
from tensorflow.python.keras.models import Sequential
from tensorflow.python.keras.layers import Dense, Conv2D, MaxPool2D, Flatten
from tensorflow.python.keras.optimizer_v1 import Adam
import numpy as np
import cv2
import matplotlib.pyplot as plt
from tensorflow.python.keras.callbacks import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau
device_list = tf.test.gpu_device_name()
if device_list != '/device:GPU:0':
raise SystemError('GPU device not found')
print('Found GPU at: {}'.format(device_list))
datagen_train = tf.keras.preprocessing.image.ImageDataGenerator()
datagen_val = tf.keras.preprocessing.image.ImageDataGenerator()
datagen_test = tf.keras.preprocessing.image.ImageDataGenerator()
size = 128
batch_size=20
tf.compat.v1.disable_eager_execution()
train_set = datagen_train.flow_from_directory("drive/MyDrive/train",
target_size = (size,size),
color_mode = "grayscale",
batch_size = batch_size,
class_mode='categorical',
shuffle=True)
val_set = datagen_val.flow_from_directory("drive/MyDrive/valid",
target_size = (size,size),
color_mode = "grayscale",
batch_size = batch_size,
class_mode='categorical',
shuffle=True)
test_set = datagen_train.flow_from_directory("drive/MyDrive/test",
target_size = (size,size),
color_mode = "grayscale",
batch_size = batch_size,
class_mode='categorical',
shuffle=True)
imgs,labels = next(test_set)
model = Sequential([
Conv2D(filters=64, kernel_size=(3,3), padding='same', activation='relu', input_shape=(128,128,1)),
MaxPool2D(pool_size =(2,2), strides=2),
Conv2D(filters=128, kernel_size=(3,3), padding='same', activation='relu'),
MaxPool2D(pool_size =(2,2), strides=2),
Conv2D(filters=256, kernel_size=(3,3), padding='same', activation='relu'),
MaxPool2D(pool_size =(2,2), strides=2),
Conv2D(filters=512, kernel_size=(3,3), padding='same', activation='relu'),
MaxPool2D(pool_size =(2,2), strides=2),
Flatten(),
Dense(units=256, activation='relu'),
Dense(units=512, activation='relu'),
Dense(units=2, activation='softmax')
])
checkpoint = ModelCheckpoint("./model.h5", monitor = 'val_acc', verbose=1, save_best_only = True, mode='max')
earlystopping = EarlyStopping(monitor='vall_loss', min_delta=0, patience=3, verbose=1,restore_best_weights= True)
reducelearningrate = ReduceLROnPlateau(monitor='val_loss', factor=0.2,patience=3,verbose=1,min_delta=0.0001)
callbacks_list = [earlystopping,checkpoint,reducelearningrate]
ep = 30
opt = Adam(lr=0.0001)
model.summary()
model.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(x=train_set, epochs=ep,steps_per_epoch=601, validation_data = val_set, validation_steps = 209, verbose=1)
model.save('Drowsines_Detector2.h5')
model.evaluate(x = imgs, y = labels, verbose = 2)
The program on first run in google colab takes 1hour and 30 mins in first epoch. Then if gets stuck on the first epoch step 601/601. Then by cancelling it ang rerunning it, it completes the first epoch very fast, like in 15 or 16 secs. Then sometimes it gets stuck on step 600/601. And sometimes gets stuck on step 601/601. But it does not continue to second epoch. How can I fix this.

How to fix failed assertion `output channels should be divisible by group' when trying to fit the model in Keras?

I'm trying to use ImageDataGenerator() for my image datasets.
Here is my image augmentation code:
batch_size = 16
train_datagen = ImageDataGenerator(
rescale=1./255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
test_datagen = ImageDataGenerator(rescale=1./255)
# Use flow from dataframe
train_generator = train_datagen.flow_from_dataframe(
dataframe=train,
directory="data/train",
x_col="id",
y_col=["not_ready", "ready"],
target_size=(300, 300),
batch_size=batch_size,
class_mode="raw",
validate_filenames=False)
validation_generator = test_datagen.flow_from_dataframe(
dataframe=validation,
directory="data/validation",
x_col="id",
y_col=["not_ready", "ready"],
target_size=(300, 300),
batch_size=batch_size,
class_mode="raw",
validate_filenames=False)
Then use that plug into my model:
model = Sequential([
layers.Conv2D(filters=16, kernel_size=(3, 3), activation='relu', input_shape=(300, 300, 1)),
layers.MaxPooling2D(pool_size=(2, 2)),
layers.Dropout(0.5),
layers.Conv2D(filters=32, kernel_size=(3, 3), activation='relu'),
layers.MaxPooling2D(pool_size=(2, 2)),
layers.Dropout(0.5),
layers.Flatten(),
layers.Dense(64, activation='relu'),
layers.Dropout(0.5),
layers.Dense(32, activation='relu'),
layers.Dropout(0.5),
layers.Dense(2, activation='sigmoid')
])
Use EarlyStopping:
early_stopping = EarlyStopping(monitor='val_loss',mode='min',verbose=1,patience=10, restore_best_weights=True)
Compile and Fit the model:
model.compile(optimizer=Adam(), loss='binary_crossentropy', metrics=['accuracy'])
history = model.fit(
train_generator,
steps_per_epoch=train_generator.n // batch_size,
epochs=100,
validation_data=validation_generator,
validation_steps=validation_generator.n // batch_size,
callbacks=[early_stopping])
That is when the code crash, and gives this error message.
/AppleInternal/Library/BuildRoots/8d3bda53-8d9c-11ec-abd7-fa6a1964e34e/Library/Caches/com.apple.xbs/Sources/MetalPerformanceShaders/MPSNDArray/Kernels/MPSNDArrayConvolution.mm:2317: failed assertion `output channels should be divisible by group'
I try to change the output neurons but that doesn't work. I don't know what to do anymore. Please help me. Thank you so much.
Got it. Because I use grayscale images. So I have to add color_mode keyword argument in both flow_from_dataframe() and set it equal to "grayscale"
train_generator = train_datagen.flow_from_dataframe(
dataframe=train,
directory="data/train",
x_col="id",
y_col=["not_ready", "ready"],
target_size=(300, 300),
batch_size=batch_size,
class_mode="raw",
color_mode="grayscale")
validation_generator = test_datagen.flow_from_dataframe(
dataframe=validation,
directory="data/validation",
x_col="id",
y_col=["not_ready", "ready"],
target_size=(300, 300),
batch_size=batch_size,
class_mode="raw",
color_mode="grayscale")

how to load model and restore training tensorflow

I want to load the training model and resume it from last checkpoint any can help me with that?
I am using tensorflow 2.0 . I have low specs pc so I can't train my model at once.
import tensorflow as tf
from tensorflow.keras import models, layers
import matplotlib.pyplot as plt
from tensorflow.python.keras.metrics import acc
import datetime
from tensorflow.keras.callbacks import TensorBoard
IMAGE_SIZE = 224
CHANNELS = 3
from tensorflow.keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(
rescale=1./255,
rotation_range=10,
horizontal_flip=True
)
train_generator = train_datagen.flow_from_directory(
'data/train/',
color_mode="rgb",
target_size=(IMAGE_SIZE,IMAGE_SIZE),
batch_size=32,
class_mode="sparse",
)
print(train_generator.class_indices)
class_names = list(train_generator.class_indices.keys())
print(class_names)
validation_datagen = ImageDataGenerator(
rescale=1./255,
rotation_range=10,
horizontal_flip=True)
validation_generator = validation_datagen.flow_from_directory(
'data/validation/',
target_size=(IMAGE_SIZE,IMAGE_SIZE),
batch_size=32,
class_mode="sparse"
)
test_datagen = ImageDataGenerator(
rescale=1./255,
rotation_range=10,
horizontal_flip=True)
test_generator = test_datagen.flow_from_directory(
'data/test/',
target_size=(IMAGE_SIZE,IMAGE_SIZE),
batch_size=32,
class_mode="sparse"
)
input_shape = (IMAGE_SIZE, IMAGE_SIZE, CHANNELS)
n_classes = 2
model = models.Sequential([
layers.InputLayer(input_shape=input_shape),
layers.Conv2D(32, kernel_size = (3,3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, kernel_size = (3,3), activation='relu'),
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='softmax'),
])
model.summary()
model.compile(
optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
metrics=['accuracy']
)
import os
checkpoint_path = "teta/cp.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)
cp_callback = tf.keras.callbacks.ModelCheckpoint(
checkpoint_path,save_weights_only=True,verbose=1)
history = model.fit(
train_generator,
steps_per_epoch=30,
batch_size=32,
validation_data=validation_generator,
validation_steps=22,
verbose=1,
callbacks=[cp_callback],
epochs=2,
)
I want to load the training model and resume it from last checkpoint any can help me with that?
I am using tensorflow 2.0 . I have low specs pc so I can't train my model at once.
I would recommend saving the whole model with model.save(*) and then loading it again with model.load(*). See this documentation for more information. In your case, you can just run:
model.load_weights('teta/your_checkpoint')
before calling model.fit(*) again.

How to add svm on top of cnn as final classifier?

I work on sentiment analysis task and i want to add SVM layer on top CNN as a final classifier, how can i do that without using hing-loss?
tweet_input = Input(shape=(seq_len,), dtype='int32')
tweet_encoder = Embedding(vocabulary_size, EMBEDDING_DIM,
input_length=seq_len, trainable=True)(tweet_input)
bigram_branch = Conv1D(filters=64, kernel_size=2, padding='same',
activation='relu', strides=1)(tweet_encoder)
bigram_branch = GlobalMaxPooling1D()(bigram_branch)
trigram_branch = Conv1D(filters=32, kernel_size=3, padding='same',
activation='relu', strides=1)(tweet_encoder)
trigram_branch = GlobalMaxPooling1D()(trigram_branch)
fourgram_branch = Conv1D(filters=16, kernel_size=4, padding='same',
activation='relu', strides=1)(tweet_encoder)
fourgram_branch = GlobalMaxPooling1D()(fourgram_branch)
merged = concatenate([bigram_branch, trigram_branch, fourgram_branch], axis=1)
merged = Dense(512, activation='softmax')(merged)
merged = Dropout(0.8)(merged)
merged = Dense(2)(merged)
output = Activation('sigmoid')(merged)
model = Model(inputs=[tweet_input], outputs=[output])
adam=keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0, amsgrad=False)
model.compile(loss='hinge',
optimizer= adam,
metrics=['accuracy'])
model.summary()

error when checking target expected dense_2 to have shape (13 ) but got array with shape ( 40)

Hello I am writing a neuron for determining the figures counting
def get_image_size():
img = cv2.imread('gestures/0/100.jpg', 0)
return img.shape // 50*50
def get_num_of_classes():
return len(os.listdir('gestures/')) //13classes
image_x, image_y = get_image_size()
The CNN Model
def cnn_model():
num_of_classes = get_num_of_classes()
model = Sequential()
model.add(Conv2D(32, (5,5), input_shape=(image_x, image_y, 1), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2), padding='same'))
model.add(Conv2D(64, (5,5), activation='relu'))
model.add(MaxPooling2D(pool_size=(5, 5), strides=(5, 5), padding='same'))
model.add(Flatten())
model.add(Dense(1024, activation='relu'))
model.add(Dropout(0.4))
model.add(Dense(num_of_classes, activation='softmax'))
sgd = optimizers.SGD(lr=1e-4)
model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
filepath="cnn_model_keras2.h5"
checkpoint1 = ModelCheckpoint(filepath, monitor='val_acc', verbose=1, save_best_only=True, mode='max')
#checkpoint2 = ModelCheckpoint(filepath, monitor='val_loss', verbose=1, save_best_only=True, mode='min')
callbacks_list = [checkpoint1]
return model, callbacks_list
Trainning
def train():
with open("train_images", "rb") as f:
train_images = np.array(pickle.load(f))
with open("train_labels", "rb") as f:
train_labels = np.array(pickle.load(f), dtype=np.int32)
with open("test_images", "rb") as f:
test_images = np.array(pickle.load(f))
with open("test_labels", "rb") as f:
test_labels = np.array(pickle.load(f), dtype=np.int32)
train_images = np.reshape(train_images, (train_images.shape[0], image_x, image_y, 1))
test_images = np.reshape(test_images, (test_images.shape[0], image_x, image_y, 1))
train_labels = np_utils.to_categorical(train_labels)
test_labels = np_utils.to_categorical(test_labels)
model, callbacks_list = cnn_model()
model.fit(train_images, train_labels, validation_data=(test_images, test_labels), epochs=50, batch_size=100, callbacks=callbacks_list)
scores = model.evaluate(test_images, test_labels, verbose=0)
print("CNN Error: %.2f%%" % (100-scores[1]*100))
but i'm getting this error : ValueError: Error when checking target: expected dense_1 to have shape (13,) but got array with shape (40,) and i searched about some solutions but nothing work , if any one have an idea how to solve it please
The error says that the number of labels you have for training is not the same as you are predicting. Looking at the code, it seems like num_of_classes != train_labels.shape[1]. If you have just a vector of classes labels such as [3, 7, 1] then you can use loss='sparse_categorical_crossentropy' which will encode the targets when training for you.

Categories

Resources