class_docstr: Model for predicting autofills given context.
class_docstr_tok: ["Model","for","predicting","autofills","given","context","."]
docstr: Adds convolution and batch norm layers if hparam.batch_norm is True.
docstr_tok: ["Adds","convolution","and","batch","norm","layers","if","hparam.batch_norm","is","True","."]
code: def apply_convolution(self, x, layer, layer_idx):
      """Adds convolution and batch norm layers if hparam.batch_norm is True."""
      if "filters" not in layer:
          return x
  
      filter_shape = layer["filters"]
      # Instantiate or retrieve filter weights.
      initializer = tf.keras.initializers.he_normal()
      regular_convs = (
          not self.hparams.use_sep_conv
          or layer_idx < self.hparams.num_initial_regular_conv_layers
      )
      if regular_convs:
          dilation_rates = layer.get("dilation_rate", 1)
          if isinstance(dilation_rates, int):
              dilation_rates = [dilation_rates] * 2
          weights = tf.get_variable(
              "weights",
              filter_shape,
              initializer=initializer if self.is_training else None,
          )
          stride = layer.get("conv_stride", 1)
          conv = tf.nn.conv2d(
              x,
              weights,
              strides=[1, stride, stride, 1],
              padding=layer.get("conv_pad", "SAME"),
              dilations=[1] + dilation_rates + [1],
          )
      else:
          num_outputs = filter_shape[-1]
          num_splits = layer.get("num_pointwise_splits", 1)
          dilation_rate = layer.get("dilation_rate", [1, 1])
          tf.logging.info("num_splits %d", num_splits)
          tf.logging.info("dilation_rate %r", dilation_rate)
          if num_splits > 1:
              num_outputs = None
          conv = tf.layers.separable_conv2d(
              x,
              num_outputs,
              filter_shape[:2],
              depth_multiplier=self.hparams.sep_conv_depth_multiplier,
              strides=layer.get("conv_stride", [1, 1]),
              padding=layer.get("conv_pad", "SAME"),
              dilation_rate=dilation_rate,
              activation=None,
              depthwise_initializer=initializer
              if self.is_training
              else None,
              pointwise_initializer=initializer
              if self.is_training
              else None,
          )
          if num_splits > 1:
              splits = tf.split(conv, num_splits, -1)
              print(len(splits), splits[0].shape)
              # TODO(annahuang): support non equal splits.
              pointwise_splits = [
                  tf.layers.dense(
                      splits[i],
                      filter_shape[3] / num_splits,
                      name="split_%d_%d" % (layer_idx, i),
                  )
                  for i in range(num_splits)
              ]
              conv = tf.concat((pointwise_splits), axis=-1)
  
      # Compute batch normalization or add biases.
      if self.hparams.batch_norm:
          y = self.apply_batchnorm(conv)
      else:
          biases = tf.get_variable(
              "bias",
              [conv.get_shape()[-1]],
              initializer=tf.constant_initializer(0.0),
          )
          y = tf.nn.bias_add(conv, biases)
      return y
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import collections
  import os
  from magenta.models.coconet import lib_hparams
  from magenta.models.coconet import lib_tfutil
  import tensorflow.compat.v1
label_desc: Use image node_id 20 for calling the CoconetGraph obj's underlying member method code with example usage: obj.apply_convolution(x, layer, layer_idx) and returns: y, x