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

Bugfixes

parent c9fa67cd
Loading
Loading
Loading
Loading
+11 −73
Original line number Diff line number Diff line
@@ -238,8 +238,6 @@ class Layer(object):
          - Add layer to tensor history
      If layer is not built:
          - Build from x._keras_shape
  get_weights()
  set_weights(weights)
  count_params()
  get_output_shape_for(input_shape)
  get_input_at(node_index)
@@ -732,46 +730,6 @@ class Layer(object):
  def weights(self):
    return self.trainable_weights + self.non_trainable_weights

  def set_weights(self, weights):
    """Sets the weights of the layer, from Numpy arrays.

    # Arguments
      weights: a list of Numpy arrays. The number
        of arrays and their shape must match
        number of the dimensions of the weights
        of the layer (i.e. it should match the
        output of `get_weights`).
    """
    params = self.weights
    if len(params) != len(weights):
      raise ValueError('You called `set_weights(weights)` on layer "' +
                       self.name +
                       '" with a  weight list of length ' +
                       str(len(weights)) +
                       ', but the layer was expecting ' +
                       str(len(params)) +
                       ' weights. Provided weights: ' +
                       str(weights)[:50] + '...')
    if not params:
        return
    weight_value_tuples = []
    param_values = model_ops.batch_get_value(params)
    for pv, p, w in zip(param_values, params, weights):
      if pv.shape != w.shape:
        raise ValueError('Layer weight shape ' +
                         str(pv.shape) +
                         ' not compatible with '
                         'provided weight shape ' + str(w.shape))
      weight_value_tuples.append((p, w))
    model_ops.batch_set_value(weight_value_tuples)

  def get_weights(self):
    """Returns the current weights of the layer,
    as a list of numpy arrays.
    """
    params = self.weights
    return model_ops.batch_get_value(params)

class InputLayer(Layer):
    """Layer to be used as an entry point into a graph.
    It can either wrap an existing tensor (pass an `input_tensor` argument)
@@ -935,23 +893,16 @@ class Dense(Layer):
      model.add(Dense(32))
  ```

  # Arguments
  Parameters
  ----------
  output_dim: int > 0.
  init: name of initialization function for the weights of the layer
      (see [initializations](../initializations.md)),.
      This parameter is only relevant
      if you don't pass a `weights` argument.
  activation: name of activation function to use
    (see [activations](../activations.md)).
    If you don't specify anything, no activation is applied
    (ie. "linear" activation: a(x) = x).
    weights: list of Numpy arrays to set as initial weights.
      The list should have 2 elements, of shape `(input_dim, output_dim)`
      and (output_dim,) for weights and biases respectively.
    W_regularizer: instance of [WeightRegularizer](../regularizers.md)
      (eg. L1 or L2 regularization), applied to the main weights matrix.
    b_regularizer: instance of [WeightRegularizer](../regularizers.md),
      applied to the bias.
  W_regularizer: (eg. L1 or L2 regularization), applied to the main weights matrix.
  b_regularizer: instance of regularize applied to the bias.
  activity_regularizer: instance of [ActivityRegularizer](../regularizers.md),
    applied to the network output.
  W_constraint: instance of the [constraints](../constraints.md) module
@@ -965,18 +916,18 @@ class Dense(Layer):
    is required when using this layer as the first layer in a model.

  # Input shape
    nD tensor with shape: `(nb_samples, ..., input_dim)`.
    nD tensor with shape: (nb_samples, ..., input_dim).
    The most common situation would be
    a 2D input with shape `(nb_samples, input_dim)`.
    a 2D input with shape (nb_samples, input_dim).

  # Output shape
    nD tensor with shape: `(nb_samples, ..., output_dim)`.
    nD tensor with shape: (nb_samples, ..., output_dim).
    For instance, for a 2D input with shape `(nb_samples, input_dim)`,
    the output would have shape `(nb_samples, output_dim)`.
  """

  def __init__(self, output_dim, init='glorot_uniform',
               activation=None, weights=None,
               activation=None,
               W_regularizer=None, b_regularizer=None, activity_regularizer=None,
               W_constraint=None, b_constraint=None,
               bias=True, input_dim=None, **kwargs):
@@ -993,7 +944,6 @@ class Dense(Layer):
    self.b_constraint = constraints.get(b_constraint)

    self.bias = bias
    self.initial_weights = weights
    self.input_spec = [InputSpec(ndim='2+')]

    if self.input_dim:
@@ -1021,9 +971,6 @@ class Dense(Layer):
    else:
      self.b = None

    if self.initial_weights is not None:
      self.set_weights(self.initial_weights)
      del self.initial_weights
    self.built = True

  def call(self, x):
@@ -1089,7 +1036,8 @@ class BatchNormalization(Layer):
  i.e. applies a transformation that maintains the mean activation
  close to 0 and the activation standard deviation close to 1.

  # Arguments
  Parameters
  ----------
  epsilon: small float > 0. Fuzz parameter.
  mode: integer, 0, 1 or 2.
    - 0: feature-wise normalization.
@@ -1109,18 +1057,12 @@ class BatchNormalization(Layer):
  momentum: momentum in the computation of the
    exponential average of the mean and standard deviation
    of the data, for feature-wise normalization.
    weights: Initialization weights.
      List of 2 Numpy arrays, with shapes:
      `[(input_shape,), (input_shape,)]`
      Note that the order of this list is [gamma, beta, mean, std]
  beta_init: name of initialization function for shift parameter
    (see [initializations](../initializations.md)), or alternatively,
    TensorFlow function to use for weights initialization.
      This parameter is only relevant if you don't pass a `weights` argument.
  gamma_init: name of initialization function for scale parameter (see
    [initializations](../initializations.md)), or alternatively,
    TensorFlow function to use for weights initialization.
      This parameter is only relevant if you don't pass a `weights` argument.
  gamma_regularizer: instance of [WeightRegularizer](../regularizers.md)
    (eg. L1 or L2 regularization), applied to the gamma vector.
  beta_regularizer: instance of [WeightRegularizer](../regularizers.md),
@@ -1139,7 +1081,7 @@ class BatchNormalization(Layer):
  """

  def __init__(self, epsilon=1e-3, mode=0, axis=-1, momentum=0.99,
               weights=None, beta_init='zero', gamma_init='one',
               beta_init='zero', gamma_init='one',
               gamma_regularizer=None, beta_regularizer=None, **kwargs):
    self.beta_init = initializations.get(beta_init)
    self.gamma_init = initializations.get(gamma_init)
@@ -1149,7 +1091,6 @@ class BatchNormalization(Layer):
    self.momentum = momentum
    self.gamma_regularizer = regularizers.get(gamma_regularizer)
    self.beta_regularizer = regularizers.get(beta_regularizer)
    self.initial_weights = weights
    if self.mode == 0:
      self.uses_learning_phase = True
    super(BatchNormalization, self).__init__(**kwargs)
@@ -1173,9 +1114,6 @@ class BatchNormalization(Layer):
                                       name='{}_running_std'.format(self.name),
                                       trainable=False)

    if self.initial_weights is not None:
      self.set_weights(self.initial_weights)
      del self.initial_weights
    self.built = True

  def call(self, x):
+3 −0
Original line number Diff line number Diff line
@@ -702,6 +702,9 @@ def cos(x, y):
class LSTMStep(Layer):
  """ LSTM whose call is a single step in the LSTM.

  TODO(rbharath): forget_bias_init uses get_value(), which evaluates provided
  tensors in session. Seems quite unnecessary...

  This layer exists because the Keras LSTM layer is intrinsically linked to an
  RNN with sequence inputs, and here, we will not be using sequence inputs, but
  rather we generate a sequence of inputs using the intermediate outputs of the
+32 −136
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ py_all = all
# This is the default internal TF session used by Keras.
# It can be set manually via `set_session(sess)`.
_SESSION = None
_EPSILON = 10e-8
# This boolean flag can be set to True to leave variable initialization
# up to the user.
# Change its value via `manual_variable_initialization(value)`.
@@ -204,32 +203,6 @@ def cast_to_floatx(x):
  """
  return np.asarray(x, dtype=tf.float32)

def to_dense(tensor):
  """Converts a sparse tensor into a dense tensor
  and returns it.

  # Arguments
      tensor: A tensor instance (potentially sparse).

  # Returns
      A dense tensor.

  # Examples
  ```python
      >>> from keras import backend as K
      >>> b = K.placeholder((2, 2), sparse=True)
      >>> print(K.is_sparse(b))
      True
      >>> c = K.to_dense(b)
      >>> print(K.is_sparse(c))
      False
  ```
  """
  if is_sparse(tensor):
    return tf.sparse_tensor_to_dense(tensor)
  else:
    return tensor

def moving_average_update(variable, value, momentum):
  try:
    return moving_averages.assign_moving_average(
@@ -238,49 +211,17 @@ def moving_average_update(variable, value, momentum):
    return moving_averages.assign_moving_average(
        variable, value, momentum)

def is_sparse(tensor):
  """Returns whether a tensor is a sparse tensor.

  # Arguments
      tensor: A tensor instance.

  # Returns
      A boolean.

  # Example
  ```python
      >>> from keras import backend as K
      >>> a = K.placeholder((2, 2), sparse=False)
      >>> print(K.is_sparse(a))
      False
      >>> b = K.placeholder((2, 2), sparse=True)
      >>> print(K.is_sparse(b))
      True
  ```
  """
  return isinstance(tensor, tf.SparseTensor)

def int_shape(x):
  """Returns the shape of a Keras tensor or a Keras variable as a tuple of
  integers or None entries.

  # Arguments
  Arguments
  ---------
  x: Tensor or variable.

  # Returns
  Returns
  -------
  A tuple of integers (or None entries).

  # Examples
  ```python
      >>> from keras import backend as K
      >>> input = K.placeholder(shape=(2, 4, 5))
      >>> K.int_shape(input)
      (2, 4, 5)
      >>> val = np.array([[1, 2], [3, 4]])
      >>> kvar = K.variable(value=val)
      >>> K.int_shape(kvar)
      (2, 2)
  ```
  """
  shape = x.get_shape()
  return tuple([i.__int__() for i in shape])
@@ -288,10 +229,12 @@ def int_shape(x):
def get_value(x):
  """Returns the value of a variable.

  # Arguments
  Parameters
  ----------
  x: input variable.

  # Returns
  Returns
  -------
  A Numpy array.
  """
  return x.eval(session=get_session())
@@ -299,65 +242,17 @@ def get_value(x):
def get_uid(prefix=''):
  """Provides a unique UID given a string prefix.

  # Arguments
  Parameters
  ----------
  prefix: string.

  # Returns
  Returns
  -------
  An integer.

  # Example
  ```
      >>> keras.backend.get_uid('dense')
      >>> 1
      >>> keras.backend.get_uid('dense')
      >>> 2
  ```

  """
  _UID_PREFIXES[prefix] += 1
  return _UID_PREFIXES[prefix]

def batch_get_value(xs):
  """Returns the value of more than one tensor variable.

  # Arguments
      x: list of variables.

  # Returns
      A list of Numpy arrays.
  """
  if xs:
    return get_session().run(xs)
  else:
    return []

def batch_set_value(tuples):
  """Sets the values of many tensor variables at once.
  It returns `None`.

  # Arguments
      tuples: a list of tuples `(tensor, value)`.
          `value` should be a Numpy array.
  """
  if tuples:
    assign_ops = []
    feed_dict = {}
    for x, value in tuples:
      value = np.asarray(value)
      tf_dtype = _convert_string_dtype(x.dtype.name.split('_')[0])
      if hasattr(x, '_assign_placeholder'):
        assign_placeholder = x._assign_placeholder
        assign_op = x._assign_op
      else:
        assign_placeholder = tf.placeholder(tf_dtype,
                                            shape=value.shape)
        assign_op = x.assign(assign_placeholder)
        x._assign_placeholder = assign_placeholder
        x._assign_op = assign_op
      assign_ops.append(assign_op)
      feed_dict[assign_placeholder] = value
    get_session().run(assign_ops, feed_dict=feed_dict)

def _initialize_variables():
  if hasattr(tf, 'global_variables'):
    variables = tf.global_variables()
@@ -390,7 +285,8 @@ def get_session():
  Note that you can manually set the global session
  via `K.set_session(sess)`.

  # Returns
  Returns
  -------
  A TensorFlow session.
  """
  global _SESSION
@@ -413,7 +309,8 @@ def get_session():
def concatenate(tensors, axis=-1):
  """Concatenates a list of tensors alongside the specified axis.

  # Returns
  Returns
  -------
  A tensor.
  """
  if axis < 0:
@@ -423,9 +320,6 @@ def concatenate(tensors, axis=-1):
    else:
      axis = 0

  if py_all([is_sparse(x) for x in tensors]):
    return tf.sparse_concat(axis, tensors)
  else:
  try:
    return tf.concat_v2([to_dense(x) for x in tensors], axis)
  except AttributeError:
@@ -446,16 +340,18 @@ def _normalize_axis(axis, ndim):
def mean(x, axis=None, keepdims=False):
  """Mean of a tensor, alongside the specified axis.

  # Arguments
  Parameters
  ----------
  x: A tensor or variable.
  axis: A list of integer. Axes to compute the mean.
  keepdims: A boolean, whether to keep the dimensions or not.
          If `keepdims` is `False`, the rank of the tensor is reduced
          by 1 for each entry in `axis`. If `keep_dims` is `True`,
    If keepdims is False, the rank of the tensor is reduced
    by 1 for each entry in axis. If keep_dims is True,
    the reduced dimensions are retained with length 1.

  # Returns
      A tensor with the mean of elements of `x`.
  Returns
  -------
  A tensor with the mean of elements of x.
  """
  axis = _normalize_axis(axis, get_ndim(x))
  if x.dtype.base_dtype == tf.bool:
@@ -469,12 +365,14 @@ def dot(x, y):
  with a ND tensor, it reproduces the Theano behavior.
  (e.g. (2, 3).(4, 3, 5) = (2, 4, 5))

  # Arguments
  Parameters
  ----------
  x: Tensor or variable.
  y: Tensor or variable.

  # Returns
      A tensor, dot product of `x` and `y`.
  Returns
  -------
  A tensor, dot product of x and y.
  """
  if get_ndim(x) is not None and (get_ndim(x) > 2 or get_ndim(y) > 2):
    x_shape = []
@@ -497,9 +395,6 @@ def dot(x, y):
    yt = tf.reshape(tf.transpose(y, perm=y_permute_dim), [y_shape[-2], -1])
    return tf.reshape(tf.matmul(xt, yt),
                      x_shape[:-1] + y_shape[:-2] + y_shape[-1:])
  if is_sparse(x):
    out = tf.sparse_tensor_dense_matmul(x, y)
  else:
  out = tf.matmul(x, y)
  return out

@@ -531,7 +426,8 @@ def get_dtype(x):
def clip(x, min_value, max_value):
  """Element-wise value clipping.

  # Returns
  Returns
  -------
  A tensor.
  """
  if max_value is not None and max_value < min_value:
@@ -547,7 +443,7 @@ def epsilon():
  # Returns
      A float.
  """
  return _EPSILON
  return 1e-7 

def variable(value, dtype=tf.float32, name=None):
  """Instantiates a variable and returns it.
@@ -791,7 +687,7 @@ def var(x, axis=None, keepdims=False):
  # Returns
      A tensor with the variance of elements of `x`.
  """
  axis = _normalize_axis(axis, ndim(x))
  axis = _normalize_axis(axis, get_ndim(x))
  if x.dtype.base_dtype == tf.bool:
    x = tf.cast(x, tf.float32)
  m = tf.reduce_mean(x, reduction_indices=axis, keep_dims=True)