예제 #1
0
 def testInitializerDifferent(self):
   for dtype in [dtypes.float32, dtypes.float64]:
     init1 = init_ops.uniform_unit_scaling_initializer(seed=1, dtype=dtype)
     init2 = init_ops.uniform_unit_scaling_initializer(seed=2, dtype=dtype)
     init3 = init_ops.uniform_unit_scaling_initializer(
         1.5, seed=1, dtype=dtype)
     self.assertFalse(identicaltest(self, init1, init2))
     self.assertFalse(identicaltest(self, init1, init3))
     self.assertFalse(identicaltest(self, init2, init3))
예제 #2
0
 def testInitializerDifferent(self):
   for dtype in [dtypes.float32, dtypes.float64]:
     init1 = init_ops.uniform_unit_scaling_initializer(seed=1, dtype=dtype)
     init2 = init_ops.uniform_unit_scaling_initializer(seed=2, dtype=dtype)
     init3 = init_ops.uniform_unit_scaling_initializer(
         1.5, seed=1, dtype=dtype)
     self.assertFalse(identicaltest(self, init1, init2))
     self.assertFalse(identicaltest(self, init1, init3))
     self.assertFalse(identicaltest(self, init2, init3))
예제 #3
0
 def testInitializerIdentical(self):
   for dtype in [dtypes.float32, dtypes.float64]:
     init1 = init_ops.uniform_unit_scaling_initializer(seed=1, dtype=dtype)
     init2 = init_ops.uniform_unit_scaling_initializer(seed=1, dtype=dtype)
     self.assertTrue(identicaltest(self, init1, init2))
     init3 = init_ops.uniform_unit_scaling_initializer(
         1.5, seed=1, dtype=dtype)
     init4 = init_ops.uniform_unit_scaling_initializer(
         1.5, seed=1, dtype=dtype)
     self.assertTrue(identicaltest(self, init3, init4))
예제 #4
0
 def testInitializerIdentical(self):
   for dtype in [dtypes.float32, dtypes.float64]:
     init1 = init_ops.uniform_unit_scaling_initializer(seed=1, dtype=dtype)
     init2 = init_ops.uniform_unit_scaling_initializer(seed=1, dtype=dtype)
     self.assertTrue(identicaltest(self, init1, init2))
     init3 = init_ops.uniform_unit_scaling_initializer(
         1.5, seed=1, dtype=dtype)
     init4 = init_ops.uniform_unit_scaling_initializer(
         1.5, seed=1, dtype=dtype)
     self.assertTrue(identicaltest(self, init3, init4))
 def testZeroSize(self):
     shape = [0, 2]
     with self.test_session():
         x = variable_scope.get_variable(
             "x",
             shape=shape,
             initializer=init_ops.uniform_unit_scaling_initializer())
         self.assertAllEqual(shape, x.eval().shape)
예제 #6
0
 def testZeroSize(self):
   shape = [0, 2]
   with self.test_session():
     x = variable_scope.get_variable(
         "x",
         shape=shape,
         initializer=init_ops.uniform_unit_scaling_initializer())
     self.assertAllEqual(shape, x.eval().shape)
예제 #7
0
 def testZeroSize(self):
   shape = [0, 2]
   with self.cached_session():
     x = variable_scope.get_variable(
         "x",
         shape=shape,
         initializer=init_ops.uniform_unit_scaling_initializer())
     variables.global_variables_initializer().run()
     self.assertAllEqual(shape, self.evaluate(x).shape)
예제 #8
0
 def testZeroSize(self):
   shape = [0, 2]
   with self.cached_session():
     x = variable_scope.get_variable(
         "x",
         shape=shape,
         initializer=init_ops.uniform_unit_scaling_initializer())
     variables.global_variables_initializer().run()
     self.assertAllEqual(shape, self.evaluate(x).shape)
예제 #9
0
    def get_embedding(self, inputs, id_to_word):
        # embedding layer for input projection
        with tf.variable_scope("Embedding"), tf.device('/cpu:0'):
            if not self.params.pre_emb:
                embedding = tf.get_variable(
                    "word_emb", [self.num_words, self.params.word_dim],
                    initializer=init_ops.uniform_unit_scaling_initializer())
            else:
                print("load word2vec")
                embedding = tf.get_variable(
                    "word_emb",
                    dtype=tf.float32,
                    initializer=np.asarray(load_word2vec(
                        self.params.pre_emb, id_to_word),
                                           dtype=np.float32))

        x = tf.nn.embedding_lookup(embedding, inputs)
        return x
예제 #10
0
  def _get_single_variable(self, name, shape=None, dtype=dtypes.float32,
                           initializer=None, regularizer=None, reuse=None,
                           trainable=True, collections=None,
                           caching_device=None, validate_shape=True):
    """Get or create a single Variable (e.g. a shard or entire variable).

    See the documentation of get_variable above (ignore partitioning components)
    for details.

    Args:
      name: see get_variable.
      shape: see get_variable.
      dtype: see get_variable.
      initializer: see get_variable.
      regularizer: see get_variable.
      reuse: see get_variable.
      trainable: see get_variable.
      collections: see get_variable.
      caching_device: see get_variable.
      validate_shape: see get_variable.

    Returns:
      A Variable.  See documentation of get_variable above.

    Raises:
      ValueError: See documentation of get_variable above.
    """

    # Set to true if initializer is a constant.
    initializing_from_value = False
    if initializer is not None and isinstance(initializer, ops.Tensor):
      initializing_from_value = True
    if shape is not None and initializing_from_value:
      raise ValueError("If initializer is a constant, do not specify shape.")

    should_check = reuse is not None
    dtype = dtypes.as_dtype(dtype)
    shape = tensor_shape.as_shape(shape)

    if name in self._vars:
      # Here we handle the case when returning an existing variable.
      if should_check and not reuse:
        tb = self._vars[name].op.traceback[::-1]
        # Throw away internal tf entries and only take a few lines.
        tb = [x for x in tb if "tensorflow/python" not in x[0]][:3]
        raise ValueError("Variable %s already exists, disallowed."
                         " Did you mean to set reuse=True in VarScope? "
                         "Originally defined at:\n\n%s" % (
                             name, "".join(traceback.format_list(tb))))
      found_var = self._vars[name]
      if not shape.is_compatible_with(found_var.get_shape()):
        raise ValueError("Trying to share variable %s, but specified shape %s"
                         " and found shape %s." % (name, shape,
                                                   found_var.get_shape()))
      if not dtype.is_compatible_with(found_var.dtype):
        dtype_str = dtype.name
        found_type_str = found_var.dtype.name
        raise ValueError("Trying to share variable %s, but specified dtype %s"
                         " and found dtype %s." % (name, dtype_str,
                                                   found_type_str))
      return found_var

    # The code below handles only the case of creating a new variable.
    if should_check and reuse:
      raise ValueError("Variable %s does not exist, disallowed."
                       " Did you mean to set reuse=None in VarScope?" % name)
    if not shape.is_fully_defined() and not initializing_from_value:
      raise ValueError("Shape of a new variable (%s) must be fully defined, "
                       "but instead was %s." % (name, shape))

    # Create the tensor to initialize the variable.
    if initializer is None:
      initializer = init_ops.uniform_unit_scaling_initializer()
    # Clear control dependencies while creating the initializer.
    with ops.control_dependencies(None):
      if initializing_from_value:
        init_val = initializer
        variable_dtype = None
      else:
        init_val = lambda: initializer(shape.as_list(), dtype=dtype)
        variable_dtype = dtype.base_dtype

    # Create the variable.
    v = variables.Variable(initial_value=init_val,
                           name=name,
                           trainable=trainable,
                           collections=collections,
                           caching_device=caching_device,
                           dtype=variable_dtype,
                           validate_shape=validate_shape)
    self._vars[name] = v
    logging.info("Created variable %s with shape %s and init %s", v.name,
                 format(shape), initializer)

    # Run the regularizer if requested and save the resulting loss.
    if regularizer:
      with ops.name_scope(name + "/Regularizer/"):
        loss = regularizer(v)
      if loss is not None:
        logging.info("Applied regularizer to %s and added the result %s to "
                     "REGULARIZATION_LOSSES.", v.name, loss.name)
        ops.add_to_collection(ops.GraphKeys.REGULARIZATION_LOSSES, loss)

    return v
예제 #11
0
  def _get_partitioned_variable_list(
      self, name, partitioner, shape=None, dtype=dtypes.float32,
      initializer=None, regularizer=None, reuse=None,
      trainable=True, collections=None, caching_device=None,
      validate_shape=True):
    """Gets or creates a sharded variable list with these parameters.

    The `partitioner` must be a callable that accepts a fully defined
    `TensorShape` and returns a sequence of integers (the `partitions`).
    These integers describe how to partition the given sharded `Variable`
    along the given dimension.  That is, `partitions[1] = 3` means split
    the `Variable` into 3 shards along dimension 1.  Currently, sharding along
    only one axis is supported.

    If the list of variables with the given name (prefix) is already stored,
    we return the stored variables. Otherwise, we create a new one.

    Set `reuse` to `True` when you only want to reuse existing Variables.
    Set `reuse` to `False` when you only want to create new Variables.
    If `reuse` is `None` (the default), both new and existing variables are
    returned.

    If initializer is `None` (the default), the default initializer passed in
    the constructor is used. If that one is `None` too, we use a new
    `UniformUnitScalingInitializer`. If initializer is a Tensor, we use
    it as a value and derive the shape from the initializer.

    If the initializer is a callable, then it will be called for each
    shard.  Otherwise the initializer should match the shape of the entire
    sharded Variable, and it will be sliced accordingly for each shard.

    Some useful partitioners are available.  See, e.g.,
    `variable_axis_size_partitioner`.

    Args:
      name: the name of the new or existing sharded variable.
      partitioner: Optional callable that accepts a fully defined `TensorShape`
        and `dtype` of the Variable to be created, and returns a list of
        partitions for each axis (currently only one axis can be partitioned).
      shape: shape of the new or existing sharded variable.
      dtype: type of the new or existing sharded variable
        (defaults to `DT_FLOAT`).
      initializer: initializer for the sharded variable.
      regularizer: a (Tensor -> Tensor or None) function; the result of
        applying it on a newly created variable will be added to the collection
        GraphKeys.REGULARIZATION_LOSSES and can be used for regularization.
      reuse: a Boolean or `None`. Controls reuse or creation of variables.
      trainable: If `True` also add the variable to the graph collection
        `GraphKeys.TRAINABLE_VARIABLES` (see tf.Variable).
      collections: List of graph collections keys to add the Variable to.
        Defaults to `[GraphKeys.VARIABLES]` (see tf.Variable).
      caching_device: Optional device string or function describing where the
        Variable should be cached for reading.  Defaults to the Variable's
        device.  If not `None`, caches on another device.  Typical use is to
        cache on the device where the Ops using the Variable reside, to
        deduplicate copying through `Switch` and other conditional statements.
      validate_shape: If False, allows the variable to be initialized with a
        value of unknown shape. If True, the default, the shape of initial_value
        must be known.

    Returns:
      A tuple `(shards, partitions)` where `shards` is the list of `Variable`
      shards and `partitions` is the output of the partitioner on the input
      shape.

    Raises:
      ValueError: when creating a new variable and shape is not declared,
        when reusing a variable and specifying a conflicting shape,
        when violating reuse during variable creation, or if an existing
        sharded variable exists for the given name but with different sharding.
    """

    initializing_from_value = False
    if initializer is not None and isinstance(initializer, ops.Tensor):
      initializing_from_value = True

    shape = tensor_shape.as_shape(shape)

    if name in self._vars:
      raise ValueError(
          "A partitioner was provided, but an unpartitioned version of the "
          "variable was found: %s.  Perhaps a variable of the same name was "
          "already created without partitioning?" % name)

    if initializing_from_value:
      shape = initializer.get_shape()

    if not shape.is_fully_defined():
      raise ValueError("Shape of a new partitioned variable (%s) must be "
                       "fully defined, but instead was %s." % (name, shape))

    if shape.ndims < 1:
      raise ValueError("A partitioned Variable must have rank at least 1, "
                       "shape: %s" % shape)

    partitions = partitioner(shape=shape, dtype=dtype)

    if not isinstance(partitions, collections_lib.Sequence):
      raise ValueError("Partitioner must return a sequence, but saw: %s"
                       % partitions)

    if len(partitions) != shape.ndims:
      raise ValueError(
          "Partitioner returned a partition list that does not match the "
          "Variable's rank: %s vs. %s" % (partitions, shape))

    if any([p < 1 for p in partitions]):
      raise ValueError(
          "Partitioner returned zero partitions for some axes: %s" % partitions)

    slice_dim, slice_shape = _compute_slice_dim_and_shape(
        shape.as_list(), partitions)

    vs = []
    num_slices = partitions[slice_dim]
    num_slices_with_excess = shape[slice_dim].value % num_slices

    slice_offset = [0] * shape.ndims

    if "%s_0" % name in self._vars:
      if "%s_%d" % (name, num_slices - 1) not in self._vars:
        raise ValueError(
            "Partitioner returned a different partitioning than what was "
            "already found.  Partitioner returned %d shards, and shard %s_0 "
            "was found, but %s_%d was not."
            % (num_slices, name, name, num_slices - 1))
      if "%s_%d" % (name, num_slices) in self._vars:
        raise ValueError(
            "Partitioner returned a different partitioning than what was "
            "already found.  Partitioner returned %d shards, and shard %s_0 "
            "was found, but so was the extra shard %s_%d."
            % (num_slices, name, name, num_slices))

    for i in xrange(num_slices):
      var_shape = slice_shape[:]
      var_offset = slice_offset[:]
      if i < num_slices_with_excess:
        var_shape[slice_dim] += 1
      slice_offset[slice_dim] += var_shape[slice_dim]

      with ops.op_scope([], name + "/PartitionedVariableList"):
        if initializer is None:
          init = init_ops.uniform_unit_scaling_initializer(
              full_shape=shape.as_list())
          init_shape = var_shape
        elif callable(initializer):
          init = initializer
          init_shape = var_shape
        elif isinstance(initializer, ops.Tensor):
          init = array_ops.slice(initializer, var_offset, var_shape)
          # Use the dtype of the given tensor.
          dtype = init.dtype.base_dtype
          init_shape = None
        else:
          init = ops.convert_to_tensor(initializer, dtype=dtype)
          init = array_ops.slice(init, var_offset, var_shape)
          init_shape = None

      with ops.name_scope(None):
        var = self._get_single_variable(
            name="%s_%d" % (name, i),
            shape=init_shape,
            dtype=dtype,
            initializer=init,
            regularizer=regularizer,
            reuse=reuse,
            trainable=trainable,
            collections=collections,
            caching_device=caching_device,
            validate_shape=validate_shape)

      # pylint: disable=protected-access
      var._set_save_slice_info(variables.Variable.SaveSliceInfo(
          name, shape.as_list(), var_offset, var_shape))
      # pylint: enable=protected-access
      vs.append(var)

    return (vs, partitions)
예제 #12
0
 def testDuplicatedInitializer(self):
     init = init_ops.uniform_unit_scaling_initializer()
     self.assertFalse(duplicated_initializer(self, init, 1))
예제 #13
0
  def get_variable(self, name, shape=None, dtype=types.float32,
                   initializer=None, reuse=None, trainable=True,
                   collections=None):
    """Gets an existing variable with these parameters or create a new one.

    If a variable with the given name is already stored, we return the stored
    variable. Otherwise, we create a new one.

    Set `reuse` to `True` when you only want to reuse existing Variables.
    Set `reuse` to `False` when you only want to create new Variables.
    If `reuse` is `None` (the default), both new and existing variables are
    returned.

    If initializer is `None` (the default), the default initializer passed in
    the constructor is used. If that one is `None` too, we use a new
    `UniformUnitScalingInitializer`.

    Args:
      name: the name of the new or existing variable.
      shape: shape of the new or existing variable.
      dtype: type of the new or existing variable (defaults to `DT_FLOAT`).
      initializer: initializer for the variable.
      reuse: a Boolean or `None`. Controls reuse or creation of variables.
      trainable: If `True` also add the variable to the graph collection
        `GraphKeys.TRAINABLE_VARIABLES` (see variables.Variable).
      collections: List of graph collections keys to add the Variable to.
        Defaults to `[GraphKeys.VARIABLES]` (see variables.Variable).

    Returns:
      The created or existing variable.

    Raises:
      ValueError: when creating a new variable and shape is not declared,
        when reusing a variable and specifying a conflicting shape,
        or when violating reuse during variable creation.
    """
    should_check = reuse is not None
    dtype = types.as_dtype(dtype)
    shape = tensor_shape.as_shape(shape)
    if name in self._vars:
      # Here we handle the case when returning an existing variable.
      if should_check and not reuse:
        raise ValueError("Over-sharing: Variable %s already exists, disallowed."
                         " Did you mean to set reuse=True in VarScope?" % name)
      found_var = self._vars[name]
      if not shape.is_compatible_with(found_var.get_shape()):
        raise ValueError("Trying to share variable %s, but specified shape %s"
                         " and found shape %s." % (name, str(shape),
                                                   str(found_var.get_shape())))
      if not dtype.is_compatible_with(found_var.dtype):
        dtype_str = dtype.name
        found_type_str = found_var.dtype.name
        raise ValueError("Trying to share variable %s, but specified dtype %s"
                         " and found dtype %s." % (name, str(dtype_str),
                                                   str(found_type_str)))
      return found_var

    # The code below handles only the case of creating a new variable.
    if should_check and reuse:
      raise ValueError("Under-sharing: Variable %s does not exist, disallowed."
                       " Did you mean to set reuse=None in VarScope?" % name)
    if not shape.is_fully_defined():
      raise ValueError("Shape of a new variable (%s) must be fully defined, "
                       "but instead was %s." % (name, shape))
    if initializer is None:
      initializer = init_ops.uniform_unit_scaling_initializer()
    with ops.name_scope(name + "/Initializer/"):
      init_val = initializer(shape.as_list(), dtype=dtype)
    v = variables.Variable(init_val, name=name, trainable=trainable,
                           collections=collections)
    self._vars[name] = v
    logging.info("Created variable %s with shape %s and init %s", v.name,
                 format(shape), str(initializer))
    return v
예제 #14
0
    def get_variable(self,
                     name,
                     shape=None,
                     dtype=dtypes.float32,
                     initializer=None,
                     regularizer=None,
                     reuse=None,
                     trainable=True,
                     collections=None,
                     caching_device=None):
        """Gets an existing variable with these parameters or create a new one.

        If a variable with the given name is already stored, we return the stored
        variable. Otherwise, we create a new one.

        Set `reuse` to `True` when you only want to reuse existing Variables.
        Set `reuse` to `False` when you only want to create new Variables.
        If `reuse` is `None` (the default), both new and existing variables are
        returned.

        If initializer is `None` (the default), the default initializer passed in
        the constructor is used. If that one is `None` too, we use a new
        `UniformUnitScalingInitializer`. If initializer is a Tensor, we use
        it as a value and derive the shape from the initializer.

        Args:
          name: the name of the new or existing variable.
          shape: shape of the new or existing variable.
          dtype: type of the new or existing variable (defaults to `DT_FLOAT`).
          initializer: initializer for the variable.
          regularizer: a (Tensor -> Tensor or None) function; the result of
            applying it on a newly created variable will be added to the collection
            GraphKeys.REGULARIZATION_LOSSES and can be used for regularization.
          reuse: a Boolean or `None`. Controls reuse or creation of variables.
          trainable: If `True` also add the variable to the graph collection
            `GraphKeys.TRAINABLE_VARIABLES` (see tf.Variable).
          collections: List of graph collections keys to add the Variable to.
            Defaults to `[GraphKeys.VARIABLES]` (see tf.Variable).
          caching_device: Optional device string or function describing where the
            Variable should be cached for reading.  Defaults to the Variable's
            device.  If not `None`, caches on another device.  Typical use is to
            cache on the device where the Ops using the Variable reside, to
            deduplicate copying through `Switch` and other conditional statements.

        Returns:
          The created or existing variable.

        Raises:
          ValueError: when creating a new variable and shape is not declared,
            when reusing a variable and specifying a conflicting shape,
            or when violating reuse during variable creation.
        """
        # Set to true if initializer is a constant.
        initializing_from_value = False
        if initializer is not None and isinstance(initializer, ops.Tensor):
            initializing_from_value = True
        if shape is not None and initializing_from_value:
            raise ValueError(
                "If initializer is a constant, do not specify shape.")

        should_check = reuse is not None
        dtype = dtypes.as_dtype(dtype)
        shape = tensor_shape.as_shape(shape)

        if name in self._vars:
            # Here we handle the case when returning an existing variable.
            if should_check and not reuse:
                raise ValueError(
                    "Variable %s already exists, disallowed."
                    " Did you mean to set reuse=True in VarScope?" % name)
            found_var = self._vars[name]
            if not shape.is_compatible_with(found_var.get_shape()):
                raise ValueError(
                    "Trying to share variable %s, but specified shape %s"
                    " and found shape %s." %
                    (name, shape, found_var.get_shape()))
            if not dtype.is_compatible_with(found_var.dtype):
                dtype_str = dtype.name
                found_type_str = found_var.dtype.name
                raise ValueError(
                    "Trying to share variable %s, but specified dtype %s"
                    " and found dtype %s." % (name, dtype_str, found_type_str))
            return found_var

        # The code below handles only the case of creating a new variable.
        if should_check and reuse:
            raise ValueError("Variable %s does not exist, disallowed."
                             " Did you mean to set reuse=None in VarScope?" %
                             name)
        if not shape.is_fully_defined() and not initializing_from_value:
            raise ValueError(
                "Shape of a new variable (%s) must be fully defined, "
                "but instead was %s." % (name, shape))

        # Create the tensor to initialize the variable.
        if initializer is None:
            initializer = init_ops.uniform_unit_scaling_initializer()
        # Clear control dependencies while creating the initializer.
        with ops.control_dependencies(None):
            if initializing_from_value:
                init_val = initializer
            else:
                with ops.name_scope(name + "/Initializer/"):
                    init_val = initializer(shape.as_list(), dtype=dtype)

        # Create the variable.
        v = variables.Variable(init_val,
                               name=name,
                               trainable=trainable,
                               collections=collections,
                               caching_device=caching_device)
        self._vars[name] = v
        logging.info("Created variable %s with shape %s and init %s", v.name,
                     format(shape), initializer)

        # Run the regularizer if requested and save the resulting loss.
        if regularizer:
            with ops.name_scope(name + "/Regularizer/"):
                loss = regularizer(v)
            if loss:
                logging.info(
                    "Applied regularizer to %s and added the result %s to "
                    "REGULARIZATION_LOSSES.", v.name, loss.name)
                ops.add_to_collection(ops.GraphKeys.REGULARIZATION_LOSSES,
                                      loss)

        return v
예제 #15
0
  def _get_partitioned_variable_list(
      self, name, partitioner, shape=None, dtype=dtypes.float32,
      initializer=None, regularizer=None, reuse=None,
      trainable=True, collections=None, caching_device=None,
      validate_shape=True):
    """Gets or creates a sharded variable list with these parameters.

    The `partitioner` must be a callable that accepts a fully defined
    `TensorShape` and returns a sequence of integers (the `partitions`).
    These integers describe how to partition the given sharded `Variable`
    along the given dimension.  That is, `partitions[1] = 3` means split
    the `Variable` into 3 shards along dimension 1.  Currently, sharding along
    only one axis is supported.

    If the list of variables with the given name (prefix) is already stored,
    we return the stored variables. Otherwise, we create a new one.

    Set `reuse` to `True` when you only want to reuse existing Variables.
    Set `reuse` to `False` when you only want to create new Variables.
    If `reuse` is `None` (the default), both new and existing variables are
    returned.

    If initializer is `None` (the default), the default initializer passed in
    the constructor is used. If that one is `None` too, we use a new
    `UniformUnitScalingInitializer`. If initializer is a Tensor, we use
    it as a value and derive the shape from the initializer.

    If the initializer is a callable, then it will be called for each
    shard.  Otherwise the initializer should match the shape of the entire
    sharded Variable, and it will be sliced accordingly for each shard.

    Some useful partitioners are available.  See, e.g.,
    `variable_axis_size_partitioner`.

    Args:
      name: the name of the new or existing sharded variable.
      partitioner: Optional callable that accepts a fully defined `TensorShape`
        and `dtype` of the Variable to be created, and returns a list of
        partitions for each axis (currently only one axis can be partitioned).
      shape: shape of the new or existing sharded variable.
      dtype: type of the new or existing sharded variable
        (defaults to `DT_FLOAT`).
      initializer: initializer for the sharded variable.
      regularizer: a (Tensor -> Tensor or None) function; the result of
        applying it on a newly created variable will be added to the collection
        GraphKeys.REGULARIZATION_LOSSES and can be used for regularization.
      reuse: a Boolean or `None`. Controls reuse or creation of variables.
      trainable: If `True` also add the variable to the graph collection
        `GraphKeys.TRAINABLE_VARIABLES` (see tf.Variable).
      collections: List of graph collections keys to add the Variable to.
        Defaults to `[GraphKeys.VARIABLES]` (see tf.Variable).
      caching_device: Optional device string or function describing where the
        Variable should be cached for reading.  Defaults to the Variable's
        device.  If not `None`, caches on another device.  Typical use is to
        cache on the device where the Ops using the Variable reside, to
        deduplicate copying through `Switch` and other conditional statements.
      validate_shape: If False, allows the variable to be initialized with a
        value of unknown shape. If True, the default, the shape of initial_value
        must be known.

    Returns:
      A tuple `(shards, partitions)` where `shards` is the list of `Variable`
      shards and `partitions` is the output of the partitioner on the input
      shape.

    Raises:
      ValueError: when creating a new variable and shape is not declared,
        when reusing a variable and specifying a conflicting shape,
        when violating reuse during variable creation, or if an existing
        sharded variable exists for the given name but with different sharding.
    """

    initializing_from_value = False
    if initializer is not None and isinstance(initializer, ops.Tensor):
      initializing_from_value = True

    shape = tensor_shape.as_shape(shape)

    if name in self._vars:
      raise ValueError(
          "A partitioner was provided, but an unpartitioned version of the "
          "variable was found: %s.  Perhaps a variable of the same name was "
          "already created without partitioning?" % name)

    if initializing_from_value:
      shape = initializer.get_shape()

    if not shape.is_fully_defined():
      raise ValueError("Shape of a new partitioned variable (%s) must be "
                       "fully defined, but instead was %s." % (name, shape))

    if shape.ndims < 1:
      raise ValueError("A partitioned Variable must have rank at least 1, "
                       "shape: %s" % shape)

    partitions = partitioner(shape=shape, dtype=dtype)

    if not isinstance(partitions, collections_lib.Sequence):
      raise ValueError("Partitioner must return a sequence, but saw: %s"
                       % partitions)

    if len(partitions) != shape.ndims:
      raise ValueError(
          "Partitioner returned a partition list that does not match the "
          "Variable's rank: %s vs. %s" % (partitions, shape))

    if any([p < 1 for p in partitions]):
      raise ValueError(
          "Partitioner returned zero partitions for some axes: %s" % partitions)

    slice_dim, slice_shape = _compute_slice_dim_and_shape(
        shape.as_list(), partitions)

    vs = []
    num_slices = partitions[slice_dim]
    num_slices_with_excess = shape[slice_dim].value % num_slices

    slice_offset = [0] * shape.ndims

    if "%s_0" % name in self._vars:
      if "%s_%d" % (name, num_slices - 1) not in self._vars:
        raise ValueError(
            "Partitioner returned a different partitioning than what was "
            "already found.  Partitioner returned %d shards, and shard %s_0 "
            "was found, but %s_%d was not."
            % (num_slices, name, name, num_slices - 1))
      if "%s_%d" % (name, num_slices) in self._vars:
        raise ValueError(
            "Partitioner returned a different partitioning than what was "
            "already found.  Partitioner returned %d shards, and shard %s_0 "
            "was found, but so was the extra shard %s_%d."
            % (num_slices, name, name, num_slices))

    for i in xrange(num_slices):
      var_shape = slice_shape[:]
      var_offset = slice_offset[:]
      if i < num_slices_with_excess:
        var_shape[slice_dim] += 1
      slice_offset[slice_dim] += var_shape[slice_dim]

      with ops.op_scope([], name + "/PartitionedVariableList"):
        if initializer is None:
          init = init_ops.uniform_unit_scaling_initializer(
              full_shape=shape.as_list())
          init_shape = var_shape
        elif callable(initializer):
          init = initializer
          init_shape = var_shape
        elif isinstance(initializer, ops.Tensor):
          init = array_ops.slice(initializer, var_offset, var_shape)
          # Use the dtype of the given tensor.
          dtype = init.dtype.base_dtype
          init_shape = None
        else:
          init = ops.convert_to_tensor(initializer, dtype=dtype)
          init = array_ops.slice(init, var_offset, var_shape)
          init_shape = None

      with ops.name_scope(None):
        var = self._get_single_variable(
            name="%s_%d" % (name, i),
            shape=init_shape,
            dtype=dtype,
            initializer=init,
            regularizer=regularizer,
            reuse=reuse,
            trainable=trainable,
            collections=collections,
            caching_device=caching_device,
            validate_shape=validate_shape)

      # pylint: disable=protected-access
      var._set_save_slice_info(variables.Variable.SaveSliceInfo(
          name, shape.as_list(), var_offset, var_shape))
      # pylint: enable=protected-access
      vs.append(var)

    return (vs, partitions)
예제 #16
0
  def _get_single_variable(self, name, shape=None, dtype=dtypes.float32,
                           initializer=None, regularizer=None, reuse=None,
                           trainable=True, collections=None,
                           caching_device=None, validate_shape=True):
    """Get or create a single Variable (e.g. a shard or entire variable).

    See the documentation of get_variable above (ignore partitioning components)
    for details.

    Args:
      name: see get_variable.
      shape: see get_variable.
      dtype: see get_variable.
      initializer: see get_variable.
      regularizer: see get_variable.
      reuse: see get_variable.
      trainable: see get_variable.
      collections: see get_variable.
      caching_device: see get_variable.
      validate_shape: see get_variable.

    Returns:
      A Variable.  See documentation of get_variable above.

    Raises:
      ValueError: See documentation of get_variable above.
    """

    # Set to true if initializer is a constant.
    initializing_from_value = False
    if initializer is not None and isinstance(initializer, ops.Tensor):
      initializing_from_value = True
    if shape is not None and initializing_from_value:
      raise ValueError("If initializer is a constant, do not specify shape.")

    should_check = reuse is not None
    dtype = dtypes.as_dtype(dtype)
    shape = tensor_shape.as_shape(shape)

    if name in self._vars:
      # Here we handle the case when returning an existing variable.
      if should_check and not reuse:
        tb = self._vars[name].op.traceback[::-1]
        # Throw away internal tf entries and only take a few lines.
        tb = [x for x in tb if "tensorflow/python" not in x[0]][:3]
        raise ValueError("Variable %s already exists, disallowed."
                         " Did you mean to set reuse=True in VarScope? "
                         "Originally defined at:\n\n%s" % (
                             name, "".join(traceback.format_list(tb))))
      found_var = self._vars[name]
      if not shape.is_compatible_with(found_var.get_shape()):
        raise ValueError("Trying to share variable %s, but specified shape %s"
                         " and found shape %s." % (name, shape,
                                                   found_var.get_shape()))
      if not dtype.is_compatible_with(found_var.dtype):
        dtype_str = dtype.name
        found_type_str = found_var.dtype.name
        raise ValueError("Trying to share variable %s, but specified dtype %s"
                         " and found dtype %s." % (name, dtype_str,
                                                   found_type_str))
      return found_var

    # The code below handles only the case of creating a new variable.
    if should_check and reuse:
      raise ValueError("Variable %s does not exist, disallowed."
                       " Did you mean to set reuse=None in VarScope?" % name)
    if not shape.is_fully_defined() and not initializing_from_value:
      raise ValueError("Shape of a new variable (%s) must be fully defined, "
                       "but instead was %s." % (name, shape))

    # Create the tensor to initialize the variable.
    if initializer is None:
      initializer = init_ops.uniform_unit_scaling_initializer()
    # Clear control dependencies while creating the initializer.
    with ops.control_dependencies(None):
      if initializing_from_value:
        init_val = initializer
        variable_dtype = None
      else:
        init_val = lambda: initializer(shape.as_list(), dtype=dtype)
        variable_dtype = dtype.base_dtype

    # Create the variable.
    v = variables.Variable(initial_value=init_val,
                           name=name,
                           trainable=trainable,
                           collections=collections,
                           caching_device=caching_device,
                           dtype=variable_dtype,
                           validate_shape=validate_shape)
    self._vars[name] = v
    logging.info("Created variable %s with shape %s and init %s", v.name,
                 format(shape), initializer)

    # Run the regularizer if requested and save the resulting loss.
    if regularizer:
      with ops.colocate_with(v.op):
        with ops.name_scope(name + "/Regularizer/"):
          loss = regularizer(v)
        if loss is not None:
          logging.info("Applied regularizer to %s and added the result %s to "
                       "REGULARIZATION_LOSSES.", v.name, loss.name)
          ops.add_to_collection(ops.GraphKeys.REGULARIZATION_LOSSES, loss)

    return v
예제 #17
0
  def get_variable(self, name, shape=None, dtype=dtypes.float32,
                   initializer=None, regularizer=None, reuse=None,
                   trainable=True, collections=None, caching_device=None):
    """Gets an existing variable with these parameters or create a new one.

    If a variable with the given name is already stored, we return the stored
    variable. Otherwise, we create a new one.

    Set `reuse` to `True` when you only want to reuse existing Variables.
    Set `reuse` to `False` when you only want to create new Variables.
    If `reuse` is `None` (the default), both new and existing variables are
    returned.

    If initializer is `None` (the default), the default initializer passed in
    the constructor is used. If that one is `None` too, we use a new
    `UniformUnitScalingInitializer`. If initializer is a Tensor, we use
    it as a value and derive the shape from the initializer.

    Args:
      name: the name of the new or existing variable.
      shape: shape of the new or existing variable.
      dtype: type of the new or existing variable (defaults to `DT_FLOAT`).
      initializer: initializer for the variable.
      regularizer: a (Tensor -> Tensor or None) function; the result of
        applying it on a newly created variable will be added to the collection
        GraphKeys.REGULARIZATION_LOSSES and can be used for regularization.
      reuse: a Boolean or `None`. Controls reuse or creation of variables.
      trainable: If `True` also add the variable to the graph collection
        `GraphKeys.TRAINABLE_VARIABLES` (see tf.Variable).
      collections: List of graph collections keys to add the Variable to.
        Defaults to `[GraphKeys.VARIABLES]` (see tf.Variable).
      caching_device: Optional device string or function describing where the
        Variable should be cached for reading.  Defaults to the Variable's
        device.  If not `None`, caches on another device.  Typical use is to
        cache on the device where the Ops using the Variable reside, to
        deduplicate copying through `Switch` and other conditional statements.

    Returns:
      The created or existing variable.

    Raises:
      ValueError: when creating a new variable and shape is not declared,
        when reusing a variable and specifying a conflicting shape,
        or when violating reuse during variable creation.
    """
    # Set to true if initializer is a constant.
    initializing_from_value = False
    if initializer is not None and isinstance(initializer, ops.Tensor):
      initializing_from_value = True
    if shape is not None and initializing_from_value:
      raise ValueError("If initializer is a constant, do not specify shape.")

    should_check = reuse is not None
    dtype = dtypes.as_dtype(dtype)
    shape = tensor_shape.as_shape(shape)

    if name in self._vars:
      # Here we handle the case when returning an existing variable.
      if should_check and not reuse:
        tb = self._vars[name].op.traceback[::-1]
        # Throw away internal tf entries and only take a few lines.
        tb = [x for x in tb if "tensorflow/python" not in x[0]][:3]
        raise ValueError("Variable %s already exists, disallowed."
                         " Did you mean to set reuse=True in VarScope? "
                         "Originally defined at:\n\n%s" % (
                             name, "".join(traceback.format_list(tb))))
      found_var = self._vars[name]
      if not shape.is_compatible_with(found_var.get_shape()):
        raise ValueError("Trying to share variable %s, but specified shape %s"
                         " and found shape %s." % (name, shape,
                                                   found_var.get_shape()))
      if not dtype.is_compatible_with(found_var.dtype):
        dtype_str = dtype.name
        found_type_str = found_var.dtype.name
        raise ValueError("Trying to share variable %s, but specified dtype %s"
                         " and found dtype %s." % (name, dtype_str,
                                                   found_type_str))
      return found_var

    # The code below handles only the case of creating a new variable.
    if should_check and reuse:
      raise ValueError("Variable %s does not exist, disallowed."
                       " Did you mean to set reuse=None in VarScope?" % name)
    if not shape.is_fully_defined() and not initializing_from_value:
      raise ValueError("Shape of a new variable (%s) must be fully defined, "
                       "but instead was %s." % (name, shape))

    # Create the tensor to initialize the variable.
    if initializer is None:
      initializer = init_ops.uniform_unit_scaling_initializer()
    # Clear control dependencies while creating the initializer.
    with ops.control_dependencies(None):
      if initializing_from_value:
        init_val = initializer
      else:
        with ops.name_scope(name + "/Initializer/"):
          init_val = initializer(shape.as_list(), dtype=dtype)

    # Create the variable.
    v = variables.Variable(init_val, name=name, trainable=trainable,
                           collections=collections,
                           caching_device=caching_device)
    self._vars[name] = v
    logging.info("Created variable %s with shape %s and init %s", v.name,
                 format(shape), initializer)

    # Run the regularizer if requested and save the resulting loss.
    if regularizer:
      with ops.name_scope(name + "/Regularizer/"):
        loss = regularizer(v)
      if loss is not None:
        logging.info("Applied regularizer to %s and added the result %s to "
                     "REGULARIZATION_LOSSES.", v.name, loss.name)
        ops.add_to_collection(ops.GraphKeys.REGULARIZATION_LOSSES, loss)

    return v
예제 #18
0
 def testDuplicatedInitializer(self):
   init = init_ops.uniform_unit_scaling_initializer()
   self.assertFalse(duplicated_initializer(self, init, 1))
예제 #19
0
  def get_variable(self, name, shape=None, dtype=types.float32,
                   initializer=None, reuse=None, trainable=True,
                   collections=None):
    """Gets an existing variable with these parameters or create a new one.

    If a variable with the given name is already stored, we return the stored
    variable. Otherwise, we create a new one.

    Set `reuse` to `True` when you only want to reuse existing Variables.
    Set `reuse` to `False` when you only want to create new Variables.
    If `reuse` is `None` (the default), both new and existing variables are
    returned.

    If initializer is `None` (the default), the default initializer passed in
    the constructor is used. If that one is `None` too, we use a new
    `UniformUnitScalingInitializer`.

    Args:
      name: the name of the new or existing variable.
      shape: shape of the new or existing variable.
      dtype: type of the new or existing variable (defaults to `DT_FLOAT`).
      initializer: initializer for the variable.
      reuse: a Boolean or `None`. Controls reuse or creation of variables.
      trainable: If `True` also add the variable to the graph collection
        `GraphKeys.TRAINABLE_VARIABLES` (see variables.Variable).
      collections: List of graph collections keys to add the Variable to.
        Defaults to `[GraphKeys.VARIABLES]` (see variables.Variable).

    Returns:
      The created or existing variable.

    Raises:
      ValueError: when creating a new variable and shape is not declared,
        when reusing a variable and specifying a conflicting shape,
        or when violating reuse during variable creation.
    """
    should_check = reuse is not None
    dtype = types.as_dtype(dtype)
    shape = tensor_shape.as_shape(shape)
    if name in self._vars:
      # Here we handle the case when returning an existing variable.
      if should_check and not reuse:
        raise ValueError("Over-sharing: Variable %s already exists, disallowed."
                         " Did you mean to set reuse=True in VarScope?" % name)
      found_var = self._vars[name]
      if not shape.is_compatible_with(found_var.get_shape()):
        raise ValueError("Trying to share variable %s, but specified shape %s"
                         " and found shape %s." % (name, shape,
                                                   found_var.get_shape()))
      if not dtype.is_compatible_with(found_var.dtype):
        dtype_str = dtype.name
        found_type_str = found_var.dtype.name
        raise ValueError("Trying to share variable %s, but specified dtype %s"
                         " and found dtype %s." % (name, dtype_str,
                                                   found_type_str))
      return found_var

    # The code below handles only the case of creating a new variable.
    if should_check and reuse:
      raise ValueError("Under-sharing: Variable %s does not exist, disallowed."
                       " Did you mean to set reuse=None in VarScope?" % name)
    if not shape.is_fully_defined():
      raise ValueError("Shape of a new variable (%s) must be fully defined, "
                       "but instead was %s." % (name, shape))
    if initializer is None:
      initializer = init_ops.uniform_unit_scaling_initializer()
    with ops.name_scope(name + "/Initializer/"):
      init_val = initializer(shape.as_list(), dtype=dtype)
    v = variables.Variable(init_val, name=name, trainable=trainable,
                           collections=collections)
    self._vars[name] = v
    logging.info("Created variable %s with shape %s and init %s", v.name,
                 format(shape), initializer)
    return v