class_docstr: Phoenix: A smart search AutoML algorithm.
class_docstr_tok: ["Phoenix",":","A","smart","search","AutoML","algorithm","."]
docstr: Compiles the keras model based on hparams.
docstr_tok: ["Compiles","the","keras","model","based","on","hparams","."]
code: def keras_compile(self, towers, hparams):
      """Compiles the keras model based on hparams."""
      optimizer_args = dict()
  
      # Learning rate
      lr = hparams.learning_rate
      if getattr(hparams, "exponential_decay_rate", None) is not None:
          max_times = self._phoenix_spec.learning_spec.max_decay_times
          steps = hparams.exponential_decay_steps
          decay = hparams.exponential_decay_rate
          lr = tf.keras.optimizers.schedules.PiecewiseConstantDecay(
              boundaries=[steps * j for j in range(1, max_times)],
              values=[
                  lr * (decay**i) for i in range(1, max_times + 1)
              ],
          )
      optimizer_args["learning_rate"] = lr
  
      # Gradient Clip
      if getattr(hparams, "gradient_max_norm", None) is not None:
          optimizer_args["clipnorm"] = hparams.gradient_max_norm
  
      # L2 Error
      if getattr(hparams, "l2_regularization", None) is not None:
          logging.error("Keras mode doesn't support L2 regularization.")
  
      # Optimizer
      optimizer = None
      if hparams.optimizer == "sgd":
          optimizer = tf.keras.optimizers.SGD(**optimizer_args)
      elif hparams.optimizer == "momentum":
          optimizer = tf.keras.optimizers.SGD(
              **optimizer_args, momentum=0.9
          )
      elif hparams.optimizer == "adam":
          optimizer = tf.keras.optimizers.Adam(**optimizer_args)
      elif hparams.optimizer == "adagrad":
          optimizer = tf.keras.optimizers.Adagrad(**optimizer_args)
      elif hparams.optimizer == "rmsprop":
          optimizer = tf.keras.optimizers.RMSprop(**optimizer_args)
      elif hparams.optimizer == "lazy_adam":
          logging.error(
              "Lazy adam is not implemented in Keras. Falling back to "
              "Adam"
          )
          optimizer = tf.keras.optimizers.Adam(**optimizer_args)
  
      towers["search_generator"][0].compile(
          optimizer=optimizer,
          loss=tf.keras.losses.SparseCategoricalCrossentropy(
              from_logits=True
          ),
      )
      return towers["search_generator"][0]
  
imports: import functools
  import inspect
  from absl import logging
  import keras_tuner
  from model_search import controller
  from model_search import hparam
  from model_search import loss_fns
  from model_search import metric_fns
  from model_search import task_manager
  from model_search.architecture import architecture_utils
  from model_search.generators import base_tower_generator
  from model_search.generators import trial_utils
  from model_search.meta import transfer_learning
  from model_search.metadata import ml_metadata_db
  from model_search.proto import phoenix_spec_pb2
  from model_search.proto import transfer_learning_spec_pb2
  import numpy
  import tensorflow.compat.v2
label_desc: Use image node_id 3 for calling the Phoenix obj's underlying member method code with example usage: obj.keras_compile(towers, hparams) and returns: towers