Commit d21490ef authored by peastman's avatar peastman
Browse files

Fixed/removed code relating to graph mode

parent 7cf104f9
Loading
Loading
Loading
Loading
+2 −12
Original line number Diff line number Diff line
@@ -318,9 +318,6 @@ class GAN(KerasModel):
      it.
    """
    self._ensure_built()
    if not tf.executing_eagerly():
      global_step_placeholder = tf.placeholder(tf.int32, tuple())
      update_global_step = self._global_step.assign(global_step_placeholder)
    gen_train_fraction = 0.0
    discrim_error = 0.0
    gen_error = 0.0
@@ -365,11 +362,7 @@ class GAN(KerasModel):
              checkpoint_interval=0)
          gen_average_steps += 1
          gen_train_fraction -= 1.0
      if tf.executing_eagerly():
      self._global_step.assign(global_step + 1)
      else:
        self.session.run(update_global_step,
                         {global_step_placeholder: global_step + 1})

      # Write checkpoints and report progress.

@@ -438,10 +431,7 @@ class GAN(KerasModel):
    inputs = [i.astype(np.float32) for i in inputs]
    pred = self.generators[generator_index](
        _list_or_tensor(inputs), training=False)
    if tf.executing_eagerly():
    pred = pred.numpy()
    else:
      pred = pred.eval(session=self.session)
    return pred


+68 −237
Original line number Diff line number Diff line
@@ -157,7 +157,6 @@ class KerasModel(Model):
    self._built = False
    self._inputs_built = False
    self._training_ops_built = False
    self._initialized_vars = set()
    self._output_functions = {}

  def _ensure_built(self):
@@ -165,13 +164,10 @@ class KerasModel(Model):
    if self._built:
      return
    self._built = True
    if not tf.executing_eagerly():
      self.session = tf.Session()
    self._global_step = tf.Variable(0, trainable=False)
    self._tf_optimizer = self.optimizer._create_optimizer(self._global_step)
    self._checkpoint = tf.train.Checkpoint(
        optimizer=self._tf_optimizer, model=self.model)
    self._init_new_vars()

  def _create_inputs(self, example_inputs):
    """The first time this is called, create tensors representing the inputs and outputs."""
@@ -188,33 +184,6 @@ class KerasModel(Model):
          np.float32 if x.dtype == np.float64 else x.dtype
          for x in example_inputs
      ]
    if tf.executing_eagerly():
      return
    if len(self.model.inputs) > 0:
      self._input_placeholders = self.model.inputs
    else:
      # The model doesn't specify inputs, so guess the input shapes based on the
      # example batch.
      self._input_placeholders = [
          tf.placeholder(dtype=tf.as_dtype(t), shape=s)
          for s, t in zip(self._input_shapes, self._input_dtypes)
      ]
      if len(self._input_shapes) == 1:
        self.model.build(self._input_shapes[0])
      else:
        self.model.build(self._input_shapes)
    if len(self._input_placeholders) == 1:
      self._output_tensors = self.model(
          self._input_placeholders[0], training=False)
    else:
      self._output_tensors = self.model(
          self._input_placeholders, training=False)
    if isinstance(self._output_tensors, tf.Tensor):
      self._output_tensors = [self._output_tensors]
    if self._prediction_outputs is None:
      self._prediction_outputs = list(range(len(self._output_tensors)))
      self._loss_outputs = list(range(len(self._output_tensors)))
    self._init_new_vars()

  def _create_training_ops(self, example_batch):
    """The first time this is called, create tensors used in optimization."""
@@ -230,35 +199,6 @@ class KerasModel(Model):
        np.float32 if x.dtype == np.float64 else x.dtype
        for x in example_batch[2]
    ]
    if tf.executing_eagerly():
      return
    self._label_placeholders = [
        tf.placeholder(dtype=tf.as_dtype(t), shape=(None,) + x.shape[1:])
        for x, t in zip(example_batch[1], self._label_dtypes)
    ]
    self._weights_placeholders = [
        tf.placeholder(dtype=tf.as_dtype(t), shape=(None,) + x.shape[1:])
        for x, t in zip(example_batch[2], self._weights_dtypes)
    ]
    self._loss_tensor = self._loss_fn(
        [self._output_tensors[i] for i in self._loss_outputs],
        self._label_placeholders, self._weights_placeholders)
    try:
      self._train_op = self._tf_optimizer.minimize(
          self._loss_tensor, global_step=self._global_step)
    except ValueError:
      # The loss doesn't depend on any variables.
      self._train_op = 0
    self._custom_train_op = {}
    self._init_new_vars()

  def _init_new_vars(self):
    """Initialize any new variables created since the last call to this method."""
    if not tf.executing_eagerly():
      vars = set(tf.global_variables())
      new_vars = vars.difference(self._initialized_vars)
      self.session.run(tf.variables_initializer(new_vars))
      self._initialized_vars = vars

  def fit(self,
          dataset,
@@ -364,9 +304,8 @@ class KerasModel(Model):
        restore = False
      inputs, labels, weights = self._prepare_batch(batch)
      self._current_summary = None
      if tf.executing_eagerly():

        # In eager mode we execute the loss function, accumulating the gradients.
      # Execute the loss function, accumulating the gradients.

      if loss is None:
        loss = self._loss_fn
@@ -387,39 +326,6 @@ class KerasModel(Model):
      self._tf_optimizer.apply_gradients(zip(grads, vars))
      self._global_step.assign_add(1)
      current_step = self._global_step.numpy()
      else:

        # In graph mode we execute the training op.

        if train_op is None:
          if loss is None and variables is None:
            train_op = self._train_op
          else:
            if variables is None:
              op_key = (None, loss)
            else:
              op_key = tuple(variables) + (loss,)
            if op_key not in self._custom_train_op:
              if loss is None:
                loss_tensor = self._loss_tensor
              else:
                loss_tensor = loss(
                    [self._output_tensors[i] for i in self._loss_outputs],
                    self._label_placeholders, self._weights_placeholders)
              if variables is None:
                vars = self.model.trainable_variables
              else:
                vars = variables
              self._custom_train_op[op_key] = self._tf_optimizer.minimize(
                  loss_tensor, global_step=self._global_step, var_list=vars)
            train_op = self._custom_train_op[op_key]
        fetches = [train_op, self._loss_tensor, self._global_step]
        feed_dict = dict(zip(self._input_placeholders, inputs))
        feed_dict.update(dict(zip(self._label_placeholders, labels)))
        feed_dict.update(dict(zip(self._weights_placeholders, weights)))
        fetched_values = self.session.run(fetches, feed_dict=feed_dict)
        batch_loss = fetched_values[1]
        current_step = fetched_values[2]

      avg_loss += batch_loss

@@ -434,7 +340,7 @@ class KerasModel(Model):
        averaged_batches = 0

      if checkpoint_interval > 0 and current_step % checkpoint_interval == checkpoint_interval - 1:
        self._exec_with_session(lambda: manager.save())
        manager.save()
      for c in callbacks:
        c(self, current_step)
      if self.tensorboard and should_log:
@@ -450,7 +356,7 @@ class KerasModel(Model):
          'Ending global_step %d: Average loss %g' % (current_step, avg_loss))

    if checkpoint_interval > 0:
      self._exec_with_session(lambda: manager.save())
      manager.save()

    time2 = time.time()
    logger.info("TIMING: model fitting took %0.3f s" % (time2 - time1))
@@ -534,10 +440,9 @@ class KerasModel(Model):
      if len(self._variance_outputs) != len(self._prediction_outputs):
        raise ValueError(
            'The number of variances must exactly match the number of outputs')
    if tf.executing_eagerly() and outputs is not None and len(
        self.model.inputs) == 0:
    if outputs is not None and len(self.model.inputs) == 0:
      raise ValueError(
          "Cannot use 'outputs' argument in eager mode with a model that does not specify its inputs"
          "Cannot use 'outputs' argument with a model that does not specify its inputs"
      )
    if isinstance(outputs, tf.Tensor):
      outputs = [outputs]
@@ -545,9 +450,8 @@ class KerasModel(Model):
      inputs, labels, weights = batch
      self._create_inputs(inputs)
      inputs, _, _ = self._prepare_batch((inputs, None, None))
      if tf.executing_eagerly():

        # In eager mode we invoke the model directly.
      # Invoke the model.

      if len(inputs) == 1:
        inputs = inputs[0]
@@ -563,16 +467,6 @@ class KerasModel(Model):
        if isinstance(output_values, tf.Tensor):
          output_values = [output_values]
        output_values = [t.numpy() for t in output_values]
      else:

        # In graph mode we execute the output tensors.

        if outputs is not None:
          fetches = outputs
        else:
          fetches = self._output_tensors
        feed_dict = dict(zip(self._input_placeholders, inputs))
        output_values = self.session.run(fetches, feed_dict=feed_dict)

      # Apply tranformers and record results.

@@ -817,8 +711,8 @@ class KerasModel(Model):
    X = np.reshape(X, [1] + list(X.shape))
    self._create_inputs([X])
    X, _, _ = self._prepare_batch(([X], None, None))
    if tf.executing_eagerly():
      # In eager mode we use a GradientTape to compute gradients.

    # Use a GradientTape to compute gradients.

    X = tf.constant(X[0])
    with tf.GradientTape(
@@ -836,35 +730,6 @@ class KerasModel(Model):
          result.append(tape.gradient(output[i], X))
        final_result.append(
            tf.reshape(tf.stack(result), output_shape + input_shape).numpy())
    else:
      # In graph mode we use tf.gradients().

      def jacobian(y, x):
        # Adapted from https://github.com/tensorflow/tensorflow/issues/675#issuecomment-319891923.
        y = tf.reshape(tf.convert_to_tensor(y)[0], [-1])
        n = y.shape[0]
        loop_vars = [
            tf.constant(0, tf.int32),
            tf.TensorArray(tf.float32, size=n)
        ]
        _, jacobian = tf.while_loop(
            lambda j, _: j < n,
            lambda j, result: (j + 1, result.write(j, tf.gradients(y[j], x))),
            loop_vars)
        return jacobian.stack()

      grads = [
          jacobian(self._output_tensors[i], self._input_placeholders[0])
          for i in self._prediction_outputs
      ]
      feed_dict = {self._input_placeholders[0]: X[0]}
      result = self.session.run(grads, feed_dict=feed_dict)
      output_shapes = [
          tuple(o.shape.as_list()[1:]) for o in self._output_tensors
      ]
      final_result = [
          x.reshape(s + input_shape) for x, s in zip(result, output_shapes)
      ]
    if len(final_result) == 1:
      return final_result[0]
    return final_result
@@ -955,14 +820,7 @@ class KerasModel(Model):
      os.makedirs(model_dir)
    manager = tf.train.CheckpointManager(self._checkpoint, model_dir,
                                         max_checkpoints_to_keep)
    self._exec_with_session(lambda: manager.save())

  def _exec_with_session(self, f):
    if tf.executing_eagerly():
      f()
    else:
      with self.session.as_default():
        f()
    manager.save()

  def get_checkpoints(self, model_dir=None):
    """Get a list of all available checkpoint files.
@@ -998,18 +856,11 @@ class KerasModel(Model):
      checkpoint = tf.train.latest_checkpoint(model_dir)
    if checkpoint is None:
      raise ValueError('No checkpoint found')
    if tf.executing_eagerly():
    self._checkpoint.restore(checkpoint)
    else:
      if session is None:
        session = self.session
      self._checkpoint.restore(checkpoint).run_restore_ops(session)

  def get_global_step(self):
    """Get the number of steps of fitting that have been performed."""
    if tf.executing_eagerly():
    return int(self._global_step)
    return self._global_step.eval(session=self.session)

  def _create_assignment_map(self, source_model, include_top=True, **kwargs):
    """
@@ -1036,7 +887,7 @@ class KerasModel(Model):
      dest_vars = dest_vars[:-2]

    for source_var, dest_var in zip(source_vars, dest_vars):
      assignment_map[source_var] = dest_var
      assignment_map[source_var.experimental_ref()] = dest_var

    return assignment_map

@@ -1054,13 +905,8 @@ class KerasModel(Model):
    value_map = {}
    source_vars = source_model.model.trainable_variables

    if tf.executing_eagerly():
    for source_var in source_vars:
        value_map[source_var] = source_var.numpy()
    else:
      for source_var in source_vars:
        # self.session is used because restore was called in the same session
        value_map[source_var] = source_var.eval(session=self.session)
      value_map[source_var.experimental_ref()] = source_var.numpy()

    return value_map

@@ -1113,11 +959,7 @@ class KerasModel(Model):
      logger.info(
          "No value map provided. Creating default value map from restored model."
      )
      if tf.executing_eagerly():
      source_model.restore(model_dir=model_dir, checkpoint=checkpoint)
      else:
        source_model.restore(
            model_dir=model_dir, checkpoint=checkpoint, session=self.session)
      value_map = self._create_value_map(source_model=source_model)

    if assignment_map is None:
@@ -1125,21 +967,10 @@ class KerasModel(Model):
      assignment_map = self._create_assignment_map(
          source_model=source_model, include_top=include_top)

    if tf.executing_eagerly():
    for source_var, dest_var in assignment_map.items():
        assert source_var.shape == dest_var.shape
      assert source_var.deref().shape == dest_var.shape
      dest_var.assign(value_map[source_var])

    else:
      with self.session.as_default():
        for source_var, dest_var in assignment_map.items():
          assert source_var.shape == dest_var.shape
          assign_op = dest_var.assign(value_map[source_var])
          self.session.run(assign_op)

    dest_vars = list(assignment_map.values())
    self._initialized_vars.update(set(dest_vars))


class _StandardLoss(object):
  """The implements the loss function for models that use a dc.models.losses.Loss."""
+6 −7
Original line number Diff line number Diff line
@@ -647,12 +647,11 @@ class CombineMeanStd(tf.keras.layers.Layer):
    if len(inputs) != 2:
      raise ValueError("Must have two in_layers")
    mean_parent, std_parent = inputs[0], inputs[1]
    if self.training_only and not training:
      return mean_parent
    noise_scale = tf.cast(training or not self.training_only, tf.float32)
    from tensorflow.python.ops import array_ops
    sample_noise = tf.random_normal(
    sample_noise = tf.random.normal(
        array_ops.shape(mean_parent), 0, 1, dtype=tf.float32)
    return mean_parent + std_parent * sample_noise
    return mean_parent + noise_scale * std_parent * sample_noise


class Stack(tf.keras.layers.Layer):
@@ -741,7 +740,7 @@ class VinaFreeEnergy(tf.keras.layers.Layer):

  def build(self, input_shape):
    self.weighted_combo = WeightedLinearCombo()
    self.w = tf.Variable(tf.random_normal((1,), stddev=self.stddev))
    self.w = tf.Variable(tf.random.normal((1,), stddev=self.stddev))
    self.built = True

  def cutoff(self, d, x):
@@ -1354,7 +1353,7 @@ class AlphaShareLayer(tf.keras.layers.Layer):
  def build(self, input_shape):
    n_alphas = 2 * len(input_shape)
    self.alphas = tf.Variable(
        tf.random_normal([n_alphas, n_alphas]), name='alphas')
        tf.random.normal([n_alphas, n_alphas]), name='alphas')
    self.built = True

  def call(self, inputs):
@@ -1441,7 +1440,7 @@ class BetaShare(tf.keras.layers.Layer):

  def build(self, input_shape):
    n_betas = len(input_shape)
    self.betas = tf.Variable(tf.random_normal([1, n_betas]), name='betas')
    self.betas = tf.Variable(tf.random.normal([1, n_betas]), name='betas')
    self.built = True

  def call(self, inputs):
+8 −10
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@ class VariationalRandomizer(Layer):
        [embedding_mean, embedding_stddev], training=training)
    mean_sq = embedding_mean * embedding_mean
    stddev_sq = embedding_stddev * embedding_stddev
    kl = mean_sq + stddev_sq - tf.log(stddev_sq + 1e-20) - 1
    kl = mean_sq + stddev_sq - tf.math.log(stddev_sq + 1e-20) - 1
    anneal_steps = self._annealing_final_step - self._annealing_start_step
    if anneal_steps > 0:
      current_step = tf.cast(global_step,
@@ -213,7 +213,7 @@ class SeqToSeq(KerasModel):
    def loss_fn(outputs, labels, weights):
      prob = tf.reduce_sum(outputs[0] * labels[0], axis=2)
      mask = tf.reduce_sum(labels[0], axis=2)
      log_prob = tf.log(prob + 1e-20) * mask
      log_prob = tf.math.log(prob + 1e-20) * mask
      loss = -tf.reduce_mean(tf.reduce_sum(log_prob, axis=1))
      return loss + sum(self.model.losses)

@@ -263,8 +263,8 @@ class SeqToSeq(KerasModel):
      indices = np.array([(i, len(batch[i]) if i < len(batch) else 0)
                          for i in range(self.batch_size)])
      probs = self.predict_on_generator([[(features, indices,
                                           self.get_global_step()), None,
                                          None]])
                                           np.array(self.get_global_step())),
                                          None, None]])
      for i in range(len(batch)):
        result.append(self._beam_search(probs[i], beam_width))
    return result
@@ -288,10 +288,7 @@ class SeqToSeq(KerasModel):
      for i, e in enumerate(batch):
        embedding_array[i] = e
      probs = self.decoder(embedding_array, training=False)
      if tf.executing_eagerly():
      probs = probs.numpy()
      else:
        probs = probs.eval(session=self.session)
      for i in range(len(batch)):
        result.append(self._beam_search(probs[i], beam_width))
    return result
@@ -310,7 +307,7 @@ class SeqToSeq(KerasModel):
      indices = np.array([(i, len(batch[i]) if i < len(batch) else 0)
                          for i in range(self.batch_size)])
      embeddings = self.predict_on_generator(
          [[(features, indices, self.get_global_step()), None, None]],
          [[(features, indices, np.array(self.get_global_step())), None, None]],
          outputs=self._embedding)
      for i in range(len(batch)):
        result.append(embeddings[i])
@@ -410,7 +407,8 @@ class SeqToSeq(KerasModel):
      features = self._create_input_array(inputs)
      labels = self._create_output_array(outputs)
      gather_indices = np.array([(i, len(x)) for i, x in enumerate(inputs)])
      yield ([features, gather_indices, self.get_global_step()], [labels], [])
      yield ([features, gather_indices,
              np.array(self.get_global_step())], [labels], [])


class AspuruGuzikAutoEncoder(SeqToSeq):
+1 −7
Original line number Diff line number Diff line
@@ -3,14 +3,13 @@ import tempfile
import deepchem as dc
import numpy as np
import tensorflow as tf
from tensorflow.python.eager import context
try:
  from StringIO import StringIO
except ImportError:
  from io import StringIO


class TestKerasModel(unittest.TestCase):
class TestCallbacks(unittest.TestCase):

  def test_validation(self):
    """Test ValidationCallback."""
@@ -52,8 +51,3 @@ class TestKerasModel(unittest.TestCase):
    valid_score = model.evaluate(valid_dataset, [metric], transformers)
    self.assertAlmostEqual(
        valid_score['mean-roc_auc_score'], max(scores), places=5)

  def test_validation_eager(self):
    """Test ValidationCallback, in eager mode."""
    with context.eager_mode():
      self.test_validation()
Loading