Python Tensorflow:链接tf.gather()会产生IndexedLices警告

Python Tensorflow:链接tf.gather()会产生IndexedLices警告,python,neural-network,tensorflow,Python,Neural Network,Tensorflow,我遇到了一个问题,链接tf.gather()索引会产生以下警告: /usr/local/lib/python3.5/dist-packages/tensorflow/python/ops/gradients.py:90: UserWarning: Converting sparse IndexedSlices to a dense Tensor of unknown shape. This may consume a large amount of memory. "C

我遇到了一个问题,链接
tf.gather()
索引会产生以下警告:

/usr/local/lib/python3.5/dist-packages/tensorflow/python/ops/gradients.py:90: UserWarning: Converting sparse IndexedSlices to a dense Tensor of unknown shape. This may consume a large amount of memory.           
  "Converting sparse IndexedSlices to a dense Tensor of unknown shape. "
当一层索引到输入层,对相应的切片执行一些操作,然后下一层索引到结果中时,就会出现这种情况。以下是一个具有代表性的例子:

import tensorflow as tf

## 10-Dimensional data will be fed to the model
X = tf.placeholder( tf.float32, [10, None] )

## W works with the first 3 features of a sample
W = tf.Variable( tf.ones( [5, 3] ) )
Xi = tf.gather( X, [0,1,2] )
mm = tf.matmul( W, Xi )

## Indexing into the result produces a warning during backprop
h = tf.gather( mm, [0,1] )
...
train_step = tf.train.AdamOptimizer(1e-4).minimize( loss )
定义
train_step
时会出现警告,如果第二个
tf.gather()
调用被取消,警告就会消失。如果
X
提供了明确数量的样本(例如
[10,1000]
),则警告也会消失

想法?

tf.gather操作的梯度返回
indexedlices
类型值。在您的程序中,第二个
tf.gather
的输入是
tf.matmul
mm
)的结果。因此,矩阵乘法的梯度函数被传递一个
indexedlices

现在,想象一下
tf.matmul
的梯度函数需要做什么。要计算梯度w.r.t
w
,它必须将传入梯度乘以
Xi
的转置。在这种情况下,传入梯度是一种
indexedlices
类型,而
Xi
的转置是一种密集张量(
张量
)类型。TensorFlow没有一个矩阵乘法的实现,它可以在
indexedlices
Tensor
上运行。因此,在调用
tf.matmul
之前,它只需将
indexedlices
转换为
Tensor

如果查看该转换函数的代码,您会注意到,当此稀疏到密集转换可能导致非常大的密集张量(
\u large\u sparse\u NUM\u ELEMENTS
确定大小)或未知大小的密集张量时,它会输出一条警告。当您使用shape
[10,None]
塑造占位符
X
时,此转换发生在形状未知的
索引图标上(实际上,只有一个维度未知,但仍然无法静态确定结果形状),因此您会看到打印出来的警告。将
X
的形状设置为
[10,1000]
后,
索引图标的形状将完全指定,并且生成的密集张量大小在阈值范围内,因此您不会看到打印出来的警告


对于您的计算,如果您无法避免对
tf.matmul
的结果执行
tf.gather
,那么我会非常担心这个警告,除非
X
中的列数非常大。

谢谢。这是有道理的。实际上,我可以将代码重新构造为使用
tf.dynamic_partition()
而不是
tf.gather()
,这不仅避免了警告,而且有助于更干净的实现。@ArtemSokolov请与dynamic_partition共享您的解决方案好吗?