我是使用 tensorflow 的新手。我想构造一个具有以下属性的双射器:它采用维度概率分布 p(x1, x2, ..., xn),它只转换两个特定维度 i 和 j,使得 xi' = xi, xj ' = xj*exp(s(xi)) + t(xj),其中 s 和 t 是使用神经网络实现的两个函数。它输出 p(x1, x2, ..., xi', .., xj', .., xn)。我有一个基本代码如下所示:
def net(x, out_size, block_w_id, block_d_id, layer_id):
x = tf.contrib.layers.fully_connected(x, 256, reuse=tf.AUTO_REUSE, scope='x1_block_w_{}_block_d_{}_layer_{}'.format(block_w_id, \
block_d_id,\
layer_id))
x = tf.contrib.layers.fully_connected(x, 256, reuse=tf.AUTO_REUSE, scope='x2_block_w_{}_block_d_{}_layer_{}'.format(block_w_id,\
block_d_id,\
layer_id))
y = tf.contrib.layers.fully_connected(x, out_size, reuse=tf.AUTO_REUSE, scope='y_block_w_{}_block_d_{}_layer_{}'.format(block_w_id,\
block_d_id,\
layer_id))
# return layers.stack(x, layers.fully_connected(reuse=tf.AUTO_REUSE), [512, 512, out_size])
return y
class NVPCoupling(tfb.Bijector):
"""NVP affine coupling layer for 2D units.
"""
def __init__(self, input_idx1, input_idx2, block_w_id = 0, block_d_id = 0, layer_id = 0, validate_args = False\
, name="NVPCoupling"):
"""
NVPCoupling only manipulate two inputs with idx1 & idx2.
"""
super(NVPCoupling, self).__init__(\
event_ndims = 1, validate_args = validate_args, name = name)
self.idx1 = input_idx1
self.idx2 = input_idx2
self.block_w_id = block_w_id
self.block_d_id = block_d_id
self.layer_id = layer_id
# create variables
tmp = tf.placeholder(dtype=DTYPE, shape = [1, 1])
self.s(tmp)
self.t(tmp)
def s(self, xd):
with tf.variable_scope('s_block_w_id_{}_block_d_id_{}_layer_{}'.format(self.block_w_id,\
self.block_d_id,\
self.layer_id),\
reuse = tf.AUTO_REUSE):
return net(xd, 1, self.block_w_id, self.block_d_id, self.layer_id)
def t(self, xd):
with tf.variable_scope('t_block_w_id_{}_block_d_id_{}_layer_{}'.format(self.block_w_id,\
self.block_d_id,\
self.layer_id),\
reuse = tf.AUTO_REUSE):
return net(xd, 1, self.block_w_id, self.block_d_id, self.layer_id)
def _forward(self, x):
x_left, x_right = x[:, self.idx1:(self.idx1 + 1)], x[:, self.idx2:(self.idx2 + 1)]
y_right = x_right * tf.exp(self.s(x_left)) + self.t(x_left)
output_tensor = tf.concat([ x[:,0:self.idx1], x_left, x[:, self.idx1+1:self.idx2]\
, y_right, x[:, (self.idx2+1):]], axis = 1)
return output_tensor
def _inverse(self, y):
y_left, y_right = y[:, self.idx1:(self.idx1 + 1)], y[:, self.idx2:(self.idx2 + 1)]
x_right = (y_right - self.t(y_left)) * tf.exp(-self.s(y_left))
output_tensor = tf.concat([ y[:, 0:self.idx1], y_left, y[:, self.idx1+1 : self.idx2]\
, x_right, y[:, (self.idx2+1):]], axis = 1)
return output_tensor
def _forward_log_det_jacobian(self, x):
event_dims = self._event_dims_tensor(x)
x_left = x[:, self.idx1:(self.idx1+1)]
return tf.reduce_sum(self.s(x_left), axis=event_dims)
但它并没有像我想的那样工作。当我使用该类时,它会弹出一个错误:
base_dist = tfd.MultivariateNormalDiag(loc=tf.zeros([2], DTYPE))
num_bijectors = 4
bijectors = []
bijectors.append(NVPCoupling(input_idx1=0, input_idx2=1, \
block_w_id=0, block_d_id=0, layer_id=0))
bijectors.append(NVPCoupling(input_idx1=1, input_idx2=0, \
block_w_id=0, block_d_id=0, layer_id=1))
bijectors.append(NVPCoupling(input_idx1=0, input_idx2=1, \
block_w_id=0, block_d_id=0, layer_id=2))
bijectors.append(NVPCoupling(input_idx1=0, input_idx2=1, \
block_w_id=0, block_d_id=0, layer_id=3))
flow_bijector = tfb.Chain(list(reversed(bijectors)))
dist = tfd.TransformedDistribution(
distribution=base_dist,
bijector=flow_bijector)
dist.sample(1000)
有错误:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-16-04da05d30f8d> in <module>()
----> 1 dist.sample(1000)
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/tensorflow/python/ops/distributions/distribution.pyc in sample(self, sample_shape, seed, name)
708 samples: a `Tensor` with prepended dimensions `sample_shape`.
709 """
--> 710 return self._call_sample_n(sample_shape, seed, name)
711
712 def _log_prob(self, value):
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/tensorflow/python/ops/distributions/transformed_distribution.pyc in _call_sample_n(self, sample_shape, seed, name, **kwargs)
412 # returned result.
413 y = self.bijector.forward(x, **kwargs)
--> 414 y = self._set_sample_static_shape(y, sample_shape)
415
416 return y
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/tensorflow/python/ops/distributions/distribution.pyc in _set_sample_static_shape(self, x, sample_shape)
1220 shape = tensor_shape.TensorShape(
1221 [None]*(ndims - event_ndims)).concatenate(self.event_shape)
-> 1222 x.set_shape(x.get_shape().merge_with(shape))
1223
1224 # Infer batch shape.
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/tensorflow/python/framework/tensor_shape.pyc in merge_with(self, other)
671 return TensorShape(new_dims)
672 except ValueError:
--> 673 raise ValueError("Shapes %s and %s are not compatible" % (self, other))
674
675 def concatenate(self, other):
ValueError: Shapes (1000, 4) and (?, 2) are not compatible
真的希望一些专家可以帮助我了解我做错了什么以及如何解决这个问题。非常感谢!H。