Commit 5ba7e79d authored by miaecle's avatar miaecle
Browse files

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

parents 56d66761 300a60d6
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
[![Coverage Status](https://coveralls.io/repos/github/deepchem/deepchem/badge.svg?branch=master)](https://coveralls.io/github/deepchem/deepchem?branch=master)

DeepChem aims to provide a high quality open-source toolchain that
democratizes the use of deep-learning in drug discovery, materials science, and quantum chemistry.
democratizes the use of deep-learning in drug discovery, materials science, quantum chemistry, and biology.

### Table of contents:

+10 −6
Original line number Diff line number Diff line
@@ -438,8 +438,8 @@ class TensorflowGraphModel(Model):
    feeding and fetching the same tensor.
    """
    weights = []
    placeholder_scope = TensorflowGraph.get_placeholder_scope(graph,
                                                              name_scopes)
    placeholder_scope = TensorflowGraph.get_placeholder_scope(
        graph, name_scopes)
    with placeholder_scope:
      for task in range(self.n_tasks):
        weights.append(
@@ -482,11 +482,15 @@ class TensorflowGraphModel(Model):
    if train:
      if not self.train_graph.session:
        config = tf.ConfigProto(allow_soft_placement=True)
        #gpu memory growth option
        config.gpu_options.allow_growth = True
        self.train_graph.session = tf.Session(config=config)
      return self.train_graph.session
    else:
      if not self.eval_graph.session:
        config = tf.ConfigProto(allow_soft_placement=True)
        #gpu memory growth option
        config.gpu_options.allow_growth = True
        self.eval_graph.session = tf.Session(config=config)
      return self.eval_graph.session

@@ -639,8 +643,8 @@ class TensorflowClassifier(TensorflowGraphModel):
    Placeholders are wrapped in identity ops to avoid the error caused by
    feeding and fetching the same tensor.
    """
    placeholder_scope = TensorflowGraph.get_placeholder_scope(graph,
                                                              name_scopes)
    placeholder_scope = TensorflowGraph.get_placeholder_scope(
        graph, name_scopes)
    with graph.as_default():
      batch_size = self.batch_size
      n_classes = self.n_classes
@@ -792,8 +796,8 @@ class TensorflowRegressor(TensorflowGraphModel):
    Placeholders are wrapped in identity ops to avoid the error caused by
    feeding and fetching the same tensor.
    """
    placeholder_scope = TensorflowGraph.get_placeholder_scope(graph,
                                                              name_scopes)
    placeholder_scope = TensorflowGraph.get_placeholder_scope(
        graph, name_scopes)
    with graph.as_default():
      batch_size = self.batch_size
      labels = []
+68 −30
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ import time
import numpy as np
import tensorflow as tf
import threading
import collections

import deepchem as dc
from deepchem.nn import model_ops
@@ -28,11 +29,12 @@ class TensorGraphMultiTaskClassifier(TensorGraph):
               n_tasks,
               n_features,
               layer_sizes=[1000],
               weight_init_stddevs=[0.02],
               bias_init_consts=[1.0],
               weight_init_stddevs=0.02,
               bias_init_consts=1.0,
               weight_decay_penalty=0.0,
               weight_decay_penalty_type="l2",
               dropouts=[0.5],
               dropouts=0.5,
               activation_fns=tf.nn.relu,
               n_classes=2,
               **kwargs):
    """Create a TensorGraphMultiTaskClassifier.
@@ -48,17 +50,24 @@ class TensorGraphMultiTaskClassifier(TensorGraph):
      number of features
    layer_sizes: list
      the size of each dense layer in the network.  The length of this list determines the number of layers.
    weight_init_stddevs: list
    weight_init_stddevs: list or float
      the standard deviation of the distribution to use for weight initialization of each layer.  The length
      of this list should equal len(layer_sizes).
    bias_init_consts: list
      of this list should equal len(layer_sizes).  Alternatively this may be a single value instead of a list,
      in which case the same value is used for every layer.
    bias_init_consts: list or loat
      the value to initialize the biases in each layer to.  The length of this list should equal len(layer_sizes).
      Alternatively this may be a single value instead of a list, in which case the same value is used for every layer.
    weight_decay_penalty: float
      the magnitude of the weight decay penalty to use
    weight_decay_penalty_type: str
      the type of penalty to use for weight decay, either 'l1' or 'l2'
    dropouts: list
    dropouts: list or float
      the dropout probablity to use for each layer.  The length of this list should equal len(layer_sizes).
      Alternatively this may be a single value instead of a list, in which case the same value is used for every layer.
    activation_fns: list or object
      the Tensorflow activation function to apply to each layer.  The length of this list should equal
      len(layer_sizes).  Alternatively this may be a single value instead of a list, in which case the
      same value is used for every layer.
    n_classes: int
      the number of classes
    """
@@ -67,6 +76,15 @@ class TensorGraphMultiTaskClassifier(TensorGraph):
    self.n_tasks = n_tasks
    self.n_features = n_features
    self.n_classes = n_classes
    n_layers = len(layer_sizes)
    if not isinstance(weight_init_stddevs, collections.Sequence):
      weight_init_stddevs = [weight_init_stddevs] * n_layers
    if not isinstance(bias_init_consts, collections.Sequence):
      bias_init_consts = [bias_init_consts] * n_layers
    if not isinstance(dropouts, collections.Sequence):
      dropouts = [dropouts] * n_layers
    if not isinstance(activation_fns, collections.Sequence):
      activation_fns = [activation_fns] * n_layers

    # Add the input features.

@@ -75,12 +93,13 @@ class TensorGraphMultiTaskClassifier(TensorGraph):

    # Add the dense layers

    for size, weight_stddev, bias_const, dropout in zip(
        layer_sizes, weight_init_stddevs, bias_init_consts, dropouts):
    for size, weight_stddev, bias_const, dropout, activation_fn in zip(
        layer_sizes, weight_init_stddevs, bias_init_consts, dropouts,
        activation_fns):
      layer = Dense(
          in_layers=[prev_layer],
          out_channels=size,
          activation_fn=tf.nn.relu,
          activation_fn=activation_fn,
          weights_initializer=TFWrapper(
              tf.truncated_normal_initializer, stddev=weight_stddev),
          biases_initializer=TFWrapper(
@@ -120,8 +139,9 @@ class TensorGraphMultiTaskClassifier(TensorGraph):
          pad_batches=pad_batches):
        feed_dict = dict()
        if y_b is not None and not predict:
          feed_dict[self.labels[0]] = to_one_hot(
              y_b.flatten(), self.n_classes).reshape(-1, self.n_tasks,
          feed_dict[self.labels[0]] = to_one_hot(y_b.flatten(),
                                                 self.n_classes).reshape(
                                                     -1, self.n_tasks,
                                                     self.n_classes)
        if X_b is not None:
          feed_dict[self.features[0]] = X_b
@@ -136,11 +156,12 @@ class TensorGraphMultiTaskRegressor(TensorGraph):
               n_tasks,
               n_features,
               layer_sizes=[1000],
               weight_init_stddevs=[0.02, 0.02],
               bias_init_consts=[1.0, 1.0],
               weight_init_stddevs=0.02,
               bias_init_consts=1.0,
               weight_decay_penalty=0.0,
               weight_decay_penalty_type="l2",
               dropouts=[0.5],
               dropouts=0.5,
               activation_fns=tf.nn.relu,
               **kwargs):
    """Create a TensorGraphMultiTaskRegressor.

@@ -155,23 +176,39 @@ class TensorGraphMultiTaskRegressor(TensorGraph):
      number of features
    layer_sizes: list
      the size of each dense layer in the network.  The length of this list determines the number of layers.
    weight_init_stddevs: list
    weight_init_stddevs: list or float
      the standard deviation of the distribution to use for weight initialization of each layer.  The length
      of this list should equal len(layer_sizes)+1.  The final element corresponds to the output layer.
    bias_init_consts: list
      Alternatively this may be a single value instead of a list, in which case the same value is used for every layer.
    bias_init_consts: list or float
      the value to initialize the biases in each layer to.  The length of this list should equal len(layer_sizes)+1.
      The final element corresponds to the output layer.
      The final element corresponds to the output layer.  Alternatively this may be a single value instead of a list,
      in which case the same value is used for every layer.
    weight_decay_penalty: float
      the magnitude of the weight decay penalty to use
    weight_decay_penalty_type: str
      the type of penalty to use for weight decay, either 'l1' or 'l2'
    dropouts: list
    dropouts: list or float
      the dropout probablity to use for each layer.  The length of this list should equal len(layer_sizes).
      Alternatively this may be a single value instead of a list, in which case the same value is used for every layer.
    activation_fns: list or object
      the Tensorflow activation function to apply to each layer.  The length of this list should equal
      len(layer_sizes).  Alternatively this may be a single value instead of a list, in which case the
      same value is used for every layer.
    """
    super(TensorGraphMultiTaskRegressor, self).__init__(
        mode='regression', **kwargs)
    self.n_tasks = n_tasks
    self.n_features = n_features
    n_layers = len(layer_sizes)
    if not isinstance(weight_init_stddevs, collections.Sequence):
      weight_init_stddevs = [weight_init_stddevs] * (n_layers + 1)
    if not isinstance(bias_init_consts, collections.Sequence):
      bias_init_consts = [bias_init_consts] * (n_layers + 1)
    if not isinstance(dropouts, collections.Sequence):
      dropouts = [dropouts] * n_layers
    if not isinstance(activation_fns, collections.Sequence):
      activation_fns = [activation_fns] * n_layers

    # Add the input features.

@@ -180,12 +217,13 @@ class TensorGraphMultiTaskRegressor(TensorGraph):

    # Add the dense layers

    for size, weight_stddev, bias_const, dropout in zip(
        layer_sizes, weight_init_stddevs, bias_init_consts, dropouts):
    for size, weight_stddev, bias_const, dropout, activation_fn in zip(
        layer_sizes, weight_init_stddevs, bias_init_consts, dropouts,
        activation_fns):
      layer = Dense(
          in_layers=[prev_layer],
          out_channels=size,
          activation_fn=tf.nn.relu,
          activation_fn=activation_fn,
          weights_initializer=TFWrapper(
              tf.truncated_normal_initializer, stddev=weight_stddev),
          biases_initializer=TFWrapper(
@@ -350,8 +388,8 @@ class TensorflowMultiTaskClassifier(TensorflowClassifier):
      mol_features: Molecule descriptor (e.g. fingerprint) tensor with shape
        batch_size x n_features.
    """
    placeholder_scope = TensorflowGraph.get_placeholder_scope(graph,
                                                              name_scopes)
    placeholder_scope = TensorflowGraph.get_placeholder_scope(
        graph, name_scopes)
    n_features = self.n_features
    with graph.as_default():
      with placeholder_scope:
@@ -373,8 +411,8 @@ class TensorflowMultiTaskClassifier(TensorflowClassifier):
      assert n_layers > 0, 'Must have some layers defined.'

      label_placeholders = self.add_label_placeholders(graph, name_scopes)
      weight_placeholders = self.add_example_weight_placeholders(graph,
                                                                 name_scopes)
      weight_placeholders = self.add_example_weight_placeholders(
          graph, name_scopes)
      if training:
        graph.queue = tf.FIFOQueue(
            capacity=5,
@@ -448,8 +486,8 @@ class TensorflowMultiTaskRegressor(TensorflowRegressor):
        batch_size x n_features.
    """
    n_features = self.n_features
    placeholder_scope = TensorflowGraph.get_placeholder_scope(graph,
                                                              name_scopes)
    placeholder_scope = TensorflowGraph.get_placeholder_scope(
        graph, name_scopes)
    with graph.as_default():
      with placeholder_scope:
        mol_features = tf.placeholder(
@@ -470,8 +508,8 @@ class TensorflowMultiTaskRegressor(TensorflowRegressor):
      assert n_layers > 0, 'Must have some layers defined.'

      label_placeholders = self.add_label_placeholders(graph, name_scopes)
      weight_placeholders = self.add_example_weight_placeholders(graph,
                                                                 name_scopes)
      weight_placeholders = self.add_example_weight_placeholders(
          graph, name_scopes)
      if training:
        graph.queue = tf.FIFOQueue(
            capacity=5,
+130 −0
Original line number Diff line number Diff line
%% Cell type:markdown id: tags:

In this IPython notebook, we will cover more advanced aspects of the `TensorGraph` framework. In particular, we will demonstrate how to share weights between layers and show how to use `DataBag` to reduce the amount of overhead needed to train complex `TensorGraph` models.

Let's start by defining a `TensorGraph` object.

%% Cell type:code id: tags:

``` python
import deepchem as dc
from deepchem.models.tensorgraph.tensor_graph import TensorGraph

tg = TensorGraph(use_queue=False)
```

%% Output

    Warning: No xgboost installed on your system
    Attempting to run xgboost will throw runtime errors
    Warning: No pyGPGO.covfunc installed on your system
    Attempting to run pyGPGO.covfunc will throw runtime errors
    Warning: No pyGPGO.acquisition installed on your system
    Attempting to run pyGPGO.acquisition will throw runtime errors
    Warning: No pyGPGO.surrogates.GaussianProcess installed on your system
    Attempting to run pyGPGO.surrogates.GaussianProcess will throw runtime errors
    Warning: No pyGPGO.GPGO installed on your system
    Attempting to run pyGPGO.GPGO will throw runtime errors

%% Cell type:markdown id: tags:

We're going to construct an architecture that has two identical feature inputs. Let's call these feature inputs `left_features` and `right_features`.

%% Cell type:code id: tags:

``` python
from deepchem.models.tensorgraph.layers import Feature

left_features = Feature(shape=(None, 75))
right_features = Feature(shape=(None, 75))
```

%% Cell type:markdown id: tags:

Let's now apply a nonlinear transformation to both `left_features` and `right_features`. We can use the `Dense` layer to do so. In addition, let's make sure that we apply the same nonlinear transformation to both `left_features` and `right_features`. To this, we can use the `Layer.shared()`. We use this method by initializing a first `Dense` layer, and then calling the `Layer.shared()` method to make a copy of that layer.

%% Cell type:code id: tags:

``` python
from deepchem.models.tensorgraph.layers import Dense


dense_left = Dense(out_channels=1, in_layers=[left_features])
dense_right = dense_left.shared(in_layers=[right_features])
```

%% Cell type:markdown id: tags:

Let's now combine these two transformed feature layers by addition. We will assume this network is being used to solve a regression problem, so we will introduce a `Label` that stores the true regression values. We can then define the objective function of the network via the `L2Loss` between the added output and the true label.

%% Cell type:code id: tags:

``` python
from deepchem.models.tensorgraph.layers import Add
from deepchem.models.tensorgraph.layers import Label
from deepchem.models.tensorgraph.layers import L2Loss
from deepchem.models.tensorgraph.layers import ReduceMean

output = Add(in_layers=[dense_left, dense_right])
tg.add_output(output)

labels = Label(shape=(None, 1))
batch_loss = L2Loss(in_layers=[labels, output])
# Need to reduce over the loss
loss = ReduceMean(in_layers=batch_loss)
tg.set_loss(loss)
```

%% Cell type:markdown id: tags:

Let's now randomly sample an artificial dataset we can use to train this architecture. We will need to sample the `left_features`, `right_features`, and `labels` in order to be able to train the network.

%% Cell type:code id: tags:

``` python
import numpy as np
import numpy.random

n_samples = 100
sampled_left_features = np.random.rand(100, 75)
sampled_right_features = np.random.rand(100, 75)
sampled_labels = np.random.rand(75, 1)
```

%% Cell type:markdown id: tags:

How can we train `TensorGraph` networks with multiple `Feature` inputs? One option is to manually construct a python generator that provides inputs. The tutorial notebook on graph convolutions does this explicitly. For simpler cases, we can use the convenience object `DataBag` which makes it easier to construct generators. A `DataBag` holds multiple datasets (added via `DataBag.add_dataset`). The method `DataBag.iterbatches()` will construct a generator that peels off batches of the desired size from each dataset and return a dictionary mapping inputs (`Feature`, `Label`, and `Weight` objects) to data for that minibatch. Let's see `DataBag` in action.

Note that we will need to wrap our sampled Numpy arrays with `NumpyDataset` objects for our call to work.

%% Cell type:code id: tags:

``` python
from deepchem.data.datasets import Databag
from deepchem.data.datasets import NumpyDataset

databag = Databag()
databag.add_dataset(left_features, NumpyDataset(sampled_left_features))
databag.add_dataset(right_features, NumpyDataset(sampled_right_features))
databag.add_dataset(labels, NumpyDataset(sampled_labels))
```

%% Cell type:markdown id: tags:

Let's now train this architecture! We need to use the method `TensorGraph.fit_generator()` passing in a generator created by `databag.iterbatches()`.

%% Cell type:code id: tags:

``` python
tg.fit_generator(
    databag.iterbatches(epochs=100, batch_size=50, pad_batches=True))
```

%% Output

    Ending global_step 200: Average loss 0.472205
    TIMING: model fitting took 0.273 s

%% Cell type:markdown id: tags:

You should now be able to construct more sophisticated `TensorGraph` architectures with relative ease!
+5 −0
Original line number Diff line number Diff line
@@ -73,3 +73,8 @@ def test_pong():
def test_graph_conv():
  nb, errors = _notebook_read("graph_convolutional_networks_for_tox21.ipynb")
  assert errors == []


def test_tg_mechanics():
  nb, errors = _notebook_read("TensorGraph_Mechanics.ipynb")
  assert errors == []