'Compute noisy top-k gating.
Args:
x: a `Tensor` of shape `[batch_size, input_size]`.
train: a boolean `Scalar`.   Setting this to false turns off noise.
summaries: a boolean.  Whether to add summaries.
Returns:
gates: a `Tensor` of shape `[batch_size, n]`
load: a `Tensor` of shape `[n]`.
If we are using noise, this is a smooth approximation of the load,
and you can define a loss in terms of it to help with load-balancing.'

def Eval(self, x, train=True, summaries=False):

    with tf.variable_scope('NoisyTopKGating'):
        hp = self._hp
        clean_logits = tf.matmul(x, self._w_gate)
        if hp.noisy_gating:
            raw_noise_stddev = tf.matmul(x, self._w_noise)
            noise_stddev = ((tf.nn.softplus(raw_noise_stddev) + hp.noise_epsilon) * tf.to_float(train))
            noisy_logits = (clean_logits + (tf.random_normal(tf.shape(clean_logits)) * noise_stddev))
            logits = noisy_logits
            if summaries:
                tf.summary.histogram('noisy_logits', noisy_logits)
                tf.summary.histogram('noise_stddev', noise_stddev)
        else:
            logits = clean_logits
        (top_logits, top_indices) = _MyTopK(logits, min((hp.k + 1), hp.num_experts))
        top_k_logits = tf.slice(top_logits, [0, 0], [(-1), hp.k])
        top_k_indices = tf.slice(top_indices, [0, 0], [(-1), hp.k])
        top_k_gates = tf.nn.softmax(top_k_logits)
        gates = _RowwiseUnsortedSegmentSum(top_k_gates, top_k_indices, hp.num_experts)
        if (hp.noisy_gating and (hp.k < hp.num_experts)):
            load = tf.reduce_sum(_ProbInTopK(clean_logits, noisy_logits, noise_stddev, top_logits, hp.k), 0)
        else:
            load = _GatesToLoad(gates)
        if summaries:
            tf.summary.histogram('importance', tf.reduce_sum(gates, 0))
            tf.summary.histogram('load', load)
        return (gates, load)
