Home > Software design >  tensorflow model gives "graph disconnected" error
tensorflow model gives "graph disconnected" error

Time:12-18

I am experimenting/fiddling/learning with some small ML problems.

I have a loaded model based on a pre-trained convolution base with some self-trained dense layers (for model details see below).

I wanted to try to apply some visualizations like activations and the Grad CAM Visualization (https://www.statworx.com/de/blog/erklaerbbarkeit-von-deep-learning-modellen-mit-grad-cam/) on the model. But I was not able to do so.

I tried to create a new model based on mine (like in the article) with

grad_model = tf.keras.models.Model(model.inputs,
                                   [model.get_layer('vgg16').output,
                                    model.output])

but this already fails with the error:

ValueError: Graph disconnected: cannot obtain value for tensor Tensor("input_5_12:0", shape=(None, None, None, 3), dtype=float32) at layer "block1_conv1". The following previous layers were accessed without issue: []

I do not understand what this means. the model surely works (i can evaluate it and make predictions with it). The call does not fail if I omit the model.get_layer('vgg16').output from the outputs list but of course, this is required for the visualization.

What I am doing wrong?

In a model that I constructed and trained from scratch, I was able to create a similar model with the activations as outputs but here i get these errors.

My model's details

The model was created with the following code and then trained and saved.

from tensorflow import keras
from tensorflow.keras import models
from tensorflow.keras import layers
from tensorflow.keras import optimizers


conv_base  = keras.applications.vgg16.VGG16(
    weights="vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5",
    include_top=False)
conv_base.trainable = False
data_augmentation = keras.Sequential(
    [
        layers.experimental.preprocessing.RandomFlip("horizontal"),
        layers.experimental.preprocessing.RandomRotation(0.1),
        layers.experimental.preprocessing.RandomZoom(0.2),
    ]
)

inputs = keras.Input(shape=(180, 180, 3))
x = data_augmentation(inputs)
x = conv_base(x)
x = layers.Flatten()(x)
x = layers.Dense(256)(x)
x = layers.Dropout(0.5)(x)
outputs = layers.Dense(1, activation="sigmoid")(x)
model = keras.Model(inputs, outputs)
model.compile(loss="binary_crossentropy",
              optimizer="rmsprop",
              metrics=["accuracy"])

later it was loaded:

model = keras.models.load_model("myModel.keras")
print(model.summary())
print(model.get_layer('sequential').summary())
print(model.get_layer('vgg16').summary())


output:

Model: "functional_3"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_6 (InputLayer)         [(None, 180, 180, 3)]     0         
_________________________________________________________________
sequential (Sequential)      (None, 180, 180, 3)       0         
_________________________________________________________________
vgg16 (Functional)           (None, None, None, 512)   14714688  
_________________________________________________________________
flatten_1 (Flatten)          (None, 12800)             0         
_________________________________________________________________
dense_2 (Dense)              (None, 256)               3277056   
_________________________________________________________________
dropout_1 (Dropout)          (None, 256)               0         
_________________________________________________________________
dense_3 (Dense)              (None, 1)                 257       
=================================================================
Total params: 17,992,001
Trainable params: 10,356,737
Non-trainable params: 7,635,264
_________________________________________________________________
None
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
random_flip (RandomFlip)     (None, 180, 180, 3)       0         
_________________________________________________________________
random_rotation (RandomRotat (None, 180, 180, 3)       0         
_________________________________________________________________
random_zoom (RandomZoom)     (None, 180, 180, 3)       0         
=================================================================
Total params: 0
Trainable params: 0
Non-trainable params: 0
_________________________________________________________________
None
Model: "vgg16"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_5 (InputLayer)         [(None, None, None, 3)]   0         
_________________________________________________________________
block1_conv1 (Conv2D)        multiple                  1792      
_________________________________________________________________
block1_conv2 (Conv2D)        multiple                  36928     
_________________________________________________________________
block1_pool (MaxPooling2D)   multiple                  0         
_________________________________________________________________
block2_conv1 (Conv2D)        multiple                  73856     
_________________________________________________________________
block2_conv2 (Conv2D)        multiple                  147584    
_________________________________________________________________
block2_pool (MaxPooling2D)   multiple                  0         
_________________________________________________________________
block3_conv1 (Conv2D)        multiple                  295168    
_________________________________________________________________
block3_conv2 (Conv2D)        multiple                  590080    
_________________________________________________________________
block3_conv3 (Conv2D)        multiple                  590080    
_________________________________________________________________
block3_pool (MaxPooling2D)   multiple                  0         
_________________________________________________________________
block4_conv1 (Conv2D)        multiple                  1180160   
_________________________________________________________________
block4_conv2 (Conv2D)        multiple                  2359808   
_________________________________________________________________
block4_conv3 (Conv2D)        multiple                  2359808   
_________________________________________________________________
block4_pool (MaxPooling2D)   multiple                  0         
_________________________________________________________________
block5_conv1 (Conv2D)        multiple                  2359808   
_________________________________________________________________
block5_conv2 (Conv2D)        multiple                  2359808   
_________________________________________________________________
block5_conv3 (Conv2D)        multiple                  2359808   
_________________________________________________________________
block5_pool (MaxPooling2D)   multiple                  0         
=================================================================
Total params: 14,714,688
Trainable params: 7,079,424
Non-trainable params: 7,635,264

CodePudding user response:

You can achieve what you want in the following way. First, define your model as follows:

inputs = tf.keras.Input(shape=(180, 180, 3))
x = data_augmentation(inputs, training=True)
x = keras.applications.VGG16(input_tensor=x,
                               include_top=False,
                               weights=None)
x.trainable = False
x = layers.Flatten()(x.output)
x = layers.Dense(256)(x)
x = layers.Dropout(0.5)(x)
x = layers.Dense(1, activation='sigmoid')(x)
model = keras.Model(inputs, x)

for i, layer in enumerate(model.layers):
    print(i, layer.name, layer.output_shape, layer.trainable)
...
17 block5_conv2 (None, 11, 11, 512) False
18 block5_conv3 (None, 11, 11, 512) False
19 block5_pool (None, 5, 5, 512) False
20 flatten_2 (None, 12800) True
21 dense_4 (None, 256) True
22 dropout_2 (None, 256) True
23 dense_5 (None, 1) True

Now, build the grad-cam model with desired output layer as follows:

grad_model = keras.models.Model(
    [model.inputs], 
    [model.get_layer('block5_pool').output, 
     model.output]
)

Test

image = np.random.rand(1, 180, 180, 3).astype(np.float32) 

with tf.GradientTape() as tape:
    convOutputs, predictions = grad_model(tf.cast(image, tf.float32))
    loss = predictions[:, tf.argmax(predictions[0])]

grads = tape.gradient(loss, convOutputs)
print(grads) 
tf.Tensor(
[[[[ 9.8454033e-04  3.6991197e-03 ... -1.2012678e-02
    -1.7934230e-03  2.2925171e-03]
   [ 1.6165405e-03 -1.9513096e-03 ... -2.5789393e-03
     1.2443252e-03 -1.3931725e-03]
   [-2.0554627e-04  1.2232144e-03 ...  5.2324748e-03
     3.1955825e-04  3.4566019e-03]
   [ 2.3650150e-03 -2.5699558e-03 ... -2.4103196e-03
     5.8940407e-03  5.3285398e-03]

...
  • Related