code: def isemhash_bottleneck(x,
                          bottleneck_bits,
                          bottleneck_noise,
                          discretize_warmup_steps,
                          mode,
                          isemhash_noise_dev=0.5,
                          isemhash_mix_prob=0.5):
    
    with tf.variable_scope("isemhash_bottleneck"):
      x = tf.layers.dense(x, bottleneck_bits, name="dense")
      y = common_layers.saturating_sigmoid(x)
      if isemhash_noise_dev > 0 and mode == tf.estimator.ModeKeys.TRAIN:
        noise = tf.truncated_normal(
            common_layers.shape_list(x), mean=0.0, stddev=isemhash_noise_dev)
        y = common_layers.saturating_sigmoid(x + noise)
      d = tf.to_float(tf.less(0.5, y)) + y - tf.stop_gradient(y)
      d = 2.0 * d - 1.0  # Move from [0, 1] to [-1, 1].
      if mode == tf.estimator.ModeKeys.TRAIN:  # Flip some bits.
        noise = tf.random_uniform(common_layers.shape_list(x))
        noise = 2.0 * tf.to_float(tf.less(bottleneck_noise, noise)) - 1.0
        d *= noise
        d = common_layers.mix(
            d,
            2.0 * y - 1.0,
            discretize_warmup_steps,
            mode == tf.estimator.ModeKeys.TRAIN,
            max_prob=isemhash_mix_prob)
      return d, 0.0
docs: Improved semantic hashing bottleneck.