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

时间:2016-08-23 22:02:59

标签: 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.           
  "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]),则警告也会消失。

思想?

1 个答案:

答案 0 :(得分:7)

tf.gather操作的渐变function会返回IndexedSlices类型的值。在您的计划中,输入第二个tf.gathertf.matmulmm)的结果。因此,矩阵乘法的梯度函数传递IndexedSlices值。

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

如果你查看转换函数here的代码,你会注意到当这种稀疏到密集的转换可能导致一个非常大的密集张量时会打印出警告(_LARGE_SPARSE_NUM_ELEMENTS确定有多大)或未知大小的密集张量。当您使用形状X整形占位符[10, None]时,此转换发生在形状未知的IndexedSlices上(实际上,只有一个维度未知,但仍无法确定结果形状静止),因此你看到打印出来的警告。将X的形状设置为[10, 1000]后,IndexedSlices的形状将完全指定, AND 生成的密集张量大小在阈值范围内,因此您看不到打印出的警告。

对于您的计算,如果您根本无法避免tf.gather的结果tf.matmul,那么我会过多地担心此警告,除非X中的列数非常大。