конструкция тензорного биектора - PullRequest
0 голосов
/ 04 июня 2018

Я новичок в распределении тензорного потока и биектор.Я знаю, что когда они разрабатывают пакет распределения tenorflow, они делят форму тензора на три группы: [sample shape, batch_shape, event_shape].Но мне трудно понять, почему, когда мы определяем новый класс биекторов, они всегда определяют размер события родительского класса равным 1. Например, следующий код является классом биекторов Real-NVP, и в его init function:

super(NVPCoupling, self).__init__(
                event_ndims=1, validate_args=validate_args, name=name)

Но, насколько я понимаю, этот класс реального NVP действует на тензор, размерность события которого равна D, верно?

def net(x, out_size):
        return layers.stack(x, layers.fully_connected, [512, 512, out_size])

    # Affine Coupling layer for Real-NVP


    class NVPCoupling(tfb.Bijector):
        """NVP affine coupling layer for 2D units.
        """

        def __init__(self, D, d, layer_id=0, validate_args=False, name="NVPCoupling"):
            """
            Args:
              d: First d units are pass-thru units.
            """
            # first d numbers decide scaling/shift factor for remaining D-d numbers.
            super(NVPCoupling, self).__init__(
                event_ndims=1, validate_args=validate_args, name=name)
            self.D, self.d = D, d
            self.id = layer_id
            # create variables here
            tmp = tf.placeholder(dtype=DTYPE, shape=[1, self.d])
            self.s(tmp)
            self.t(tmp)

        def s(self, xd):
            with tf.variable_scope('s%d' % self.id, reuse=tf.AUTO_REUSE):
                return net(xd, self.D - self.d)

        def t(self, xd):
            with tf.variable_scope('t%d' % self.id, reuse=tf.AUTO_REUSE):
                return net(xd, self.D - self.d)

        def _forward(self, x):
            xd, xD = x[:, :self.d], x[:, self.d:]
            yD = xD * tf.exp(self.s(xd)) + self.t(xd)  # [batch, D-d]
            return tf.concat([xd, yD], axis=1)

        def _inverse(self, y):
            yd, yD = y[:, :self.d], y[:, self.d:]
            xD = (yD - self.t(yd)) * tf.exp(-self.s(yd))
            return tf.concat([yd, xD], axis=1)

        def _forward_log_det_jacobian(self, x):
            event_dims = self._event_dims_tensor(x)
            xd = x[:, :self.d]
            return tf.reduce_sum(self.s(xd), axis=event_dims)

Кроме того, когда мы используемтензор образца для его обучения, тензор имеет форму [batch_size, D].Но местозаполнитель tmp имеет форму = [1, self.d], а не [Batch_size, self.d].В чем причина этого.Надеюсь, что некоторые эксперты могут прояснить это.Спасибо.

1 Ответ

0 голосов
/ 05 июля 2018

event_ndims - это число измерений события, а не размер ввода.Таким образом, event_ndims=1 работает с векторами, event_ndims=2 с матрицами и так далее.См. __init__ строку документации для Bijector класса.

...