tf.boolean_mask、mask_dimension一定要指定吗?
tf.boolean_mask, mask_dimension must be specified?
使用 tf.boolean_mask()
时,会出现值错误。它显示“必须指定掩码尺寸的数量,即使某些尺寸是 None。例如 shape=[None] 可以,但 shape=None 不是。
我怀疑在创建布尔掩码时出现问题,因为当我只是手动创建一个布尔掩码时,一切正常。但是,到目前为止,我已经检查了 s 的形状和数据类型,没有发现任何可疑之处。两者似乎都与我手工创建的布尔掩码的形状和类型相同。
Please see a screenshot of the problem.
以下应该允许您在您的机器上重现错误。你需要 tensorflow、numpy 和 scipy.
with tf.Session() as sess:
# receive five embedded vectors
v0 = tf.constant([[3.0,1.0,2.,4.,2.]])
v1 = tf.constant([[4.0,0,1.0,4,1.]])
v2 = tf.constant([[1.0,1.0,0.0,4.,8.]])
v3 = tf.constant([[1.,4,2.,5.,2.]])
v4 = tf.constant([[3.,2.,3.,2.,5.]])
# concatenate the five embedded vectors into a matrix
VT = tf.concat([v0,v1,v2,v3,v4],axis=0)
# perform SVD on the concatenated matrix
s, u1, u2 = tf.svd(VT)
e = tf.square(s) # list of eigenvalues
v = u1 # eigenvectors as column vectors
# sample a set
s = tf.py_func(sample_dpp_bin,[e,v],tf.bool)
X = tf.boolean_mask(VT,s)
print(X.eval())
这是生成s的代码。 s 是来自行列式点过程的样本(对于数学感兴趣的人)。
请注意,我正在使用 tf.py_func 来包装此 python 函数:
import tensorflow as tf
import numpy as np
from scipy.linalg import orth
def sample_dpp_bin(e_val,e_vec):
# e_val = np.array of eigenvalues
# e_vec = array of eigenvectors (= column vectors)
eps = 0.01
# sample a set of eigenvectors
ind = (np.random.rand(len(e_val)) <= (e_val)/(1+e_val))
k = sum(ind)
if k == e_val.size:
return np.ones(e_val.size,dtype=bool) # check for full set
if k == 0:
return np.zeros(e_val.size,dtype=bool)
V = e_vec[:,np.array(ind)]
# sample a set of k items
sample = np.zeros(e_val.size,dtype=bool)
for l in range(k-1,-1,-1):
p = np.sum(V**2,axis=1)
p = np.cumsum(p / np.sum(p)) # item cumulative probabilities
i = int((np.random.rand() <= p).argmax()) # choose random item
sample[i] = True
j = (np.abs(V[i,:])>eps).argmax() # pick an eigenvector not orthogonal to e_i
Vj = V[:,j]
V = orth(V - (np.outer(Vj,(V[i,:]/Vj[i]))))
return sample
如果我打印 s 并且 tf.reshape(s)
的输出是
[False True True True True]
[5]
如果我打印 VT 并且 tf.reshape(VT)
的输出是
[[ 3. 1. 2. 4. 2.]
[ 4. 0. 1. 4. 1.]
[ 1. 1. 0. 4. 8.]
[ 1. 4. 2. 5. 2.]
[ 3. 2. 3. 2. 5.]]
[5 5]
非常感谢任何帮助。
以下示例适合我。
import tensorflow as tf
import numpy as np
tensor = [[1, 2], [3, 4], [5, 6]]
mask = np.array([True, False, True])
t_m = tf.boolean_mask(tensor, mask)
sess = tf.Session()
print(sess.run(t_m))
输出:
[[1 2]
[5 6]]
提供您的可运行代码片段以重现错误。我认为你可能在 s 中做错了什么。
更新:
s = tf.py_func(sample_dpp_bin,[e,v],tf.bool)
s_v = (s.eval())
X = tf.boolean_mask(VT,s_v)
print(X.eval())
mask 应该是 np 数组而不是 TF 张量。您不必使用 tf.pyfunc.
错误消息指出未定义遮罩的形状。如果你打印 tf.shape(s)
你会得到什么?我敢打赌你的代码的问题是 s
的形状是完全未知的,你可以通过像 s.set_shape((None))
这样的简单调用来解决这个问题(简单地指定 s
是一个一维张量)。考虑这个代码片段:
X = np.random.randint(0, 2, (100, 100, 3))
with tf.Session() as sess:
X_tf = tf.placeholder(tf.int8)
# X_tf.set_shape((None, None, None))
y = tf.greater(tf.reduce_max(X_tf, axis=(0, 1)), 0)
print(tf.shape(y))
z = tf.boolean_mask(X_tf, y, axis=2)
print(sess.run(z, feed_dict={X_tf: X}))
这会打印 Tensor("Shape_3:0", shape=(?,), dtype=int32)
的形状(即,甚至 y
的尺寸也是未知的)和 returns 与您遇到的错误相同。但是,如果取消注释 set_shape
行,则已知 X_tf
是 3 维的,因此 s
是 1 维的。代码然后工作。所以,我认为您需要做的就是在 py_func
调用之后添加一个 s.set_shape((None))
调用。
使用 tf.boolean_mask()
时,会出现值错误。它显示“必须指定掩码尺寸的数量,即使某些尺寸是 None。例如 shape=[None] 可以,但 shape=None 不是。
我怀疑在创建布尔掩码时出现问题,因为当我只是手动创建一个布尔掩码时,一切正常。但是,到目前为止,我已经检查了 s 的形状和数据类型,没有发现任何可疑之处。两者似乎都与我手工创建的布尔掩码的形状和类型相同。
Please see a screenshot of the problem. 以下应该允许您在您的机器上重现错误。你需要 tensorflow、numpy 和 scipy.
with tf.Session() as sess:
# receive five embedded vectors
v0 = tf.constant([[3.0,1.0,2.,4.,2.]])
v1 = tf.constant([[4.0,0,1.0,4,1.]])
v2 = tf.constant([[1.0,1.0,0.0,4.,8.]])
v3 = tf.constant([[1.,4,2.,5.,2.]])
v4 = tf.constant([[3.,2.,3.,2.,5.]])
# concatenate the five embedded vectors into a matrix
VT = tf.concat([v0,v1,v2,v3,v4],axis=0)
# perform SVD on the concatenated matrix
s, u1, u2 = tf.svd(VT)
e = tf.square(s) # list of eigenvalues
v = u1 # eigenvectors as column vectors
# sample a set
s = tf.py_func(sample_dpp_bin,[e,v],tf.bool)
X = tf.boolean_mask(VT,s)
print(X.eval())
这是生成s的代码。 s 是来自行列式点过程的样本(对于数学感兴趣的人)。 请注意,我正在使用 tf.py_func 来包装此 python 函数:
import tensorflow as tf
import numpy as np
from scipy.linalg import orth
def sample_dpp_bin(e_val,e_vec):
# e_val = np.array of eigenvalues
# e_vec = array of eigenvectors (= column vectors)
eps = 0.01
# sample a set of eigenvectors
ind = (np.random.rand(len(e_val)) <= (e_val)/(1+e_val))
k = sum(ind)
if k == e_val.size:
return np.ones(e_val.size,dtype=bool) # check for full set
if k == 0:
return np.zeros(e_val.size,dtype=bool)
V = e_vec[:,np.array(ind)]
# sample a set of k items
sample = np.zeros(e_val.size,dtype=bool)
for l in range(k-1,-1,-1):
p = np.sum(V**2,axis=1)
p = np.cumsum(p / np.sum(p)) # item cumulative probabilities
i = int((np.random.rand() <= p).argmax()) # choose random item
sample[i] = True
j = (np.abs(V[i,:])>eps).argmax() # pick an eigenvector not orthogonal to e_i
Vj = V[:,j]
V = orth(V - (np.outer(Vj,(V[i,:]/Vj[i]))))
return sample
如果我打印 s 并且 tf.reshape(s)
的输出是
[False True True True True]
[5]
如果我打印 VT 并且 tf.reshape(VT)
的输出是
[[ 3. 1. 2. 4. 2.]
[ 4. 0. 1. 4. 1.]
[ 1. 1. 0. 4. 8.]
[ 1. 4. 2. 5. 2.]
[ 3. 2. 3. 2. 5.]]
[5 5]
非常感谢任何帮助。
以下示例适合我。
import tensorflow as tf
import numpy as np
tensor = [[1, 2], [3, 4], [5, 6]]
mask = np.array([True, False, True])
t_m = tf.boolean_mask(tensor, mask)
sess = tf.Session()
print(sess.run(t_m))
输出:
[[1 2]
[5 6]]
提供您的可运行代码片段以重现错误。我认为你可能在 s 中做错了什么。
更新:
s = tf.py_func(sample_dpp_bin,[e,v],tf.bool)
s_v = (s.eval())
X = tf.boolean_mask(VT,s_v)
print(X.eval())
mask 应该是 np 数组而不是 TF 张量。您不必使用 tf.pyfunc.
错误消息指出未定义遮罩的形状。如果你打印 tf.shape(s)
你会得到什么?我敢打赌你的代码的问题是 s
的形状是完全未知的,你可以通过像 s.set_shape((None))
这样的简单调用来解决这个问题(简单地指定 s
是一个一维张量)。考虑这个代码片段:
X = np.random.randint(0, 2, (100, 100, 3))
with tf.Session() as sess:
X_tf = tf.placeholder(tf.int8)
# X_tf.set_shape((None, None, None))
y = tf.greater(tf.reduce_max(X_tf, axis=(0, 1)), 0)
print(tf.shape(y))
z = tf.boolean_mask(X_tf, y, axis=2)
print(sess.run(z, feed_dict={X_tf: X}))
这会打印 Tensor("Shape_3:0", shape=(?,), dtype=int32)
的形状(即,甚至 y
的尺寸也是未知的)和 returns 与您遇到的错误相同。但是,如果取消注释 set_shape
行,则已知 X_tf
是 3 维的,因此 s
是 1 维的。代码然后工作。所以,我认为您需要做的就是在 py_func
调用之后添加一个 s.set_shape((None))
调用。