关于tf.Sparse_Tensor的dense_shape的问题?

问题描述

简单来说,目的是在MyClass中,根据self.inputs选择合适的membership function,要么是rul,要么是2-rul,在def __init__中定义self.inputs的shape =(None, n_inputs),所以rul.shape[0]也是未知的。由于张量的值不能修改,计划先用tf.where()提取indices,随后用tf.gather_nd提取对应的值,然后用tf.SparseTensor构建稀疏张量,最后用tf.assign更新self.rul。具体代码如下。现在问题来了,到tf.SparseTensor这里报错“ValueError: Cannot convert a partially known TensorShape to a Tensor: (?, 24)”,我觉得是dense_shape应该要明确指定的缘故。诚心求教,怎么解决这个问题?不胜感激!

原始代码

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

class MyClass:

    def __init__(self, n_inputs, n_rules, learning_rate=1e-2):
        self.n = n_inputs
        self.m = n_rules
        self.inputs = tf.placeholder(tf.float32, shape=(None, n_inputs))  # Input
        self.targets = tf.placeholder(tf.float32, shape=None)  # Desired output
        mu = tf.get_variable("mu", [n_rules * n_inputs],
                             initializer=tf.random_normal_initializer(0, 1))  # Means of Gaussian MFS
        sigma = tf.get_variable("sigma", [n_rules * n_inputs],
                                initializer=tf.random_normal_initializer(0, 1))  # Standard deviations of Gaussian MFS
        y = tf.get_variable("y", [1, n_rules], initializer=tf.random_normal_initializer(0, 1))  # Sequent centers

        self.params = tf.trainable_variables()

        # rules activation. 
        Rul = tf.exp(-0.5 * tf.square(tf.subtract(tf.tile(self.inputs,(1,n_rules)),mu)) / tf.square(sigma))
        Rul_diff = 2. - 2 * Rul
                
        indices = tf.where(tf.less(tf.tile(tf.reduce_mean(self.inputs, axis = 0),[n_rules]),tf.tile(self.inputs,(1,n_rules))))
        gather_nd = tf.gather_nd(Rul, indices)
        Rul1 = tf.SparseTensor(indices, gather_nd, tf.shape(Rul))
        Rul_add = tf.sparse_tensor_to_dense(tf.SparseTensor(indices, gather_nd, tf.shape(Rul)))
        Ruls = tf.assign_add(Rul, Rul_add)
        ........

错误信息

~\ in __init__(self, n_inputs, n_rules, learning_rate)
     36         indices = tf.where(tf.less(tf.tile(tf.reduce_mean(self.inputs, axis = 0),[n_rules]),tf.tile(self.inputs,(1,n_rules))))
     37         gather_nd = tf.gather_nd(Rul, indices)
---> 38         Rul1 = tf.SparseTensor(indices, gather_nd, tf.shape(Rul))
     39         #Rul_add = tf.sparse_tensor_to_dense(tf.SparseTensor(indices, gather_nd, tf.shape(Rul)))
     40         Rul_add = tf.sparses_tensor_to_dense(Rul1)

D:\Anaconda3\envs\tf1.5\lib\site-packages\tensorflow\python\framework\sparse_tensor.py in __init__(self, indices, values, dense_shape)
    126           values, name="values", as_ref=True)
    127       dense_shape = ops.convert_to_tensor(
--> 128           dense_shape, name="dense_shape", dtype=dtypes.int64)
    129     self._indices = indices
    130     self._values = values

D:\Anaconda3\envs\tf1.5\lib\site-packages\tensorflow\python\framework\ops.py in convert_to_tensor(value, dtype, name, preferred_dtype)
    944       name=name,
    945       preferred_dtype=preferred_dtype,
--> 946       as_ref=False)
    947 
    948 

D:\Anaconda3\envs\tf1.5\lib\site-packages\tensorflow\python\framework\ops.py in internal_convert_to_tensor(value, dtype, name, as_ref, preferred_dtype, ctx)
   1034 
   1035     if ret is None:
-> 1036       ret = conversion_func(value, dtype=dtype, name=name, as_ref=as_ref)
   1037 
   1038     if ret is NotImplemented:

D:\Anaconda3\envs\tf1.5\lib\site-packages\tensorflow\python\framework\constant_op.py in _tensor_shape_tensor_conversion_function(s, dtype, name, as_ref)
    254   if not s.is_fully_defined():
    255     raise ValueError(
--> 256         "Cannot convert a partially known TensorShape to a Tensor: %s" % s)
    257   s_list = s.as_list()
    258   int64_value = 0

ValueError: Cannot convert a partially known TensorShape to a Tensor: (?, 24)

你好,我是有问必答小助手,非常抱歉,本次您提出的有问必答问题,技术专家团超时未为您做出解答


本次提问扣除的有问必答次数,将会以问答VIP体验卡(1次有问必答机会、商城购买实体图书享受95折优惠)的形式为您补发到账户。


因为有问必答VIP体验卡有效期仅有1天,您在需要使用的时候【私信】联系我,我会为您补发。

几天过去,最后还是自己解决这个问题。不使用

tf.SparseTensor()

而是直接使用

tf.where(cond, x, y)

就可以实现目的。
通过这次案例,深刻理解了

tf.where(cond, x, y)

x与y为None和不为None的区别。

推及到其他函数,提醒自己要认真理解函数的说明文档。特别在此记录一下。