Commit c4016be5 authored by miaecle's avatar miaecle
Browse files

Merge remote-tracking branch 'remotes/origin/master' into BP

parents 86a93af4 287ada79
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ import deepchem as dc
import deepchem.rl.envs.tictactoe
from deepchem.models.tensorgraph.layers import Flatten, Dense, SoftMax, \
    BatchNorm, Squeeze
from deepchem.models.tensorgraph.optimizers import Adam


class TicTacToePolicy(dc.rl.Policy):
@@ -66,8 +67,7 @@ def eval_tic_tac_toe(value_weight,
        entropy_weight=0.01,
        value_weight=value_weight,
        model_dir=model_dir,
        optimizer=dc.models.tensorgraph.TFWrapper(
            tf.train.AdamOptimizer, learning_rate=0.001))
        optimizer=Adam(learning_rate=0.001))
    try:
      a3c.restore()
    except:
+17 −0
Original line number Diff line number Diff line
@@ -396,6 +396,23 @@ class NumpyDataset(Dataset):
    ids = self.ids[indices]
    return NumpyDataset(X, y, w, ids)

  @staticmethod
  def from_DiskDataset(ds):
    """

    Parameters
    ----------
    ds : DiskDataset
    DiskDataset to transorm to NumpyDataset

    Returns
    -------
    NumpyDataset
      Data of ds as NumpyDataset

    """
    return NumpyDataset(ds.X, ds.y, ds.w, ds.ids)


class DiskDataset(Dataset):
  """
+16 −17
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@ from operator import mul
from deepchem.utils.evaluate import Evaluator
from deepchem.utils.save import log


class HyperparamOpt(object):
  """
  Provides simple hyperparameter search capabilities.
@@ -23,8 +24,13 @@ class HyperparamOpt(object):

  # TODO(rbharath): This function is complicated and monolithic. Is there a nice
  # way to refactor this?
  def hyperparam_search(self, params_dict, train_dataset, valid_dataset,
                        output_transformers, metric, use_max=True,
  def hyperparam_search(self,
                        params_dict,
                        train_dataset,
                        valid_dataset,
                        output_transformers,
                        metric,
                        use_max=True,
                        logdir=None):
    """Perform hyperparams search according to params_dict.
    
@@ -40,8 +46,6 @@ class HyperparamOpt(object):

    number_combinations = reduce(mul, [len(vals) for vals in hyperparam_vals])

    valid_csv_out = tempfile.NamedTemporaryFile()
    valid_stats_out = tempfile.NamedTemporaryFile()
    if use_max:
      best_validation_score = -np.inf
    else:
@@ -49,10 +53,10 @@ class HyperparamOpt(object):
    best_hyperparams = None
    best_model, best_model_dir = None, None
    all_scores = {}
    for ind, hyperparameter_tuple in enumerate(itertools.product(*hyperparam_vals)):
    for ind, hyperparameter_tuple in enumerate(
        itertools.product(*hyperparam_vals)):
      model_params = {}
      log("Fitting model %d/%d" % (ind+1, number_combinations),
          self.verbose)
      log("Fitting model %d/%d" % (ind + 1, number_combinations), self.verbose)
      for hyperparam, hyperparam_val in zip(hyperparams, hyperparameter_tuple):
        model_params[hyperparam] = hyperparam_val
      log("hyperparameters: %s" % str(model_params), self.verbose)
@@ -75,8 +79,7 @@ class HyperparamOpt(object):
      model.save()

      evaluator = Evaluator(model, valid_dataset, output_transformers)
      multitask_scores = evaluator.compute_model_performance(
          [metric], valid_csv_out.name, valid_stats_out.name)
      multitask_scores = evaluator.compute_model_performance([metric])
      valid_score = multitask_scores[metric.name]
      all_scores[str(hyperparameter_tuple)] = valid_score

@@ -92,8 +95,8 @@ class HyperparamOpt(object):
        shutil.rmtree(model_dir)

      log("Model %d/%d, Metric %s, Validation set %s: %f" %
          (ind+1, number_combinations, metric.name, ind, valid_score),
          self.verbose)
          (ind + 1, number_combinations, metric.name, ind,
           valid_score), self.verbose)
      log("\tbest_validation_score so far: %f" % best_validation_score,
          self.verbose)
    if best_model is None:
@@ -101,14 +104,10 @@ class HyperparamOpt(object):
      # arbitrarily return last model
      best_model, best_hyperparams = model, hyperparameter_tuple
      return best_model, best_hyperparams, all_scores
    train_csv_out = tempfile.NamedTemporaryFile()
    train_stats_out = tempfile.NamedTemporaryFile()
    train_evaluator = Evaluator(best_model, train_dataset, output_transformers)
    multitask_scores = train_evaluator.compute_model_performance(
        [metric], train_csv_out.name, train_stats_out.name)
    multitask_scores = train_evaluator.compute_model_performance([metric])
    train_score = multitask_scores[metric.name]
    log("Best hyperparameters: %s" % str(best_hyperparams),
        self.verbose)
    log("Best hyperparameters: %s" % str(best_hyperparams), self.verbose)
    log("train_score: %f" % train_score, self.verbose)
    log("validation_score: %f" % best_validation_score, self.verbose)
    return best_model, best_hyperparams, all_scores
+170 −0
Original line number Diff line number Diff line
"""Optimizers and related classes for use with TensorGraph."""

import tensorflow as tf


class Optimizer(object):
  """An algorithm for optimizing a TensorGraph based model.

  This is an abstract class.  Subclasses represent specific optimization algorithms.
  """

  def _create_optimizer(self, global_step):
    """Construct the TensorFlow optimizer.

    Parameters
    ----------
    global_step: tensor
      a tensor containing the global step index during optimization, used for learning rate decay

    Returns
    -------
    a new TensorFlow optimizer implementing the algorithm
    """
    raise NotImplemented("Subclasses must implement this")


class LearningRateSchedule(object):
  """A schedule for changing the learning rate over the course of optimization.

  This is an abstract class.  Subclasses represent specific schedules.
  """

  def _create_tensor(self, global_step):
    """Construct a tensor that equals the learning rate.

    Parameters
    ----------
    global_step: tensor
      a tensor containing the global step index during optimization

    Returns
    -------
    a tensor that equals the learning rate
    """
    raise NotImplemented("Subclasses must implement this")


class Adam(Optimizer):
  """The Adam optimization algorithm."""

  def __init__(self, learning_rate=0.001, beta1=0.9, beta2=0.999,
               epsilon=1e-08):
    """Construct an Adam optimizer.

    Parameters
    ----------
    learning_rate: float or LearningRateSchedule
      the learning rate to use for optimization
    beta1: float
      a parameter of the Adam algorithm
    beta2: float
      a parameter of the Adam algorithm
    epsilon: float
      a parameter of the Adam algorithm
    """
    self.learning_rate = learning_rate
    self.beta1 = beta1
    self.beta2 = beta2
    self.epsilon = epsilon

  def _create_optimizer(self, global_step):
    if isinstance(self.learning_rate, LearningRateSchedule):
      learning_rate = self.learning_rate._create_tensor(global_step)
    else:
      learning_rate = self.learning_rate
    return tf.train.AdamOptimizer(
        learning_rate=learning_rate,
        beta1=self.beta1,
        beta2=self.beta2,
        epsilon=self.epsilon)


class GradientDescent(Optimizer):
  """The gradient descent optimization algorithm."""

  def __init__(self, learning_rate=0.001):
    """Construct a gradient descent optimizer.

    Parameters
    ----------
    learning_rate: float or LearningRateSchedule
      the learning rate to use for optimization
    """
    self.learning_rate = learning_rate

  def _create_optimizer(self, global_step):
    if isinstance(self.learning_rate, LearningRateSchedule):
      learning_rate = self.learning_rate._create_tensor(global_step)
    else:
      learning_rate = self.learning_rate
    return tf.train.GradientDescentOptimizer(learning_rate=learning_rate)


class ExponentialDecay(LearningRateSchedule):
  """A learning rate that decreases exponentially with the number of training steps."""

  def __init__(self, initial_rate, decay_rate, decay_steps, staircase=True):
    """Create an exponentially decaying learning rate.

    The learning rate starts as initial_rate.  Every decay_steps training steps, it is multiplied by decay_rate.

    Parameters
    ----------
    initial_rate: float
      the initial learning rate
    decay_rate: float
      the base of the exponential
    decay_steps: int
      the number of training steps over which the rate decreases by decay_rate
    staircase: bool
      if True, the learning rate decreases by discrete jumps every decay_steps.
      if False, the learning rate decreases smoothly every step
    """
    self.initial_rate = initial_rate
    self.decay_rate = decay_rate
    self.decay_steps = decay_steps
    self.staircase = staircase

  def _create_tensor(self, global_step):
    return tf.train.exponential_decay(
        learning_rate=self.initial_rate,
        global_step=global_step,
        decay_rate=self.decay_rate,
        decay_steps=self.decay_steps,
        staircase=self.staircase)


class PolynomialDecay(LearningRateSchedule):
  """A learning rate that decreases from an initial value to a final value over a fixed number of training steps."""

  def __init__(self, initial_rate, final_rate, decay_steps, power=1.0):
    """Create a smoothly decaying learning rate.

    The learning rate starts as initial_rate.  It smoothly decreases to final_rate over decay_steps training steps.
    It decays as a function of (1-step/decay_steps)**power.  Once the final rate is reached, it remains there for
    the rest of optimization.

    Parameters
    ----------
    initial_rate: float
      the initial learning rate
    final_rate: float
      the final learning rate
    decay_steps: int
      the number of training steps over which the rate decreases from initial_rate to final_rate
    power: float
      the exponent controlling the shape of the decay
    """
    self.initial_rate = initial_rate
    self.final_rate = final_rate
    self.decay_steps = decay_steps
    self.power = power

  def _create_tensor(self, global_step):
    return tf.train.polynomial_decay(
        learning_rate=self.initial_rate,
        end_learning_rate=self.final_rate,
        global_step=global_step,
        decay_steps=self.decay_steps,
        power=self.power)
+9 −13
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ from deepchem.data import NumpyDataset
from deepchem.metrics import to_one_hot, from_one_hot
from deepchem.models.models import Model
from deepchem.models.tensorgraph.layers import InputFifoQueue, Label, Feature, Weights
from deepchem.models.tensorgraph.optimizers import Adam
from deepchem.trans import undo_transforms
from deepchem.utils.evaluate import GeneratorEvaluator
from deepchem.feat.graph_features import ConvMolFeaturizer
@@ -54,6 +55,8 @@ class TensorGraph(Model):
    graph: tensorflow.Graph
      the Graph in which to create Tensorflow objects.  If None, a new Graph
      is created.
    learning_rate: float or LearningRateSchedule
      the learning rate to use for optimization
    kwargs
    """

@@ -67,12 +70,8 @@ class TensorGraph(Model):
    self.loss = None
    self.built = False
    self.queue_installed = False
    self.optimizer = TFWrapper(
        tf.train.AdamOptimizer,
        learning_rate=learning_rate,
        beta1=0.9,
        beta2=0.999,
        epsilon=1e-7)
    self.optimizer = Adam(
        learning_rate=learning_rate, beta1=0.9, beta2=0.999, epsilon=1e-7)

    # Singular place to hold Tensor objects which don't serialize
    # These have to be reconstructed on restoring from pickle
@@ -234,7 +233,7 @@ class TensorGraph(Model):
          feed_dict[self.features[0]] = X_b
        if len(self.task_weights) == 1 and w_b is not None and not predict:
          feed_dict[self.task_weights[0]] = w_b
        for (inital_state, zero_state) in zip(self.rnn_initial_states,
        for (initial_state, zero_state) in zip(self.rnn_initial_states,
                                               self.rnn_zero_states):
          feed_dict[initial_state] = zero_state
        yield feed_dict
@@ -425,11 +424,7 @@ class TensorGraph(Model):
    self.outputs.append(layer)

  def set_optimizer(self, optimizer):
    """Set the optimizer to use for fitting.

    The argument should be a callable object (most often a TFWrapper) that constructs
    a Tensorflow optimizer when called.
    """
    """Set the optimizer to use for fitting."""
    self.optimizer = optimizer

  def get_pickling_errors(self, obj, seen=None):
@@ -562,7 +557,8 @@ class TensorGraph(Model):
    elif obj == "FileWriter":
      self.tensor_objects['FileWriter'] = tf.summary.FileWriter(self.model_dir)
    elif obj == 'Optimizer':
      self.tensor_objects['Optimizer'] = self.optimizer()
      self.tensor_objects['Optimizer'] = self.optimizer._create_optimizer(
          self._get_tf('GlobalStep'))
    elif obj == 'train_op':
      self.tensor_objects['train_op'] = self._get_tf('Optimizer').minimize(
          self.loss.out_tensor, global_step=self._get_tf('GlobalStep'))
Loading