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