2016-03-09 24 views
30

は、私は最近のモデルを実装し、私はそれを実行したとき、私はこの警告受け取っ:いくつかの同様のパラメータ設定(埋め込むの次元)でテンソルフローの高密度グラジエントの説明?

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. " 

突然のモデルはとてつもなく遅いのですが。

  1. この警告は何を意味しますか?私がやったことは、すべてのグラデーションが密集してしまったため、バックプロップが密行列計算を実行しているようです。
  2. これが原因でモデルに問題がある場合は、 ?

答えて

10

高密度のTensorは標準のPython配列のように考えることができます。疎なものは、インデックスおよび値の集合として考えることができる。

# dense 
array = ['a', None, None, 'c'] 

# sparse 
array = [(0, 'a'), (3, 'c')] 

あなたはスパース配列は、はるかに効率的に密なものとはなり空のエントリの多くを持っている場合あなたが見ることができるようになっています。しかし、すべてのエントリが埋まっていれば、密集がはるかに効率的です。あなたのケースでは、テンソルフローグラフのどこかで、疎な配列が不定サイズの密なものに変換されています。警告はちょうどあなたがこのような多くのメモリを無駄にする可能性があるということです。しかし、疎な配列があまりにも大きすぎない/すでにかなり密でなければ、まったく問題にならないかもしれません。

診断したい場合は、さまざまなテンソルオブジェクトに名前を付けることをお勧めします。この変換で使用されているものを正確に印刷し、調整することができるものを見つけ出すことができます。

29

この警告は、疎のtf.IndexedSlicesオブジェクトが暗黙的に高密度のtf.Tensorに変換された場合に表示されます。これは通常、1つの演算子(通常tf.gather())がスパース勾配を逆伝播するが、それを受け取る演算子には疎な勾配を扱う特殊な勾配関数がないときに発生する。その結果、TensorFlowは自動的にtf.IndexedSlicesを稠密化します。これは、テンソルが大きい場合にパフォーマンスに壊滅的な影響を及ぼす可能性があります。この問題を解決するには

、あなたはtf.gather()からparams入力(またはtf.nn.embedding_lookup()からparams入力は)tf.Variableであることを確認してみてください。変数は疎な更新を直接受け取ることができるので、変換は必要ありません。 tf.gather()(およびtf.nn.embedding_lookup())は任意のテンソルを入力として受け取りますが、これはバックプロパゲーショングラフがより複雑になり、暗黙的な変換が行われる可能性があります。

+1

ありがとうございます。これを引き起こしているオペアンプを特定するにはどうすればよいですか? – Taaam

+2

最も簡単な方法は、コードで 'tf.gather()'または 'tf.nn 'を調べることです。embedding_lookup() '呼び出しを実行し、それらのoppsの' params'(最初の)引数であるテンソル 't'を見つけ、' t.op'を出力します。一般に、 't'が' tf.Variable'であれば最高のパフォーマンスを得ますが、 'tf.concat()'のようないくつかのオプションではグラデーションを効率的にする特殊化があります。 – mrry

+2

'reshape'を与えられた' boolean_mask'のようです。これは、複数の 'reshape'、' pack's、 'tile's、' expand_dim's、 'squeeze's、' batch_matmul'sなどのグラフの中の損失計算に使用されます。どのopが疎なグラデーションを受け入れることができないのかを特定する – Taaam

5

完全に答えはmrryです。

実際に私はこの問題の別の解決策を掲載します。

tf.gather()の代わりにtf.dynamic_partition()を使用して、警告を排除することができます。

のコード例は以下の通りです:

# Create the cells for the RNN network 
lstm = tf.nn.rnn_cell.BasicLSTMCell(128) 

# Get the output and state from dynamic rnn 
output, state = tf.nn.dynamic_rnn(lstm, sequence, dtype=tf.float32, sequence_length = seqlen) 

# Convert output to a tessor and reshape it 
outputs = tf.reshape(tf.pack(output), [-1, lstm.output_size]) 

# Set partions to 2 
num_partitions = 2 

# The partitions argument is a tensor which is already fed to a placeholder. 
# It is a 1-D tensor with the length of batch_size * max_sequence_length. 
# In this partitions tensor, you need to set the last output idx for each seq to 1 and 
# others remain 0, so that the result could be separated to two parts, 
# one is the last outputs and the other one is the non-last outputs. 
res_out = tf.dynamic_partition(outputs, partitions, num_partitions) 

# prediction 
preds = tf.matmul(res_out[1], weights) + bias 

が、これはあなたを助けることができる願っています。