1# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14# ==============================================================================
15
16"""Wrappers for candidate sampling operations."""
17
18from __future__ import absolute_import
19from __future__ import division
20from __future__ import print_function
21
22from tensorflow.python.framework import random_seed
23from tensorflow.python.ops import array_ops  # pylint: disable=unused-import
24from tensorflow.python.ops import gen_candidate_sampling_ops
25from tensorflow.python.ops import math_ops  # pylint: disable=unused-import
26from tensorflow.python.util import deprecation
27from tensorflow.python.util import dispatch
28from tensorflow.python.util.tf_export import tf_export
29
30
31@tf_export(
32    'random.uniform_candidate_sampler',
33    v1=['random.uniform_candidate_sampler', 'nn.uniform_candidate_sampler'])
34@dispatch.add_dispatch_support
35@deprecation.deprecated_endpoints('nn.uniform_candidate_sampler')
36def uniform_candidate_sampler(true_classes, num_true, num_sampled, unique,
37                              range_max, seed=None, name=None):
38  """Samples a set of classes using a uniform base distribution.
39
40  This operation randomly samples a tensor of sampled classes
41  (`sampled_candidates`) from the range of integers `[0, range_max)`.
42
43  The elements of `sampled_candidates` are drawn without replacement
44  (if `unique=True`) or with replacement (if `unique=False`) from
45  the base distribution.
46
47  The base distribution for this operation is the uniform distribution
48  over the range of integers `[0, range_max)`.
49
50  In addition, this operation returns tensors `true_expected_count`
51  and `sampled_expected_count` representing the number of times each
52  of the target classes (`true_classes`) and the sampled
53  classes (`sampled_candidates`) is expected to occur in an average
54  tensor of sampled classes.  These values correspond to `Q(y|x)`
55  defined in [this
56  document](http://www.tensorflow.org/extras/candidate_sampling.pdf).
57  If `unique=True`, then these are post-rejection probabilities and we
58  compute them approximately.
59
60  Args:
61    true_classes: A `Tensor` of type `int64` and shape `[batch_size,
62      num_true]`. The target classes.
63    num_true: An `int`.  The number of target classes per training example.
64    num_sampled: An `int`.  The number of classes to randomly sample. The
65      `sampled_candidates` return value will have shape `[num_sampled]`. If
66      `unique=True`, `num_sampled` must be less than or equal to `range_max`.
67    unique: A `bool`. Determines whether all sampled classes in a batch are
68      unique.
69    range_max: An `int`. The number of possible classes.
70    seed: An `int`. An operation-specific seed. Default is 0.
71    name: A name for the operation (optional).
72
73  Returns:
74    sampled_candidates: A tensor of type `int64` and shape `[num_sampled]`.  The
75      sampled classes, either with possible duplicates (`unique=False`) or all
76      unique (`unique=True`). In either case, `sampled_candidates` is
77      independent of the true classes.
78    true_expected_count: A tensor of type `float`.  Same shape as
79      `true_classes`. The expected counts under the sampling distribution
80      of each of `true_classes`.
81    sampled_expected_count: A tensor of type `float`. Same shape as
82      `sampled_candidates`. The expected counts under the sampling distribution
83      of each of `sampled_candidates`.
84  """
85  seed1, seed2 = random_seed.get_seed(seed)
86  return gen_candidate_sampling_ops.uniform_candidate_sampler(
87      true_classes, num_true, num_sampled, unique, range_max, seed=seed1,
88      seed2=seed2, name=name)
89
90
91@tf_export(
92    'random.log_uniform_candidate_sampler',
93    v1=[
94        'random.log_uniform_candidate_sampler',
95        'nn.log_uniform_candidate_sampler'
96    ])
97@dispatch.add_dispatch_support
98@deprecation.deprecated_endpoints('nn.log_uniform_candidate_sampler')
99def log_uniform_candidate_sampler(true_classes, num_true, num_sampled, unique,
100                                  range_max, seed=None, name=None):
101  """Samples a set of classes using a log-uniform (Zipfian) base distribution.
102
103  This operation randomly samples a tensor of sampled classes
104  (`sampled_candidates`) from the range of integers `[0, range_max)`.
105
106  The elements of `sampled_candidates` are drawn without replacement
107  (if `unique=True`) or with replacement (if `unique=False`) from
108  the base distribution.
109
110  The base distribution for this operation is an approximately log-uniform
111  or Zipfian distribution:
112
113  `P(class) = (log(class + 2) - log(class + 1)) / log(range_max + 1)`
114
115  This sampler is useful when the target classes approximately follow such
116  a distribution - for example, if the classes represent words in a lexicon
117  sorted in decreasing order of frequency. If your classes are not ordered by
118  decreasing frequency, do not use this op.
119
120  In addition, this operation returns tensors `true_expected_count`
121  and `sampled_expected_count` representing the number of times each
122  of the target classes (`true_classes`) and the sampled
123  classes (`sampled_candidates`) is expected to occur in an average
124  tensor of sampled classes.  These values correspond to `Q(y|x)`
125  defined in [this
126  document](http://www.tensorflow.org/extras/candidate_sampling.pdf).
127  If `unique=True`, then these are post-rejection probabilities and we
128  compute them approximately.
129
130  Args:
131    true_classes: A `Tensor` of type `int64` and shape `[batch_size,
132      num_true]`. The target classes.
133    num_true: An `int`.  The number of target classes per training example.
134    num_sampled: An `int`.  The number of classes to randomly sample.
135    unique: A `bool`. Determines whether all sampled classes in a batch are
136      unique.
137    range_max: An `int`. The number of possible classes.
138    seed: An `int`. An operation-specific seed. Default is 0.
139    name: A name for the operation (optional).
140
141  Returns:
142    sampled_candidates: A tensor of type `int64` and shape `[num_sampled]`.
143      The sampled classes.
144    true_expected_count: A tensor of type `float`.  Same shape as
145      `true_classes`. The expected counts under the sampling distribution
146      of each of `true_classes`.
147    sampled_expected_count: A tensor of type `float`. Same shape as
148      `sampled_candidates`. The expected counts under the sampling distribution
149      of each of `sampled_candidates`.
150  """
151  seed1, seed2 = random_seed.get_seed(seed)
152  return gen_candidate_sampling_ops.log_uniform_candidate_sampler(
153      true_classes, num_true, num_sampled, unique, range_max, seed=seed1,
154      seed2=seed2, name=name)
155
156
157@tf_export(
158    'random.learned_unigram_candidate_sampler',
159    'nn.learned_unigram_candidate_sampler')
160@dispatch.add_dispatch_support
161@deprecation.deprecated_endpoints(['nn.learned_unigram_candidate_sampler'])
162def learned_unigram_candidate_sampler(true_classes, num_true, num_sampled,
163                                      unique, range_max, seed=None, name=None):
164  """Samples a set of classes from a distribution learned during training.
165
166  This operation randomly samples a tensor of sampled classes
167  (`sampled_candidates`) from the range of integers `[0, range_max)`.
168
169  The elements of `sampled_candidates` are drawn without replacement
170  (if `unique=True`) or with replacement (if `unique=False`) from
171  the base distribution.
172
173  The base distribution for this operation is constructed on the fly
174  during training.  It is a unigram distribution over the target
175  classes seen so far during training.  Every integer in `[0, range_max)`
176  begins with a weight of 1, and is incremented by 1 each time it is
177  seen as a target class.  The base distribution is not saved to checkpoints,
178  so it is reset when the model is reloaded.
179
180  In addition, this operation returns tensors `true_expected_count`
181  and `sampled_expected_count` representing the number of times each
182  of the target classes (`true_classes`) and the sampled
183  classes (`sampled_candidates`) is expected to occur in an average
184  tensor of sampled classes.  These values correspond to `Q(y|x)`
185  defined in [this
186  document](http://www.tensorflow.org/extras/candidate_sampling.pdf).
187  If `unique=True`, then these are post-rejection probabilities and we
188  compute them approximately.
189
190  Args:
191    true_classes: A `Tensor` of type `int64` and shape `[batch_size,
192      num_true]`. The target classes.
193    num_true: An `int`.  The number of target classes per training example.
194    num_sampled: An `int`.  The number of classes to randomly sample.
195    unique: A `bool`. Determines whether all sampled classes in a batch are
196      unique.
197    range_max: An `int`. The number of possible classes.
198    seed: An `int`. An operation-specific seed. Default is 0.
199    name: A name for the operation (optional).
200
201  Returns:
202    sampled_candidates: A tensor of type `int64` and shape `[num_sampled]`.
203      The sampled classes.
204    true_expected_count: A tensor of type `float`.  Same shape as
205      `true_classes`. The expected counts under the sampling distribution
206      of each of `true_classes`.
207    sampled_expected_count: A tensor of type `float`. Same shape as
208      `sampled_candidates`. The expected counts under the sampling distribution
209      of each of `sampled_candidates`.
210
211  """
212  seed1, seed2 = random_seed.get_seed(seed)
213  return gen_candidate_sampling_ops.learned_unigram_candidate_sampler(
214      true_classes, num_true, num_sampled, unique, range_max, seed=seed1,
215      seed2=seed2, name=name)
216
217
218@tf_export('random.fixed_unigram_candidate_sampler',
219           'nn.fixed_unigram_candidate_sampler')
220@dispatch.add_dispatch_support
221def fixed_unigram_candidate_sampler(true_classes,
222                                    num_true,
223                                    num_sampled,
224                                    unique,
225                                    range_max,
226                                    vocab_file='',
227                                    distortion=1.0,
228                                    num_reserved_ids=0,
229                                    num_shards=1,
230                                    shard=0,
231                                    unigrams=(),
232                                    seed=None,
233                                    name=None):
234  """Samples a set of classes using the provided (fixed) base distribution.
235
236  This operation randomly samples a tensor of sampled classes
237  (`sampled_candidates`) from the range of integers `[0, range_max)`.
238
239  The elements of `sampled_candidates` are drawn without replacement
240  (if `unique=True`) or with replacement (if `unique=False`) from
241  the base distribution.
242
243  The base distribution is read from a file or passed in as an
244  in-memory array. There is also an option to skew the distribution by
245  applying a distortion power to the weights.
246
247  In addition, this operation returns tensors `true_expected_count`
248  and `sampled_expected_count` representing the number of times each
249  of the target classes (`true_classes`) and the sampled
250  classes (`sampled_candidates`) is expected to occur in an average
251  tensor of sampled classes.  These values correspond to `Q(y|x)`
252  defined in [this
253  document](http://www.tensorflow.org/extras/candidate_sampling.pdf).
254  If `unique=True`, then these are post-rejection probabilities and we
255  compute them approximately.
256
257  Args:
258    true_classes: A `Tensor` of type `int64` and shape `[batch_size,
259      num_true]`. The target classes.
260    num_true: An `int`.  The number of target classes per training example.
261    num_sampled: An `int`.  The number of classes to randomly sample.
262    unique: A `bool`. Determines whether all sampled classes in a batch are
263      unique.
264    range_max: An `int`. The number of possible classes.
265    vocab_file: Each valid line in this file (which should have a CSV-like
266      format) corresponds to a valid word ID. IDs are in sequential order,
267      starting from num_reserved_ids. The last entry in each line is expected
268      to be a value corresponding to the count or relative probability. Exactly
269      one of `vocab_file` and `unigrams` needs to be passed to this operation.
270    distortion: The distortion is used to skew the unigram probability
271      distribution.  Each weight is first raised to the distortion's power
272      before adding to the internal unigram distribution. As a result,
273      `distortion = 1.0` gives regular unigram sampling (as defined by the vocab
274      file), and `distortion = 0.0` gives a uniform distribution.
275    num_reserved_ids: Optionally some reserved IDs can be added in the range
276      `[0, num_reserved_ids)` by the users. One use case is that a special
277      unknown word token is used as ID 0. These IDs will have a sampling
278      probability of 0.
279    num_shards: A sampler can be used to sample from a subset of the original
280      range in order to speed up the whole computation through parallelism. This
281      parameter (together with `shard`) indicates the number of partitions that
282      are being used in the overall computation.
283    shard: A sampler can be used to sample from a subset of the original range
284      in order to speed up the whole computation through parallelism. This
285      parameter (together with `num_shards`) indicates the particular partition
286      number of the operation, when partitioning is being used.
287    unigrams: A list of unigram counts or probabilities, one per ID in
288      sequential order. Exactly one of `vocab_file` and `unigrams` should be
289      passed to this operation.
290    seed: An `int`. An operation-specific seed. Default is 0.
291    name: A name for the operation (optional).
292
293  Returns:
294    sampled_candidates: A tensor of type `int64` and shape `[num_sampled]`.
295      The sampled classes.
296    true_expected_count: A tensor of type `float`.  Same shape as
297      `true_classes`. The expected counts under the sampling distribution
298      of each of `true_classes`.
299    sampled_expected_count: A tensor of type `float`. Same shape as
300      `sampled_candidates`. The expected counts under the sampling distribution
301      of each of `sampled_candidates`.
302
303  """
304  seed1, seed2 = random_seed.get_seed(seed)
305  return gen_candidate_sampling_ops.fixed_unigram_candidate_sampler(
306      true_classes, num_true, num_sampled, unique, range_max,
307      vocab_file=vocab_file, distortion=distortion,
308      num_reserved_ids=num_reserved_ids, num_shards=num_shards, shard=shard,
309      unigrams=unigrams, seed=seed1, seed2=seed2, name=name)
310
311
312@tf_export('random.all_candidate_sampler', 'nn.all_candidate_sampler')
313def all_candidate_sampler(true_classes, num_true, num_sampled, unique,
314                          seed=None, name=None):
315  """Generate the set of all classes.
316
317  Deterministically generates and returns the set of all possible classes.
318  For testing purposes.  There is no need to use this, since you might as
319  well use full softmax or full logistic regression.
320
321  Args:
322    true_classes: A `Tensor` of type `int64` and shape `[batch_size,
323      num_true]`. The target classes.
324    num_true: An `int`.  The number of target classes per training example.
325    num_sampled: An `int`.  The number of possible classes.
326    unique: A `bool`. Ignored.
327      unique.
328    seed: An `int`. An operation-specific seed. Default is 0.
329    name: A name for the operation (optional).
330
331  Returns:
332    sampled_candidates: A tensor of type `int64` and shape `[num_sampled]`.
333      This operation deterministically returns the entire range
334      `[0, num_sampled]`.
335    true_expected_count: A tensor of type `float`.  Same shape as
336      `true_classes`. The expected counts under the sampling distribution
337      of each of `true_classes`. All returned values are 1.0.
338    sampled_expected_count: A tensor of type `float`. Same shape as
339      `sampled_candidates`. The expected counts under the sampling distribution
340      of each of `sampled_candidates`. All returned values are 1.0.
341  """
342  seed1, seed2 = random_seed.get_seed(seed)
343  return gen_candidate_sampling_ops.all_candidate_sampler(
344      true_classes, num_true, num_sampled, unique, seed=seed1, seed2=seed2,
345      name=name)
346
347
348@tf_export('nn.compute_accidental_hits')
349@dispatch.add_dispatch_support
350def compute_accidental_hits(true_classes, sampled_candidates, num_true,
351                            seed=None, name=None):
352  """Compute the position ids in `sampled_candidates` matching `true_classes`.
353
354  In Candidate Sampling, this operation facilitates virtually removing
355  sampled classes which happen to match target classes.  This is done
356  in Sampled Softmax and Sampled Logistic.
357
358  See our [Candidate Sampling Algorithms
359  Reference](http://www.tensorflow.org/extras/candidate_sampling.pdf).
360
361  We presuppose that the `sampled_candidates` are unique.
362
363  We call it an 'accidental hit' when one of the target classes
364  matches one of the sampled classes.  This operation reports
365  accidental hits as triples `(index, id, weight)`, where `index`
366  represents the row number in `true_classes`, `id` represents the
367  position in `sampled_candidates`, and weight is `-FLOAT_MAX`.
368
369  The result of this op should be passed through a `sparse_to_dense`
370  operation, then added to the logits of the sampled classes. This
371  removes the contradictory effect of accidentally sampling the true
372  target classes as noise classes for the same example.
373
374  Args:
375    true_classes: A `Tensor` of type `int64` and shape `[batch_size,
376      num_true]`. The target classes.
377    sampled_candidates: A tensor of type `int64` and shape `[num_sampled]`.
378      The sampled_candidates output of CandidateSampler.
379    num_true: An `int`.  The number of target classes per training example.
380    seed: An `int`. An operation-specific seed. Default is 0.
381    name: A name for the operation (optional).
382
383  Returns:
384    indices: A `Tensor` of type `int32` and shape `[num_accidental_hits]`.
385      Values indicate rows in `true_classes`.
386    ids: A `Tensor` of type `int64` and shape `[num_accidental_hits]`.
387      Values indicate positions in `sampled_candidates`.
388    weights: A `Tensor` of type `float` and shape `[num_accidental_hits]`.
389      Each value is `-FLOAT_MAX`.
390
391  """
392  seed1, seed2 = random_seed.get_seed(seed)
393  return gen_candidate_sampling_ops.compute_accidental_hits(
394      true_classes, sampled_candidates, num_true, seed=seed1, seed2=seed2,
395      name=name)
396