Example #1
0
class Sampler():
    def __init__(self, inputDim=1, outputDim=1, optimizer=Adam()):
        self.inputDim = inputDim
        self.outputDim = outputDim
        self.mean = Dense(self.inputDim,
                          self.outputDim,
                          activation=Identity(),
                          optimizer=copy.copy(optimizer))
        self.logVar = Dense(self.inputDim,
                            self.outputDim,
                            activation=Identity(),
                            optimizer=copy.copy(optimizer))

    def feedforward(self, input):
        self.latentMean = self.mean.feedforward(input)
        self.latentLogVar = self.logVar.feedforward(input)

        self.epsilon = np.random.standard_normal(size=(self.outputDim,
                                                       input.shape[1]))
        self.sample = self.latentMean + np.exp(
            self.latentLogVar / 2.) * self.epsilon

        return self.sample

    def backpropagate(self, lastGradient):
        gradLogVar = {}
        gradMean = {}
        tmp = self.outputDim * lastGradient.shape[1]

        # KL divergence gradients
        gradLogVar["KL"] = (np.exp(self.latentLogVar) - 1) / (2 * tmp)
        gradMean["KL"] = self.latentMean / tmp

        # MSE gradients
        gradLogVar["MSE"] = 0.5 * lastGradient * self.epsilon * np.exp(
            self.latentLogVar / 2.)
        gradMean["MSE"] = lastGradient

        # backpropagate gradients thorugh self.mean and self.logVar
        return self.mean.backward(gradMean["KL"] +
                                  gradMean["MSE"]) + self.logVar.backward(
                                      gradLogVar["KL"] + gradLogVar["MSE"])

    def getKLDivergence(self, output):
        # output.shape[1] == batchSize
        return -np.sum(1 + self.latentLogVar - np.square(self.latentMean) -
                       np.exp(self.latentLogVar)) / (2 * self.outputDim *
                                                     output.shape[1])