张量流双射结构
tensorflow bijector construction
我是张量流分布和双射器的新手。我知道当他们设计 tensorflow 分发包时,他们将张量的形状分为三组:[sample shape, batch_shape, event_shape]。但是我很难理解为什么当我们定义一个新的bijectorclass时,他们总是定义parentclass的事件维度为1。例如下面的代码是一个Real-NVP bijectorclass,并在其 init 函数中:
super(NVPCoupling, self).__init__(
event_ndims=1, validate_args=validate_args, name=name)
但是据我了解,这个real-NVPclass是作用在事件维度为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]。这是什么原因。
希望有高手能解释一下。谢谢
event_ndims
是事件维度的数,不是输入的大小。因此 event_ndims=1
对向量进行运算,event_ndims=2
对矩阵进行运算,依此类推。请参阅 __init__
文档字符串以获得 Bijector
class。
我是张量流分布和双射器的新手。我知道当他们设计 tensorflow 分发包时,他们将张量的形状分为三组:[sample shape, batch_shape, event_shape]。但是我很难理解为什么当我们定义一个新的bijectorclass时,他们总是定义parentclass的事件维度为1。例如下面的代码是一个Real-NVP bijectorclass,并在其 init 函数中:
super(NVPCoupling, self).__init__(
event_ndims=1, validate_args=validate_args, name=name)
但是据我了解,这个real-NVPclass是作用在事件维度为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]。这是什么原因。 希望有高手能解释一下。谢谢
event_ndims
是事件维度的数,不是输入的大小。因此 event_ndims=1
对向量进行运算,event_ndims=2
对矩阵进行运算,依此类推。请参阅 __init__
文档字符串以获得 Bijector
class。