I am trying to train a custom CNN model in TensorFlow. I want somehow to freeze some layers of the model in specific epochs while the training is still running. I have achieved freezing the layers but i had to train the model for some epochs, then change the trainable attribute to False in specific layers i wanted to freeze, then compile the model, and the start training again.
I have tried to implement it using the CustomCallback() Class, and in certain epochs to freeze some layers, but it seemed that this didn't work. As far as TensorFlow mentions about changing the .trainable attribute of a layer, then you have to compile the model for the change to be applied at the model, but there is an error emerging, "TypeError: 'NoneType' object is not callable".
That is my code:
Load libraries
import tensorflow as tf
from tensorflow.keras import datasets, layers, models
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
from keras.callbacks import ModelCheckpoint, EarlyStopping
from tensorflow.keras.utils import Sequence
from keras.models import load_model
Load dataset
#Load dataset
(X_train, y_train), (X_test, y_test) = tf.keras.datasets.cifar10.load_data()
#Normalize
X_train, X_test = X_train/255.0, X_test/255.0
Build model
cnn = models.Sequential([
layers.Conv2D(filters = 32, kernel_size = (1,1), padding = "same", activation = "relu", input_shape = (32,32,3)),
layers.Conv2D(filters = 64, kernel_size = (3,3), padding = "same", activation = "relu"),
layers.MaxPool2D(pool_size = (2,2)),
layers.Conv2D(filters = 64, kernel_size = (3,3), padding = "same", activation = "relu"),
layers.Conv2D(filters = 128, kernel_size = (5,5), padding = "same", activation = "relu"),
layers.MaxPool2D(pool_size = (2,2)),
layers.Flatten(),
layers.Dense(64, activation = "relu"),
layers.Dense(128, activation = "relu"),
layers.Dense(64, activation = "relu"),
layers.Dense(10, activation = "softmax")
])
Create CustomCallback Class
class CustomCallback(tf.keras.callbacks.Callback):
def on_epoch_begin(self, epoch, logs = None):
if epoch == 5:
cnn.layers[0].trainable, cnn.layers[1].trainable, cnn.layers[2].trainable = (False, False, False)
cnn.compile(optimizer = optimizer, loss = "sparse_categorical_crossentropy", metrics = ["accuracy"])
elif epoch == 10:
cnn.layers[3].trainable, cnn.layers[4].trainable, cnn.layers[5].trainable = (False, False, False)
cnn.compile(optimizer = optimizer, loss = "sparse_categorical_crossentropy", metrics = ["accuracy"])
elif epoch == 15:
cnn.layers[6].trainable, cnn.layers[7].trainable, cnn.layers[8].trainable = (False, False, False)
cnn.compile(optimizer = optimizer, loss = "sparse_categorical_crossentropy", metrics = ["accuracy"])
Define optimizer and compile
#Define the optimizer
optimizer = tf.keras.optimizers.Adam(learning_rate = 0.001)
#Compile the model
cnn.compile(optimizer = optimizer , loss = "sparse_categorical_crossentropy", metrics = ["accuracy"])
Train model
results = cnn.fit(X_train, y_train, epochs = 20, validation_data = (X_test, y_test), batch_size = 1024, callbacks = [CustomCallback()])
An error pops-up "TypeError: 'NoneType' object is not callable". If i don't compile the model after freezing some layers it seems to not get an error, but while training all layers are updated in all epochs.