web-dev-qa-db-ja.com

Tensorflow RNNで埋め込みレイヤーを構築するにはどうすればよいですか?

私は、作家の年齢に基づいてテキストを分類するためのRNN LSTMネットワークを構築しています(二項分類-若い/大人)。

ネットワークが学習せず、突然過剰適合を開始したようです。

rnn_overfitting
赤:電車
青:検証

1つの可能性は、データ表現が十分ではない可能性があります。ユニークな単語を頻度で並べ替えて、インデックスを付けました。例えば。:

unknown -> 0
the     -> 1
a       -> 2
.       -> 3
to      -> 4

だから私はそれをWordの埋め込みに置き換えようとしています。いくつかの例を見ましたが、コードに実装できません。ほとんどの例は次のようになります。

embedding = tf.Variable(tf.random_uniform([vocab_size, hidden_size], -1, 1))
inputs = tf.nn.embedding_lookup(embedding, input_data)

これは、埋め込みを学習するレイヤーを構築していることを意味しますか? Word2VecまたはGloveをダウンロードして、それを使用する必要があると思いました。

とにかく、この埋め込みレイヤーを構築したいとしましょう...
コードで次の2行を使用すると、エラーが発生します。

TypeError:パラメーター 'indices'に渡された値のDataTypefloat32が、許可された値のリストにありません:int32、int64

したがって、input_dataタイプをint32に変更する必要があると思います。だから私はそれをします(結局のところそれはすべてのインデックスです)、そして私はこれを手に入れます:

TypeError:入力はシーケンスである必要があります

この回答 で提案されているように、inputstf.contrib.rnn.static_rnnへの引数)をリスト:[inputs]でラップしようとしましたが、別のエラーが発生しました:

ValueError:入力サイズ(入力の次元0)は、形状推論を介してアクセス可能である必要がありますが、値はありません。


更新:

テンソルをembedding_lookupに渡す前に、テンソルxをアンスタックしていました。埋め込み後にアンスタックを移動しました。

更新されたコード:

MIN_TOKENS = 10
MAX_TOKENS = 30
x = tf.placeholder("int32", [None, MAX_TOKENS, 1])
y = tf.placeholder("float", [None, N_CLASSES]) # 0.0 / 1.0
...
seqlen = tf.placeholder(tf.int32, [None]) #list of each sequence length*
embedding = tf.Variable(tf.random_uniform([VOCAB_SIZE, HIDDEN_SIZE], -1, 1))
inputs = tf.nn.embedding_lookup(embedding, x) #x is the text after converting to indices
inputs = tf.unstack(inputs, MAX_POST_LENGTH, 1)
outputs, states = tf.contrib.rnn.static_rnn(lstm_cell, inputs, dtype=tf.float32, sequence_length=seqlen) #---> Produces error

*seqlen:シーケンスをゼロパディングして、すべてのリストサイズが同じになるようにしましたが、実際のサイズが異なるため、パディングなしで長さを説明するリストを作成しました。

新しいエラー:

ValueError:レイヤーbasic_lstm_cell_1の入力0はレイヤーと互換性がありません:予期されるndim = 2、見つかったndim = 3。受け取ったフルシェイプ:[なし、1、64]

64は各非表示レイヤーのサイズです。

寸法に問題があることは明らかです...埋め込み後に入力をネットワークに適合させるにはどうすればよいですか?

9
Alaa M.

tf.nn.static_rnn から、inputs引数は次のようになります。

入力の長さTのリスト、それぞれが形状のテンソル[batch_size、input_size]

したがって、コードは次のようになります。

x = tf.placeholder("int32", [None, MAX_TOKENS])
...
inputs = tf.unstack(inputs, axis=1)
4
vijay m

tf.squeeze は、テンソルからサイズ1の次元を削除するメソッドです。最終目標が入力形状を[None、64]にすることである場合は、inputs = tf.squeeze(inputs)のような行を配置すると、問題が解決します。

1