'random sample function that actually returns mean
new forward pass that returns logQ as a list
can get x_i from samples'

def get_muprop_gradient(self):

    (logQHard, hardSamples) = self._recognition_network()
    (hardELBO, reinforce_model_grad) = self._generator_network(hardSamples, logQHard)
    (logQ, muSamples) = self._recognition_network(sampler=self._mean_sample)
    (muELBO, _) = self._generator_network(muSamples, logQ)
    muELBOGrads = tf.gradients(tf.reduce_sum(muELBO), [muSamples[i]['activation'] for i in xrange(self.hparams.n_layer)])
    learning_signal = hardELBO
    optimizerLoss = 0.0
    learning_signals = []
    for i in xrange(self.hparams.n_layer):
        dfDiff = tf.reduce_sum((muELBOGrads[i] * (hardSamples[i]['activation'] - muSamples[i]['activation'])), axis=1)
        dfMu = tf.reduce_sum((tf.stop_gradient(muELBOGrads[i]) * tf.nn.sigmoid(hardSamples[i]['log_param'])), axis=1)
        scaling_baseline_0 = self._create_eta(collection='BASELINE')
        scaling_baseline_1 = self._create_eta(collection='BASELINE')
        learning_signals.append((((learning_signal - (scaling_baseline_0 * muELBO)) - (scaling_baseline_1 * dfDiff)) - self._create_baseline()))
        self.baseline_loss.append(tf.square(learning_signals[i]))
        optimizerLoss += ((logQHard[i] * tf.stop_gradient(learning_signals[i])) + (tf.stop_gradient(scaling_baseline_1) * dfMu))
    optimizerLoss += reinforce_model_grad
    optimizerLoss *= (-1)
    optimizerLoss = tf.reduce_mean(optimizerLoss)
    muprop_gradient = self.optimizer_class.compute_gradients(optimizerLoss)
    debug = {'ELBO': hardELBO, 'muELBO': muELBO}
    debug.update(dict([(('RMS    learning    signal    layer    %d' % i), U.rms(learning_signal)) for (i, learning_signal) in enumerate(learning_signals)]))
    return (muprop_gradient, debug)
