zzh8829 / yolov3-tf2

YoloV3 Implemented in Tensorflow 2.0
MIT License
2.51k stars 909 forks source link

Unable to access intermediate layers, getting ValueError: Graph disconnected #330

Open semihcanturk opened 4 years ago

semihcanturk commented 4 years ago

I'm trying to access the intermediate layers of the YOLOv3 model during a forward pass. Using the functional API, this is usually achieved as follows (from https://www.tensorflow.org/guide/keras/functional, see section "Extract and reuse nodes in the graph of layers"):

features_list = [layer.output for layer in model.layers]
feat_extraction_model = keras.Model(inputs=model.input, outputs=features_list)

img = np.random.random((1, 416, 416, 3)).astype("float32")
extracted_features = feat_extraction_model(img)

However, I am getting the following error when I run grad_model = tf.keras.models.Model([yolo.inputs], [layer.output for layer in yolo.layers]) with YOLOv3 (full script attached below):

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

Now, one usually gets this when your inputs and outputs in keras.Model(inputs=model.input, outputs=features_list) are from different graphs, but i don’t see how that’s possible in my case. I used the following script to access the intermediate layers - does anyone have any idea how I can work around this? Any other method suggestions to access the intermediate layers are also welcome. Thank you!

import sys
import tensorflow as tf
tf.config.experimental_run_functions_eagerly(True)
from absl import app, logging, flags
from absl.flags import FLAGS
import time
import cv2
import numpy as np
from yolov3_tf2.models import (
    YoloV3, YoloV3Tiny, YoloLoss, yolo_anchors, yolo_anchor_masks
)
from yolov3_tf2.dataset import transform_images, transform_targets

from yolov3_tf2.dataset import transform_images, load_tfrecord_dataset
from yolov3_tf2.utils import draw_outputs

flags.DEFINE_string('classes', './data/coco.names', 'path to classes file')
flags.DEFINE_string('weights', './checkpoints/yolov3.tf',
                    'path to weights file')
flags.DEFINE_boolean('tiny', False, 'yolov3 or yolov3-tiny')
flags.DEFINE_integer('size', 416, 'resize images to')
flags.DEFINE_string('image', './data/girl.png', 'path to input image')
flags.DEFINE_string('tfrecord', None, 'tfrecord instead of image')
flags.DEFINE_string('output', './output.jpg', 'path to output image')
flags.DEFINE_integer('num_classes', 80, 'number of classes in the model')

app._run_init(['yolov3'], app.parse_flags_with_usage)

# physical_devices = tf.config.experimental.list_physical_devices('GPU')
# tf.config.experimental.set_memory_growth(physical_devices[0], True)

FLAGS.image = 'data/meme.jpg'

yolo = YoloV3(classes=FLAGS.num_classes, training=True)

# yolo.load_weights(FLAGS.weights).expect_partial()
# logging.info('weights loaded')

class_names = [c.strip() for c in open(FLAGS.classes).readlines()]
logging.info('classes loaded')

img_raw = tf.image.decode_image(
    open(FLAGS.image, 'rb').read(), channels=3)

img = tf.expand_dims(img_raw, 0)
img = transform_images(img, FLAGS.size)

# THIS IS THE LINE THAT FAILS
grad_model = tf.keras.models.Model(
            [yolo.inputs], [layer.output for layer in yolo.layers]
        )

with tf.GradientTape() as tape:
    inputs = tf.cast(img, tf.float32)
    predictions = grad_model(inputs)
    print(predictions.shape)
troyliu0105 commented 4 years ago

I have same issue...