def create_id3_embedding(videos, warmup=False, batch_size=16):
    """Embeds the given videos using the Inflated 3D Convolution ne   twork.

    Downloads the graph of the I3D from tf.hub and adds it to the graph on the
    first call.

    Args:
      videos: <float32>[batch_size, num_frames, height=224, width=224, depth=3].
        Expected range is [-1, 1].

    Returns:
      embedding: <float32>[batch_size, embedding_size]. embedding_size depends
                 on the model used.

    Raises:
      ValueError: when a provided embedding_layer is not supported.
    """

    # batch_size = 16
    module_spec = "https://tfhub.dev/deepmind/i3d-kinetics-400/1"

    # Making sure that we import the graph separately for
    # each different input video tensor.
    module_name = "fvd_kinetics-400_id3_module_" + six.ensure_str(videos.name).replace(
        ":", "_"
    )

    assert_ops = [
        tf.Assert(
            tf.reduce_max(videos) <= 1.001, ["max value in frame is > 1", videos]
        ),
        tf.Assert(
            tf.reduce_min(videos) >= -1.001, ["min value in frame is < -1", videos]
        ),
        tf.assert_equal(
            tf.shape(videos)[0],
            batch_size,
            ["invalid frame batch size: ", tf.shape(videos)],
            summarize=6,
        ),
    ]
    with tf.control_dependencies(assert_ops):
        videos = tf.identity(videos)

    module_scope = "%s_apply_default/" % module_name

    # To check whether the module has already been loaded into the graph, we look
    # for a given tensor name. If this tensor name exists, we assume the function
    # has been called before and the graph was imported. Otherwise we import it.
    # Note: in theory, the tensor could exist, but have wrong shapes.
    # This will happen if create_id3_embedding is called with a frames_placehoder
    # of wrong size/batch size, because even though that will throw a tf.Assert
    # on graph-execution time, it will insert the tensor (with wrong shape) into
    # the graph. This is why we need the following assert.
    if warmup:
        video_batch_size = int(videos.shape[0])
        assert video_batch_size in [
            batch_size,
            -1,
            None,
        ], f"Invalid batch size {video_batch_size}"
    tensor_name = module_scope + "RGB/inception_i3d/Mean:0"
    if not _is_in_graph(tensor_name):
        i3d_model = hub.Module(module_spec, name=module_name)
        i3d_model(videos)

    # gets the kinetics-i3d-400-logits layer
    tensor_name = module_scope + "RGB/inception_i3d/Mean:0"
    tensor = tf.get_default_graph().get_tensor_by_name(tensor_name)
    return tensor
Embeds the given videos using the Inflated 3D Convolution ne   twork.

    Downloads the graph of the I3D from tf.hub and adds it to the graph on the
    first call.

    Args:
      videos: <float32>[batch_size, num_frames, height=224, width=224, depth=3].
        Expected range is [-1, 1].

    Returns:
      embedding: <float32>[batch_size, embedding_size]. embedding_size depends
                 on the model used.

    Raises:
      ValueError: when a provided embedding_layer is not supported.
    
extern/ldm_zero123/modules/evaluate/frechet_video_distance.py