code: def link_inference(
      output_dim: int = 1,
      output_act: AnyStr = "linear",
      edge_embedding_method: AnyStr = "ip",
      clip_limits: Optional[Tuple[float]] = None,
      name: AnyStr = "link_inference",
  ):
      """
      Defines an edge inference function that takes source, destination node embeddings (node features) as input,
      and returns a numeric vector of output_dim size.
  
      This function takes as input as either:
  
       * A list of two tensors of shape (N, M) being the embeddings for each of the nodes in the link,
         where N is the number of links, and M is the node embedding size.
       * A single tensor of shape (..., N, 2, M) where the axis second from last indexes the nodes
         in the link and N is the number of links and M the embedding size.
  
      Note that the output tensor is flattened before being returned.
  
      .. seealso:: Related functionality: :class:`.LinkEmbedding`, :func:`.link_classification`, :func:`.link_regression`.
  
      Args:
          output_dim (int): Number of predictor's output units -- desired dimensionality of the output.
          output_act (str), optional: activation function applied to the output, one of "softmax", "sigmoid", etc.,
              or any activation function supported by Keras, see https://keras.io/activations/ for more information.
          edge_embedding_method (str), optional: Name of the method of combining ``(src,dst)`` node features or embeddings into edge embeddings.
              One of:
  
              * ``concat`` -- concatenation,
              * ``ip`` or ``dot`` -- inner product, :math:`ip(u,v) = sum_{i=1..d}{u_i*v_i}`,
              * ``mul`` or ``hadamard`` -- element-wise multiplication, :math:`h(u,v)_i = u_i*v_i`,
              * ``l1`` -- L1 operator, :math:`l_1(u,v)_i = |u_i-v_i|`,
              * ``l2`` -- L2 operator, :math:`l_2(u,v)_i = (u_i-v_i)^2`,
              * ``avg`` -- average, :math:`avg(u,v) = (u+v)/2`.
  
              For all methods except ``ip`` or ``dot`` a dense layer is applied on top of the combined
              edge embedding to transform to a vector of size ``output_dim``.
          clip_limits (Tuple[float]): lower and upper thresholds for LeakyClippedLinear unit on top. If None (not provided),
              the LeakyClippedLinear unit is not applied.
          name (str): optional name of the defined function, used for error logging
  
      Returns:
          Function taking edge tensors with ``src``, ``dst`` node embeddings (i.e., pairs of ``(node_src, node_dst)`` tensors) and
          returning a vector of output_dim length (e.g., edge class probabilities, edge attribute prediction, etc.).
      """
  
      if edge_embedding_method in ["ip", "dot"] and output_dim != 1:
          warnings.warn(
              "For inner product link method the output_dim will be ignored as it is fixed to be 1.",
              stacklevel=2,
          )
          output_dim = 1
  
      def edge_function(x):
          le = LinkEmbedding(
              activation="linear", method=edge_embedding_method
          )(x)
  
          # All methods apart from inner product have a dense layer
          # to convert link embedding to the desired output
          if edge_embedding_method in ["ip", "dot"]:
              out = Activation(output_act)(le)
          else:
              out = Dense(output_dim, activation=output_act)(le)
  
          # Reshape outputs
          out = Reshape((output_dim,))(out)
  
          if clip_limits:
              out = LeakyClippedLinear(
                  low=clip_limits[0], high=clip_limits[1], alpha=0.1
              )(out)
          return out
  
      print(
          "{}: using '{}' method to combine node embeddings into edge embeddings".format(
              name, edge_embedding_method
          )
      )
      return edge_function
  
file_path: stellargraph/stellargraph/layer/link_inference.py
imports: from typing import AnyStr, Optional, List, Tuple
  import tensorflow
  from tensorflow.keras.layers import Layer, Concatenate, Dense, Lambda, Multiply, Average, Reshape, Activation
  from tensorflow.keras import backend
  import warnings
label_desc: Use image node_id 1 for calling a global function with example usage: link_inference(output_dim, output_act, edge_embedding_method, clip_limits, name) and returns: edge_function, out