How to prepend layers to Inception model

Hi,

Since the TF docs mention “tf.keras.preprocessing.image.ImageDataGenerator is not recommended for new code.”, I tried to prepend a tf.keras.layers.RandomRotation layer to the Inception model (similar to the example here: Apprentissage par transfert et mise au point  |  TensorFlow Core).
The two parts do not seem to be connected though. This is the code I added to the lab 1 code:

from tensorflow.keras import Input
from tensorflow.keras.layers import RandomRotation
inputs = Input(shape=(150, 150, 3))
rotation_layer = RandomRotation(0.11)
prep_data = rotation_layer(inputs)
pre_trained_model(prep_data)
pre_trained_model.summary()

The model summary shows the same Inception model without the prepended layers.
Any tips on how to do this correctly?

Your code should work fine, but the point is you have not actually changed the definition of pre_trained_model. If you want the prepended layer to show up in the model summary, you could define another actual “model” instance that includes the added layer and the base model. There is an example of how to do exactly this for the purposes of data augmentation in DLS Course 4 Week 2 Transfer Learning with MobilNet, if you have taken DLS C4.

I guess that’s what I get for not posting the full code! :wink: (I did actually do that lab in DLS).
I thought that the summary also included linked input layers. The reason I did the summary() was because I was getting an error with the full code:

from tensorflow.keras import Input
from tensorflow.keras.layers import RandomRotation
inputs = Input(shape=(150, 150, 3))
rotation_layer = RandomRotation(0.11)
prep_data = rotation_layer(inputs)
pre_trained_model(prep_data)
pre_trained_model.summary()
x = layers.Flatten()(last_output)
x = layers.Dense(1024, activation='relu')(x)
x = layers.Dropout(0.2)(x)                  
x = layers.Dense  (1, activation='sigmoid')(x)    

model = Model(inputs, x) 

The error I get with the Model() line is:

ValueError: Graph disconnected: cannot obtain value for tensor KerasTensor(type_spec=TensorSpec(shape=(None, 150, 150, 3), dtype=tf.float32, name='input_3'), name='input_3', description="created by layer 'input_3'") at layer "conv2d_94". The following previous layers were accessed without issue: []
``

Where is last_output defined?

I simply added the few lines above to the lab notebook.
last_output is defined just below the following block:

Hi @lmdevries,
As @paulinpaloalto said, there is a disconnection in the lines of code.
Checking your first comments and the code in colab, we can see that you can continue to use the same model created, but the warning is that is a good idea to use another way to load the dataset into the model. In this case, you could make use of tf.keras.preprocessing.image_dataset_from_directory or tf.data.Dataset to load the data into the model, instead of ImageDataGenerator.
Keep learning!

Not sure I follow.
Initially, the lab notebook runs fine as it was provided.
I wanted to try to add an augmentation layer before Inception, so I created those layers.
To avoid further confusion I provide the exact part (creating the new model) that is causing me issues (and has nothing to do with how I load the datasets…):

from tensorflow.keras.applications.inception_v3 import InceptionV3
from tensorflow.keras import layers, Model, Input
from tensorflow.keras.layers import RandomRotation

# Create Inception model
local_weights_file = '/tmp/inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5'
base_model = InceptionV3(input_shape = (150, 150, 3), 
                         include_top = False, 
                        weights = None)
base_model.load_weights(local_weights_file)
for layer in base_model.layers:
  layer.trainable = False

# Add augmentation layers
inputs = Input(shape=(150, 150, 3))
r = RandomRotation(0.11)(inputs)
# Use augmentation layers as input for the Inception model
x = base_model(r, training=False)
# Add layers for transfer learning
x = layers.Flatten()(base_model.get_layer('mixed7').output)
x = layers.Dense(1024, activation='relu')(x)
x = layers.Dropout(0.2)(x)                  
x = layers.Dense  (1, activation='sigmoid')(x)
# Link new inputs with dense output
model = Model(inputs, x)

The last line (model=etc.) causes the error mentioned earlier:

ValueError: Graph disconnected: cannot obtain value for tensor KerasTensor(type_spec=TensorSpec(shape=(None, 150, 150, 3), dtype=tf.float32, name='input_4'), name='input_4', description="created by layer 'input_4'") at layer "conv2d_188". The following previous layers were accessed without issue: []

My guess is that the problem is those two lines. Notice that the “Flatten” layer does not use the x as input directly. Maybe it is doing something that is logically equivalent, but just from the POV of the compute graph it looks disconnected at that point.

If you really want the output to be from a layer other than the output layer of base_model, maybe you also need to create a new model that is just the subset of base_model that you need and then invoke that instead of the full base_model at that point in the series of computations.

maybe you also need to create a new model that is just the subset of base_model

Ok, that worked, thanks! For future reference, here is the working model:

from tensorflow.keras.applications.inception_v3 import InceptionV3
from tensorflow.keras import layers, Model, Input
from tensorflow.keras.layers import RandomRotation

# Set the weights file you downloaded into a variable
local_weights_file = '/tmp/inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5'

# Initialize the base model.
# Set the input shape and remove the dense layers.
base_model = InceptionV3(input_shape = (150, 150, 3), 
                         include_top = False, 
                        weights = None)

# Load the pre-trained weights you downloaded.
base_model.load_weights(local_weights_file)

# Freeze the weights of the layers.
for layer in base_model.layers:
  layer.trainable = False

inputs = Input(shape=(150, 150, 3))
r = RandomRotation(0.11)(inputs)
augmentation_model = Model(inputs, r)
#augmentation_model.summary()

x = layers.Flatten()(base_model.get_layer('mixed7').output)
x = layers.Dense(1024, activation='relu')(x)
x = layers.Dropout(0.2)(x)                  
x = layers.Dense  (1, activation='sigmoid')(x)   
inception_plus_transfer_model = Model(base_model.input, x) 
#inception_plus_transfer_model.summary()

inception_model_output = inception_plus_transfer_model(augmentation_model.output)
final_model = Model(augmentation_model.input, inception_model_output, name='augm_inception_transfer')
final_model.summary()