Commit 48a88fb8 authored by Bharath's avatar Bharath
Browse files

Merge branch 'master' of https://github.com/deepchem/deepchem into vs-utils-scripts

parents 2282dac1 012e5874
Loading
Loading
Loading
Loading
+58 −1
Original line number Diff line number Diff line
@@ -95,7 +95,8 @@ class Dataset(object):
    """
    if not len(self.metadata_df):
      raise ValueError("No data in dataset.")
    sample_X = load_from_disk(self.metadata_df.iterrows().next()[1]['X'])[0]
    sample_X = load_from_disk(
        self.metadata_df.iterrows().next()[1]['X-transformed'])[0]
    return np.shape(sample_X)

  def _get_metadata_filename(self):
@@ -189,6 +190,13 @@ class Dataset(object):
    X_means, X_stds, y_means, y_stds = compute_mean_and_std(df)
    return X_means, X_stds, y_means, y_stds
  
  def update_moments(self):
    """Re-compute statistics of this dataset during transformation"""
    df = self.metadata_df
    X_means, X_stds, y_means, y_stds = update_mean_and_std(df)
    return X_means, X_stds, y_means, y_stds
 
 
def compute_sums_and_nb_sample(tensor, W=None):
  """
  Computes sums, squared sums of tensor along axis 0.
@@ -329,3 +337,52 @@ def compute_mean_and_std(df):
  y_means = np.sum(y_sums, axis=0)/y_n
  y_vars = np.sum(y_sum_squares, axis=0)/y_n - np.square(y_means)
  return overall_X_means, np.sqrt(X_vars), y_means, np.sqrt(y_vars)

def update_mean_and_std(df):
  """
  Compute means/stds of X/y from sums/sum_squares of tensors.
  """
  X_n = list(df['X_n']) 
  X_transform = []
  for _, row in df.iterrows():
    Xt = load_from_disk(row['X-transformed'])
    X_transform.append(np.array(Xt))

  # Re-calculate X_sums and X_sum_squares 
  X_sums = []
  X_sum_squares = []
  for i, row in df.iterrows():
    Xs = np.sum(X_transform[i],axis=0)
    Xss = np.sum(np.square(X_transform[i]),axis=0)
    X_sums.append(Xs)
    X_sum_squares.append(Xss)

  n = float(np.sum(X_n))
  X_sums = np.vstack(X_sums)
  X_sum_squares = np.vstack(X_sum_squares)
  overall_X_sums = np.sum(X_sums, axis=0)
  overall_X_means = overall_X_sums / n
  overall_X_sum_squares = np.sum(X_sum_squares, axis=0)

  X_vars = (overall_X_sum_squares - np.square(overall_X_sums)/n)/(n)

  y_n = list(df['y_n'])
  y_transform = []
  for _, row in df.iterrows():
    yt = load_from_disk(row['y-transformed'])
    y_transform.append(np.array(yt))

  y_sums = []
  y_sum_squares = []
  for i, row in df.iterrows():
    ys = np.sum(y_transform[i],axis=0)
    yss = np.sum(np.square(y_transform[i]),axis=0)
    y_sums.append(ys)
    y_sum_squares.append(yss)

  y_n = np.sum(y_n, axis=0)
  y_sums = np.vstack(y_sums)
  y_sum_squares = np.vstack(y_sum_squares)
  y_means = np.sum(y_sums, axis=0)/y_n
  y_vars = np.sum(y_sum_squares, axis=0)/y_n - np.square(y_means)
  return overall_X_means, np.sqrt(X_vars), y_means, np.sqrt(y_vars)
+15 −7
Original line number Diff line number Diff line
@@ -51,19 +51,24 @@ class HyperparamOpt(object):
        model_params[hyperparam] = hyperparam_val

      model_dir = tempfile.mkdtemp()
      model = self.model_class(self.task_types, model_params, logdir=logdir,
                               train=True)
      if logdir is not None:
        model = self.model_class(self.task_types, model_params, logdir=logdir)
      else:
        model = self.model_class(self.task_types, model_params)
      model.fit(train_dataset)
      model.save(model_dir)
    
      evaluator = Evaluator(model, valid_dataset, output_transformers)
      df, score = evaluator.compute_model_performance(
      df, scores_df, multitask_scores = evaluator.compute_model_performance(
          [metric], valid_csv_out, valid_stats_out)
      valid_score = score.iloc[0][metric.name]
      if not metric.is_multitask:
        valid_score = scores_df.iloc[0][metric.name]
      else:
        valid_score = multitask_scores[metric.name]
      all_scores[hyperparameter_tuple] = valid_score
    
      if (use_max and valid_score > best_validation_score) or (
          not use_max and valid_score < best_validation_score):
      if (use_max and valid_score >= best_validation_score) or (
          not use_max and valid_score <= best_validation_score):
        best_validation_score = valid_score
        best_hyperparams = hyperparameter_tuple
        if best_model_dir is not None:
@@ -82,9 +87,12 @@ class HyperparamOpt(object):
    train_csv_out = tempfile.NamedTemporaryFile()
    train_stats_out = tempfile.NamedTemporaryFile()
    train_evaluator = Evaluator(best_model, train_dataset, output_transformers)
    train_df, train_score = train_evaluator.compute_model_performance(
    train_df, train_score, multitask_scores = train_evaluator.compute_model_performance(
        [metric], train_csv_out, train_stats_out)
    if not metric.is_multitask:
      train_score = train_score.iloc[0][metric.name]
    else:
      train_score = multitask_scores[metric.name]
    log("Best hyperparameters: %s" % str(zip(hyperparams, best_hyperparams)),
        self.verbosity)
    log("train_score: %f" % train_score, self.verbosity)
+42 −2
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ import os
import unittest
import tempfile
import shutil
import numpy as np
from deepchem.models.test import TestAPI
from deepchem.models.sklearn_models import SklearnModel
from deepchem.featurizers.fingerprints import CircularFingerprint
@@ -21,8 +22,7 @@ from deepchem import metrics
from deepchem.metrics import Metric
from sklearn.ensemble import RandomForestRegressor

def rf_model_builder(task_types, params_dict, logdir=None,
                     train=True):
def rf_model_builder(task_types, params_dict, logdir=None):
    """Builds random forests given hyperparameters.

    Last two arguments only for tensorflow models and ignored.
@@ -62,3 +62,43 @@ class TestHyperparamOptAPI(TestAPI):
    self._hyperparam_opt(rf_model_builder, params_dict, train_dataset,
                         valid_dataset, output_transformers, task_types,
                         metric)

  def test_multitask_keras_mlp_ECFP_classification_hyperparam_opt(self):
    """Straightforward test of Keras multitask deepchem classification API."""
    from deepchem.models.keras_models.fcnet import MultiTaskDNN
    splittype = "scaffold"
    output_transformers = []
    input_transformers = []
    task_type = "classification"

    input_file = os.path.join(self.current_dir, "multitask_example.csv")
    tasks = ["task0", "task1", "task2", "task3", "task4", "task5", "task6",
             "task7", "task8", "task9", "task10", "task11", "task12",
             "task13", "task14", "task15", "task16"]
    task_types = {task: task_type for task in tasks}

    compound_featurizers = [CircularFingerprint(size=1024)]
    complex_featurizers = []

    train_dataset, valid_dataset, _, transformers = self._featurize_train_test_split(
        splittype, compound_featurizers, 
        complex_featurizers, input_transformers,
        output_transformers, input_file, task_types.keys())
    metric = Metric(metrics.matthews_corrcoef, np.mean)
    params_dict= {"nb_hidden": [5, 10],
                  "activation": ["relu"],
                  "dropout": [.5],
                  "learning_rate": [.01],
                  "momentum": [.9],
                  "nesterov": [False],
                  "decay": [1e-4],
                  "batch_size": [5],
                  "nb_epoch": [2],
                  "init": ["glorot_uniform"],
                  "nb_layers": [1],
                  "batchnorm": [False],
                  "data_shape": [train_dataset.get_data_shape()]}
    
    self._hyperparam_opt(MultiTaskDNN, params_dict, train_dataset,
                         valid_dataset, output_transformers, task_types,
                         metric)
+39 −28
Original line number Diff line number Diff line
@@ -15,9 +15,6 @@
# limitations under the License.
"""Evaluation metrics."""

import collections


import numpy as np
import warnings
from sklearn.metrics import roc_auc_score
@@ -28,30 +25,6 @@ from sklearn.metrics import r2_score
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_error

def compute_metrics(num_tasks, y_true, y_pred, metric):
  """Compute a performance metric for each task.

  Args:
    y_true: A list of arrays containing true values for each task.
    y_pred: A list of arrays containing predicted values for each task.
    metric: Must be a class that inherits from Metric 

  Returns:
    A numpy array containing metric values for each task.
  """
  computed_metrics = []
  for task in xrange(num_tasks):
    yt = y_true[task]
    yp = y_pred[task]
    try:
      metric_value = metric.compute(yt, yp)
    except (AssertionError, ValueError) as e:
      warnings.warn("Error calculating metric %s for task %d: %s"
                    % (metric_str, task, e))
      metric_value = np.nan
    computed_metrics.append(metric_value)
  return computed_metrics

def compute_roc_auc_scores(y, y_pred):
  """Transforms the results dict into roc-auc-scores and prints scores.

@@ -105,20 +78,58 @@ def kappa_score(y_true, y_pred):
class Metric(object):
  """Wrapper class for computing user-defined metrics."""

  def __init__(self, metric, name=None, threshold=None):
  def __init__(self, metric, task_averager=None, name=None, threshold=None):
    """
    Args:
      metric: function that takes args y_true, y_pred (in that order) and
              computes desired score.
      task_averager: If not None, should be a function that averages metrics
              across tasks. For example, task_averager=np.mean. If task_averager
              is provided, this task will be inherited as a multitask metric.
    """
    self.metric = metric
    self.task_averager = task_averager
    self.is_multitask = (self.task_averager is not None)
    if name is None:
      if not self.is_multitask:  
        self.name = self.metric.__name__
      else:
        self.name = self.task_averager.__name__ + "-" + self.metric.__name__
    else:
      self.name = name
    self.threshold = threshold

  def compute_metric(self, y_true, y_pred):
    """Compute a performance metric for each task.

    Args:
      num_tasks: Number of tasks
      y_true: A list of arrays containing true values for each task.
      y_pred: A list of arrays containing predicted values for each task.
      metric: Must be a class that inherits from Metric 

    Returns:
      A numpy array containing metric values for each task.
    """
    assert len(y_true) == len(y_pred)
    num_tasks = len(y_true)
    computed_metrics = []
    for task in xrange(num_tasks):
      yt = y_true[task]
      yp = y_pred[task]
      try:
        metric_value = self.compute_singletask_metric(yt, yp)
      except (AssertionError, ValueError) as e:
        warnings.warn("Error calculating metric %s for task %d: %s"
                      % (metric_str, task, e))
        metric_value = np.nan
      computed_metrics.append(metric_value)
    if not self.is_multitask:
      return computed_metrics
    else:
      return self.task_averager(computed_metrics)

  def compute_singletask_metric(self, y_true, y_pred):
    """Compute a metric value.

    Args:
+2 −2
Original line number Diff line number Diff line
@@ -73,14 +73,14 @@ class TestAPI(unittest.TestCase):
    evaluator = Evaluator(model, train_dataset, transformers, verbose=True)
    with tempfile.NamedTemporaryFile() as train_csv_out:
      with tempfile.NamedTemporaryFile() as train_stats_out:
        _, _ = evaluator.compute_model_performance(
        _, _, _ = evaluator.compute_model_performance(
            metrics, train_csv_out, train_stats_out)

    # Eval model on test
    evaluator = Evaluator(model, test_dataset, transformers, verbose=True)
    with tempfile.NamedTemporaryFile() as test_csv_out:
      with tempfile.NamedTemporaryFile() as test_stats_out:
        _, _ = evaluator.compute_model_performance(
        _, _, _ = evaluator.compute_model_performance(
            metrics, test_csv_out, test_stats_out)

  def _featurize_train_test_split(self, splittype, compound_featurizers, 
Loading