我正在Tensorflow中构建一个规范化的流(分布和双射子链的连接)。以下是Bijector链的代码:
class Flow( tfb.Bijector ):
def __init__( self, theta, a, **kwargs ):
tfb.Bijector.__init__( self, forward_min_event_ndims = 0, **kwargs )
bijectors = [ tfb.Tanh() ]
self.chain = tfb.Chain( bijectors = bijectors )
def _forward( self, z ):
return self.chain( z )
def _inverse( self, x ):
result = self.chain.inverse( x )
return result
def _forward_log_det_jacobian( self, z ):
return self.chain._forward_log_det_jacobian( z, event_ndims = 2 )下面是我尝试测试它的方法,特别是测试基本分发和流的prob方法:
Z = tf.convert_to_tensor( [ [ [ 0.1, 0.2 ], [ 0.3, 0.4 ], [ 0.5, 0.6 ] ],
[ [ 0.8, 0.7 ], [ 0.6, 0.5 ], [ 0.4, 0.3 ] ],
[ [ 0.4, 0.7 ], [ 0.2, 0.1 ], [ 0.8, 0.0 ] ] ] )
print( "Z", Z )
nf = Flow( 1., 2. ) # ### theta, a
bd = tfd.MultivariateNormalDiag( loc=[0.,0.], scale_diag=[1.,1.] )
td = tfd.TransformedDistribution( bd, nf )
td.log_prob( Z )最后一条语句失败,堆栈跟踪如下:
---------------------------------------------------------------------------
InvalidArgumentError Traceback (most recent call last)
<ipython-input-29-9f91e9e1871a> in <module>()
24 bd = tfd.MultivariateNormalDiag( loc=[0.,0], scale_diag=[1.,1.] )
25 td = tfd.TransformedDistribution( bd, nf )
---> 26 td.prob( Z )
12 frames
/usr/local/lib/python3.7/dist-packages/tensorflow_probability/python/distributions/distribution.py in prob(self, value, name, **kwargs)
1322 values of type `self.dtype`.
1323 """
-> 1324 return self._call_prob(value, name, **kwargs)
1325
1326 def _call_unnormalized_log_prob(self, value, name, **kwargs):
/usr/local/lib/python3.7/dist-packages/tensorflow_probability/python/distributions/distribution.py in _call_prob(self, value, name, **kwargs)
1304 with self._name_and_control_scope(name, value, kwargs):
1305 if hasattr(self, '_prob'):
-> 1306 return self._prob(value, **kwargs)
1307 if hasattr(self, '_log_prob'):
1308 return tf.exp(self._log_prob(value, **kwargs))
/usr/local/lib/python3.7/dist-packages/tensorflow_probability/python/distributions/transformed_distribution.py in _prob(self, y, **kwargs)
371 )
372 ildj = self.bijector.inverse_log_det_jacobian(
--> 373 y, event_ndims=event_ndims, **bijector_kwargs)
374 if self.bijector._is_injective: # pylint: disable=protected-access
375 base_prob = self.distribution.prob(x, **distribution_kwargs)
/usr/local/lib/python3.7/dist-packages/tensorflow_probability/python/bijectors/bijector.py in inverse_log_det_jacobian(self, y, event_ndims, name, **kwargs)
1318 ValueError: if the value of `event_ndims` is not valid for this bijector.
1319 """
-> 1320 return self._call_inverse_log_det_jacobian(y, event_ndims, name, **kwargs)
1321
1322 def _call_forward_log_det_jacobian(self, x, event_ndims, name, **kwargs):
/usr/local/lib/python3.7/dist-packages/tensorflow_probability/python/bijectors/bijector.py in _call_inverse_log_det_jacobian(self, y, event_ndims, name, **kwargs)
1274 'is implemented. One or the other is required.')
1275
-> 1276 return self._reduce_jacobian_det_over_shape(ildj, reduce_shape)
1277
1278 def inverse_log_det_jacobian(self,
/usr/local/lib/python3.7/dist-packages/tensorflow_probability/python/bijectors/bijector.py in _reduce_jacobian_det_over_shape(self, unreduced, reduce_shape)
1531 ones = tf.ones(reduce_shape, unreduced.dtype)
1532 reduce_dims = ps.range(-ps.size(reduce_shape), 0)
-> 1533 return tf.reduce_sum(ones * unreduced, axis=reduce_dims)
1534
1535 def _parameter_control_dependencies(self, is_init):
/usr/local/lib/python3.7/dist-packages/tensorflow/python/ops/math_ops.py in binary_op_wrapper(x, y)
1232 # r_binary_op_wrapper use different force_same_dtype values.
1233 x, y = maybe_promote_tensors(x, y, force_same_dtype=False)
-> 1234 return func(x, y, name=name)
1235 except (TypeError, ValueError) as e:
1236 # Even if dispatching the op failed, the RHS may be a tensor aware
/usr/local/lib/python3.7/dist-packages/tensorflow/python/ops/math_ops.py in _mul_dispatch(x, y, name)
1573 return sparse_tensor.SparseTensor(y.indices, new_vals, y.dense_shape)
1574 else:
-> 1575 return multiply(x, y, name=name)
1576
1577
/usr/local/lib/python3.7/dist-packages/tensorflow/python/util/dispatch.py in wrapper(*args, **kwargs)
204 """Call target, and fall back on dispatchers if there is a TypeError."""
205 try:
--> 206 return target(*args, **kwargs)
207 except (TypeError, ValueError):
208 # Note: convert_to_eager_tensor currently raises a ValueError, not a
/usr/local/lib/python3.7/dist-packages/tensorflow/python/ops/math_ops.py in multiply(x, y, name)
528 """
529
--> 530 return gen_math_ops.mul(x, y, name)
531
532
/usr/local/lib/python3.7/dist-packages/tensorflow/python/ops/gen_math_ops.py in mul(x, y, name)
6238 return _result
6239 except _core._NotOkStatusException as e:
-> 6240 _ops.raise_from_not_ok_status(e, name)
6241 except _core._FallbackException:
6242 pass
/usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/ops.py in raise_from_not_ok_status(e, name)
6895 message = e.message + (" name: " + name if name is not None else "")
6896 # pylint: disable=protected-access
-> 6897 six.raise_from(core._status_to_exception(e.code, message), None)
6898 # pylint: enable=protected-access
6899
/usr/local/lib/python3.7/dist-packages/six.py in raise_from(value, from_value)
InvalidArgumentError: required broadcastable shapes at loc(unknown) [Op:Mul]我无法从堆栈跟踪中找出哪里出了问题。
你能帮上忙吗?
发布于 2021-07-30 15:54:13
通过尝试随机扰动我的代码,我能够找到解决方案:在对Bijector.__init__的调用中,将事件形状的最小维数从0改为1,并将_forward_log_det_jacobian方法的事件形状的维数从2改为1。
<opinion>为什么错误消息不能更直接地指出此问题?</opinion>
发布于 2021-08-05 21:05:36
使用此代码我将event_ndims =3从2更改为3,然后定义init( self,theta,a,b,**kwargs ):给出3个变量而不是2,因为数组是3_3_2,所以需要在"tfd.MultivariateNormalDiag(loc=1.,2.,scale_identity_multiplier=1.,2.,3.“中进行一些更改。)
import tensorflow as tf
import tensorflow_probability as tfp
tfb = tfp.bijectors
tfd = tfp.distributions
Z = tf.convert_to_tensor( [[[ 0.1, 0.2 ], [ 0.3, 0.4 ], [ 0.5, 0.6 ]], [[ 0.8, 0.7 ], [ 0.6, 0.5 ], [ 0.4, 0.3 ]],[[ 0.4, 0.7 ], [ 0.2, 0.1 ], [ 0.8, 0.0 ]]] )
class Flow( tfb.Bijector ):
def __init__( self, theta, a,b, **kwargs ):
tfb.Bijector.__init__( self, forward_min_event_ndims = 0, **kwargs )
bijectors = [ tfb.Tanh() ]
self.chain = tfb.Chain( bijectors = bijectors )
def _forward( self, z ):
return self.chain( z )
def _inverse( self, x ):
result = self.chain.inverse( x )
return result
def _forward_log_det_jacobian( self, z ):
return self.chain._forward_log_det_jacobian( z, event_ndims = 3 )
nf = Flow(1,2,3)
bd = tfd.MultivariateNormalDiag(loc=[1., 2.], scale_identity_multiplier=[1., 2.,3.])
td = tfd.TransformedDistribution(bd, nf)
td.log_prob(Z)希望它能为您工作!:)
https://stackoverflow.com/questions/68535253
复制相似问题