Commit c5b049a0 authored by Bharath Ramsundar's avatar Bharath Ramsundar
Browse files

Merge pull request #182 from rbharath/multitask_debug

Correct multitask data loading issue.
parents af059dd0 588901e2
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -199,7 +199,17 @@ class Dataset(object):
        yield (X_batch, y_batch, w_batch, ids_batch)

  @staticmethod
  def from_numpy(data_dir, tasks, X, y, w, ids):
  def from_numpy(data_dir, X, y, w=None, ids=None, tasks=None):
    n_samples = len(X)
    # The -1 indicates that y will be reshaped to have length -1
    y = np.reshape(y, (n_samples, -1))
    n_tasks = y.shape[1]
    if ids is None:
      ids = np.arange(n_samples)
    if w is None:
      w = np.ones_like(y)
    if tasks is None:
      tasks = np.arange(n_tasks)
    raw_data = (ids, X, y, w)
    return Dataset(data_dir=data_dir, tasks=tasks, raw_data=raw_data)
    
@@ -374,8 +384,7 @@ def _df_to_numpy(df, feature_types, tasks):
  # perform common train/test split across all tasks
  n_samples = df.shape[0]
  n_tasks = len(tasks)
  y = np.array([df[task].values for task in tasks])
  y = np.reshape(y, (n_samples, n_tasks))
  y = np.hstack([np.reshape(np.array(df[task].values), (n_samples, 1)) for task in tasks])
  w = np.ones((n_samples, n_tasks))
  missing = np.zeros_like(y).astype(int)
  tensors = []
+126 −0
Original line number Diff line number Diff line
"""
Testing singletask/multitask data loading capabilities.
"""
from __future__ import print_function
from __future__ import division
from __future__ import unicode_literals

__author__ = "Bharath Ramsundar"
__copyright__ = "Copyright 2016, Stanford University"
__license__ = "LGPL"

import os
import shutil
import tempfile
import numpy as np
from deepchem.models.tests import TestAPI
from deepchem.utils.save import load_from_disk
from deepchem.featurizers.fingerprints import CircularFingerprint
from deepchem.featurizers.featurize import DataFeaturizer
from deepchem.datasets import Dataset

## task0: 1,1,0,-,0,-,1,-,-,1

class TestLoad(TestAPI):
  """
  Test singletask/multitask data loading.
  """

  def test_singletask_matches_multitask_load(self):
    """Check that singletask load and multitask load of dataset are same."""
    # Only for debug!
    np.random.seed(123)

    # Set some global variables up top
    reload = True
    verbosity = "high"

    base_dir = tempfile.mkdtemp()

    current_dir = os.path.dirname(os.path.realpath(__file__))
    #Make directories to store the raw and featurized datasets.
    feature_dir = os.path.join(base_dir, "features")
    samples_dir = os.path.join(base_dir, "samples")
    full_dir = os.path.join(base_dir, "full_dataset")
    train_dir = os.path.join(base_dir, "train_dataset")
    valid_dir = os.path.join(base_dir, "valid_dataset")
    test_dir = os.path.join(base_dir, "test_dataset")
    model_dir = os.path.join(base_dir, "model")

    # Load dataset
    print("About to load dataset.")
    dataset_file = os.path.join(
        current_dir, "../../models/tests/multitask_example.csv")
    dataset = load_from_disk(dataset_file)
    print("Columns of dataset: %s" % str(dataset.columns.values))
    print("Number of examples in dataset: %s" % str(dataset.shape[0]))

    # Featurize tox21 dataset
    print("About to featurize dataset.")
    featurizers = [CircularFingerprint(size=1024)]
    all_tasks = ["task%d"%i for i in range(17)] 
    # For debugging purposes
    n_tasks = 17 
    tasks = all_tasks[0:n_tasks]
    valid_scores = {}

    ####### Do multitask load
    if os.path.exists(feature_dir):
      shutil.rmtree(feature_dir)
    featurizer = DataFeaturizer(tasks=tasks,
                                smiles_field="smiles",
                                compound_featurizers=featurizers,
                                verbosity=verbosity)
    featurized_samples = featurizer.featurize(
        dataset_file, feature_dir,
        samples_dir, shard_size=8192,
        reload=reload)
    if os.path.exists(full_dir):
      shutil.rmtree(full_dir)
    full_dataset = Dataset(data_dir=full_dir, samples=featurized_samples, 
                            featurizers=featurizers, tasks=tasks,
                            verbosity=verbosity, reload=reload)

    # Do train/valid split.
    X_multi, y_multi, w_multi, ids_multi = full_dataset.to_numpy()


    ####### Do singletask load
    X_tasks, y_tasks, w_tasks, ids_tasks = [], [], [], []
    for task in tasks:
      print("Processing task %s" % task)
      if os.path.exists(feature_dir):
        shutil.rmtree(feature_dir)
      featurizer = DataFeaturizer(tasks=[task],
                                  smiles_field="smiles",
                                  compound_featurizers=featurizers,
                                  verbosity=verbosity)
      featurized_samples = featurizer.featurize(
          dataset_file, feature_dir,
          samples_dir, shard_size=8192,
          reload=reload)
      if os.path.exists(full_dir):
        shutil.rmtree(full_dir)
      full_dataset = Dataset(data_dir=full_dir, samples=featurized_samples, 
                              featurizers=featurizers, tasks=[task],
                              verbosity=verbosity, reload=reload)

      X_task, y_task, w_task, ids_task = full_dataset.to_numpy()
      X_tasks.append(X_task)
      y_tasks.append(y_task)
      w_tasks.append(w_task)
      ids_tasks.append(ids_task)

    ################## Do comparison
    for ind, task in enumerate(tasks):
      y_multi_task = y_multi[:, ind]
      w_multi_task = w_multi[:, ind]

      #X_task = X_tasks[ind]
      y_task = y_tasks[ind]
      w_task = w_tasks[ind]
      ids_task = ids_tasks[ind]

      np.testing.assert_allclose(y_multi_task.flatten(), y_task.flatten())
      np.testing.assert_allclose(w_multi_task.flatten(), w_task.flatten())
    shutil.rmtree(base_dir)
+0 −1
Original line number Diff line number Diff line
@@ -350,7 +350,6 @@ class FeaturizedSamples(object):
    self.compounds_df = compounds_df
    self.num_samples = len(compounds_df)


  def _get_compounds_filename(self):
    """
    Get standard location for file listing compounds in this dataframe.
+6 −4
Original line number Diff line number Diff line
@@ -94,8 +94,9 @@ class TestHyperparamOptAPI(TestAPI):
    y_train = np.random.randint(2, size=(n_train, n_tasks))
    w_train = np.ones_like(y_train)
    ids_train = ["C"] * n_train
    train_dataset = Dataset.from_numpy(self.train_dir, tasks,
                                       X_train, y_train, w_train, ids_train)
    train_dataset = Dataset.from_numpy(self.train_dir,
                                       X_train, y_train, w_train, ids_train,
                                       tasks)

    # Define validation dataset
    n_valid = 10
@@ -103,8 +104,9 @@ class TestHyperparamOptAPI(TestAPI):
    y_valid = np.random.randint(2, size=(n_valid, n_tasks))
    w_valid = np.ones_like(y_valid)
    ids_valid = ["C"] * n_valid
    valid_dataset = Dataset.from_numpy(self.valid_dir, tasks,
                                       X_valid, y_valid, w_valid, ids_valid)
    valid_dataset = Dataset.from_numpy(self.valid_dir,
                                       X_valid, y_valid, w_valid, ids_valid,
                                       tasks)
    params_dict = {
        "batch_size": [32],
        "data_shape": [train_dataset.get_data_shape()],
+9 −3
Original line number Diff line number Diff line
@@ -123,7 +123,7 @@ class Metric(object):
    assert mode in ["classification", "regression"]
    self.mode = mode

  def compute_metric(self, y_true, y_pred, w, n_classes=2):
  def compute_metric(self, y_true, y_pred, w=None, n_classes=2):
    """Compute a performance metric for each task.

    Args:
@@ -134,12 +134,18 @@ class Metric(object):
    Returns:
      A numpy array containing metric values for each task.
    """
    assert y_true.shape[0] == y_pred.shape[0] == w.shape[0]
    if len(y_true.shape) > 1:
      n_samples, n_tasks = y_true.shape[0], y_true.shape[1] 
    else:
      n_samples, n_tasks = y_true.shape[0], 1
    if self.mode == "classification":
      y_pred = np.reshape(y_pred, (n_samples, n_tasks, n_classes))
    else:
      y_pred = np.reshape(y_pred, (n_samples, n_tasks))
    y_true = np.reshape(y_true, (n_samples, n_tasks))
    if w is None:
      w = np.ones_like(y_true)
    assert y_true.shape[0] == y_pred.shape[0] == w.shape[0]
    computed_metrics = []
    for task in xrange(n_tasks):
      y_task = y_true[:, task]
@@ -183,8 +189,8 @@ class Metric(object):
    # If there are no nonzero examples, metric is ill-defined.
    if not y_true.size:
      return np.nan
    y_true = np.reshape(y_true, (n_samples,))

    y_true = np.reshape(y_true, (n_samples,))
    if self.mode == "classification":
      n_classes = y_pred.shape[-1]
      # TODO(rbharath): This has been a major source of bugs. Is there a more
Loading