I am planning to use CNN+LSTM for image classification into 4 categories.
I am not really familiar on how to combining CNN and LSTM.
I faced an error: You must compile your model before using it.
when I am trying to compile CNN+LSTM.
The data sets are a series of medical images. I am able to get roughly 70% accuracy by using CNN alone (small sample size of around 300 samples only), so I decided to combine LSTM to see if there will be a boost in accuracy.
from keras.optimizers import RMSprop
from keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras import Sequential
from tensorflow.keras.layers import (LSTM, Dense, Embedding, Dropout, Conv2D, BatchNormalization, Activation,
MaxPooling2D, Flatten, TimeDistributed, SpatialDropout1D)
train_datagen = ImageDataGenerator(rescale=1. / 255, shear_range=0.2, zoom_range=0.2, rotation_range=45,
horizontal_flip=True, vertical_flip=True, validation_split=.2)
validation_datagen = ImageDataGenerator(rescale=1. / 255, validation_split=.2)
test_datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = train_datagen.flow_from_directory(directory=r'', target_size=(224, 224), color_mode="rgb",
batch_size=32, class_mode='categorical', shuffle=True, seed=42)
validation_generator = validation_datagen.flow_from_directory(directory=r'', target_size=(224, 224), color_mode="rgb",
batch_size=32, class_mode='categorical', shuffle=True,
seed=42)
test_generator = test_datagen.flow_from_directory(directory=r'', target_size=(224, 224), color_mode="rgb",
batch_size=1, class_mode=None, shuffle=False, seed=42)
num_classes = 4
input_shape = (224, 224, 3)
# input image dimensions
img_rows, img_cols = 224, 224
model = Sequential()
# define CNN model
model.add(TimeDistributed(Conv2D(32, (3, 3), padding='same', input_shape=input_shape)))
model.add(TimeDistributed(BatchNormalization()))
model.add(TimeDistributed(Activation('relu')))
model.add(TimeDistributed(MaxPooling2D(pool_size=(2, 2))))
model.add(TimeDistributed(Conv2D(64, (3, 3))))
model.add(TimeDistributed(BatchNormalization()))
model.add(TimeDistributed(Activation('relu')))
model.add(TimeDistributed(MaxPooling2D(pool_size=(2, 2))))
model.add(TimeDistributed(Dropout(0.25)))
model.add(TimeDistributed(Flatten()))
model.add(TimeDistributed(Dense(256)))
model.add(TimeDistributed(BatchNormalization()))
model.add(TimeDistributed(Activation('relu')))
model.add(TimeDistributed(Dropout(0.25)))
# define LSTM model
model.add(LSTM(100, input_shape=(5, 1), return_sequences=True))
model.add(LSTM(Embedding(8192, 256)))
model.add(LSTM(SpatialDropout1D(0.3)))
model.add(LSTM(256, dropout=0.3, recurrent_dropout=0.3))
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.3))
model.add(Dense(5, activation='softmax'))
model.compile(loss=keras.losss.categorical_crossentropy, optimizer=RMSprop(lr=0.001, rho=0.9, epsilon=1e-08, decay=0.0),
metrics=['accuracy'])
STEP_SIZE_TRAIN = train_generator.n // train_generator.batch_size
STEP_SIZE_VALID = validation_generator.n // validation_generator.batch_size
model.fit_generator(generator=train_generator, steps_per_epoch=50, validation_data=validation_generator,
validation_steps=STEP_SIZE_VALID, epochs=30)
You can simply move the input_shape=input_shape
out from Conv2D and put it in TimeDistributed. ie
model.add(TimeDistributed(Conv2D(32, (3, 3), padding='same'), input_shape=input_shape))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.