I have built a one class anomaly detection deep learning model and I am training it on one class red-blood cell images.
I have calculated a threshold that will be able to differentiate between anomalous and normal images but for some reason it doesn't identify as many abnormal images as I would like.
What are some of the hyperparameters that I can tune to make my model learn well and predict better.
Here is my code.
import tensorflow as tf
from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, UpSampling2D, BatchNormalization, LayerNormalization
from tensorflow.keras.models import Model
from tensorflow.keras.regularizers import l1
from tensorflow.keras.optimizers import Adam
optimizer = Adam(learning_rate=0.0001)
input_shape = (SIZE, SIZE, 3)
# Encoder
inputs = Input(shape=input_shape)
x = Conv2D(64, (3, 3), activation='relu', padding='same', activity_regularizer=l1(1e-6))(inputs)
x = MaxPooling2D((2, 2), padding='same')(x)
x = Conv2D(32, (3, 3), activation='relu', padding='same', activity_regularizer=l1(1e-6))(x)
x = MaxPooling2D((2, 2), padding='same')(x)
x = Conv2D(16, (3, 3), activation='relu', padding='same', activity_regularizer=l1(1e-6))(x)
encoded = MaxPooling2D((2, 2), padding='same')(x)
# Decoder
x = Conv2D(16, (3, 3), activation='relu', padding='same', activity_regularizer=l1(1e-6))(encoded)
x = UpSampling2D((2, 2))(x)
x = Conv2D(32, (3, 3), activation='relu', padding='same', activity_regularizer=l1(1e-6))(x)
x = UpSampling2D((2, 2))(x)
x = Conv2D(64, (3, 3), activation='relu', padding='same', activity_regularizer=l1(1e-6))(x)
x = UpSampling2D((2, 2))(x)
decoded = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(x)
# Define the autoencoder model
autoencoder = Model(inputs, decoded)
# Compile the model
autoencoder.compile(optimizer=optimizer, loss='mean_squared_error')
# Print the model summary
autoencoder.summary()
#Fit the model.
history = autoencoder.fit(
train_generator,
steps_per_epoch= 250 // batch_size,
epochs=1000,
validation_data=validation_generator,
validation_steps= 250 // batch_size,
shuffle = True)
#plot the training and validation loss at each epoch
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(1, len(loss) + 1)
plt.plot(epochs, loss, 'y', label='Training loss')
plt.plot(epochs, val_loss, 'r', label='Validation loss')
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()
I want to have a low reconstruction error for the normal instances and a high reconstruction error for abnormal instances. Any idea on how I can improve the performance of my model ?
Here is a snapshot of the the loss.
Epoch 1/1000
7/7 [==============================] - 31s 4s/step - loss: 0.1420 - val_loss: 0.1355
Epoch 2/1000
7/7 [==============================] - 30s 4s/step - loss: 0.1302 - val_loss: 0.1266
Epoch 3/1000
7/7 [==============================] - 30s 4s/step - loss: 0.1228 - val_loss: 0.1201
Epoch 4/1000
7/7 [==============================] - 30s 4s/step - loss: 0.1152 - val_loss: 0.1111
Epoch 5/1000
7/7 [==============================] - 31s 5s/step - loss: 0.1028 - val_loss: 0.0920
Epoch 6/1000
7/7 [==============================] - 30s 4s/step - loss: 0.0785 - val_loss: 0.0630
Epoch 7/1000
7/7 [==============================] - 30s 4s/step - loss: 0.0571 - val_loss: 0.0507
Epoch 8/1000
7/7 [==============================] - 30s 4s/step - loss: 0.0470 - val_loss: 0.0430
Epoch 9/1000
7/7 [==============================] - 30s 4s/step - loss: 0.0412 - val_loss: 0.0392
Epoch 10/1000
7/7 [==============================] - 30s 4s/step - loss: 0.0381 - val_loss: 0.0366
Epoch 11/1000
7/7 [==============================] - 30s 5s/step - loss: 0.0361 - val_loss: 0.0347
Epoch 12/1000
7/7 [==============================] - 30s 4s/step - loss: 0.0341 - val_loss: 0.0333
Epoch 13/1000
7/7 [==============================] - 31s 5s/step - loss: 0.0330 - val_loss: 0.0320