Commit 67bbb06e authored by peastman's avatar peastman
Browse files

Created Gather layer

parent a574e3f2
Loading
Loading
Loading
Loading
+53 −0
Original line number Diff line number Diff line
@@ -517,6 +517,59 @@ class Repeat(Layer):
    return out_tensor


class Gather(Layer):
  """Gather slices from the input."""

  def __init__(self, in_layers=None, indices=None, axis=0, **kwargs):
    """Create a Gather layer.

    The slice indices may be specified in two ways.  If the indices are constants,
    you can pass them to this constructor as a list or array.  Alternatively, the
    indices can be calculated by another layer.  In that case, pass None for indices,
    and instead provide them as the second input layer.

    Parameters
    ----------
    in_layers: list
      the input layers.  If indices is not None, this should be of length 1.  If indices
      is None, this should be of length 2, with the first entry calculating the tensor
      from which to take slices, and the second entry calculating the slice indices.
    indices: array
      the slice indices (if they are constants) or None (if the indices are provided by
      an input)
    axis: int
      the axis along which to select slices.  The indices refer to positions along this axis.
    """
    self.indices = indices
    self.axis = axis
    super(Gather, self).__init__(in_layers, **kwargs)
    try:
      s = list(self.in_layers[0].shape)
      if indices is None:
        s[axis] = None
      else:
        s[axis] = len(indices)
      self._shape = tuple(s)
    except:
      pass

  def create_tensor(self, in_layers=None, set_tensors=True, **kwargs):
    inputs = self._get_input_tensors(in_layers)
    if self.indices is None:
      if len(inputs) != 2:
        raise ValueError("Must have two parents")
      indices = inputs[1]
    if self.indices is not None:
      if len(inputs) != 1:
        raise ValueError("Must have one parent")
      indices = self.indices
    parent_tensor = inputs[0]
    out_tensor = tf.gather(parent_tensor, indices, axis=self.axis)
    if set_tensors:
      self.out_tensor = out_tensor
    return out_tensor


class GRU(Layer):
  """A Gated Recurrent Unit.

+10 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ from deepchem.models.tensorgraph.layers import Reshape
from deepchem.models.tensorgraph.layers import Transpose
from deepchem.models.tensorgraph.layers import CombineMeanStd
from deepchem.models.tensorgraph.layers import Repeat
from deepchem.models.tensorgraph.layers import Gather
from deepchem.models.tensorgraph.layers import GRU
from deepchem.models.tensorgraph.layers import TimeSeriesDense
from deepchem.models.tensorgraph.layers import Input
@@ -147,6 +148,15 @@ class TestLayers(test_util.TensorFlowTestCase):
      out_tensor = out_tensor.eval()
      assert out_tensor.shape == (batch_size, n_repeat, in_dim)

  def test_gather(self):
    """Test that Gather can be invoked."""
    in_tensor = np.random.uniform(size=(5, 4)).astype(np.float32)
    with self.test_session() as sess:
      out_tensor = Gather(indices=[2, 3], axis=0)(in_tensor).eval()
      assert np.array_equal(in_tensor[[2, 3]], out_tensor)
      out_tensor = Gather(axis=1)(in_tensor, np.array([1, 3])).eval()
      assert np.array_equal(in_tensor[:, [1, 3]], out_tensor)

  def test_gru(self):
    """Test that GRU can be invoked."""
    batch_size = 10
+11 −1
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@ import numpy as np
import tensorflow as tf
from deepchem.models import TensorGraph
from deepchem.models.tensorgraph.layers import Feature, Conv1D, Dense, Flatten, Reshape, Squeeze, Transpose, \
    CombineMeanStd, Repeat, GRU, L2Loss, Concat, SoftMax, Constant, Variable, Add, Multiply, InteratomicL2Distances, \
    CombineMeanStd, Repeat, Gather, GRU, L2Loss, Concat, SoftMax, Constant, Variable, Add, Multiply, InteratomicL2Distances, \
    SoftMaxCrossEntropy, ReduceMean, ToFloat, ReduceSquareDifference, Conv2D, MaxPool, ReduceSum, GraphConv, GraphPool, \
    GraphGather, BatchNorm, WeightedError, \
    LSTMStep, AttnLSTMEmbedding, IterRefLSTMEmbedding
@@ -91,6 +91,16 @@ def test_Repeat_pickle():
  tg.save()


def test_Gather_pickle():
  tg = TensorGraph()
  feature = Feature(shape=(tg.batch_size, 1))
  layer = Gather(indices=[0, 2, 3], in_layers=feature)
  tg.add_output(layer)
  tg.set_loss(layer)
  tg.build()
  tg.save()


def test_GRU_pickle():
  tg = TensorGraph()
  feature = Feature(shape=(tg.batch_size, 10, 10))