首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么Tensorflow张量索引在规范化流"prob“方法中失败

为什么Tensorflow张量索引在规范化流"prob“方法中失败
EN

Stack Overflow用户
提问于 2021-07-27 03:08:05
回答 2查看 91关注 0票数 1

我正在Tensorflow中构建一个规范化的流(分布和双射子链的连接)。以下是Bijector链的代码:

代码语言:javascript
复制
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方法:

代码语言:javascript
复制
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 )

最后一条语句失败,堆栈跟踪如下:

代码语言:javascript
复制
---------------------------------------------------------------------------
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]

我无法从堆栈跟踪中找出哪里出了问题。

你能帮上忙吗?

EN

回答 2

Stack Overflow用户

发布于 2021-07-30 15:54:13

通过尝试随机扰动我的代码,我能够找到解决方案:在对Bijector.__init__的调用中,将事件形状的最小维数从0改为1,并将_forward_log_det_jacobian方法的事件形状的维数从2改为1。

<opinion>为什么错误消息不能更直接地指出此问题?</opinion>

票数 0
EN

Stack Overflow用户

发布于 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.“中进行一些更改。)

代码语言:javascript
复制
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)

希望它能为您工作!:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68535253

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档