2017-10-09 11 views
7

私はテンソルフローで、それぞれが異なるサイズの複数のsoftmax出力を持つネットワークを作成しようとしています。ネットワークのアーキテクチャは、 入力 - > LSTM - >ドロップアウトです。それから私は2つのソフトマックスレイヤーを持っています:10の出力のソフトマックスと20の出力のソフトマックス。これは、2組の出力(10と20)を生成し、それらを結合して最終出力を生成したいからです。私はTensorflowでこれを行う方法がわかりません。Tensorflowで複数のSoftmax出力を使用するには?

これまで説明したようなネットワークを作成するには、softmaxが1つしかないと思うので、このようなことができると思います。

inputs = tf.placeholder(tf.float32, [batch_size, maxlength, vocabsize]) 
lengths = tf.placeholders(tf.int32, [batch_size]) 
embeddings = tf.Variable(tf.random_uniform([vocabsize, 256], -1, 1)) 
lstm = {} 
lstm[0] = tf.contrib.rnn.LSTMCell(hidden_layer_size, state_is_tuple=True, initializer=tf.contrib.layers.xavier_initializer(seed=random_seed)) 
lstm[0] = tf.contrib.rnn.DropoutWrapper(lstm[0], output_keep_prob=0.5) 
lstm[0] = tf.contrib.rnn.MultiRNNCell(cells=[lstm[0]] * 1, state_is_tuple=True) 
output_layer = {} 
output_layer[0] = Layer.W(1 * hidden_layer_size, 20, 'OutputLayer') 
output_bias = {} 
output_bias[0] = Layer.b(20, 'OutputBias') 
outputs = {} 
fstate = {} 
with tf.variable_scope("lstm0"): 
    # create the rnn graph at run time 
    outputs[0], fstate[0] = tf.nn.dynamic_rnn(lstm[0], tf.nn.embedding_lookup(embeddings, inputs), 
             sequence_length=lengths, 
             dtype=tf.float32) 
logits = {} 
logits[0] = tf.matmul(tf.concat([f.h for f in fstate[0]], 1), output_layer[0]) + output_bias[0] 
loss = {} 
loss[0] = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits[0], labels=labels[0])) 

しかし、今、私は(ドロップアウト後)私のRNNの出力が2つのソフトマックス層に流入したい、サイズ10とサイズ20の別の1誰もがこれを行う方法のアイデアを持っていますか?

おかげ

編集:理想的には私は、このようなこのKnetジュリアライブラリにここで定義されているものとして、ソフトマックスのバージョンを使用したいと思います。 Tensorflowには同等の機能がありますか? https://github.com/denizyuret/Knet.jl/blob/1ef934cc58f9671f2d85063f88a3d6959a49d088/deprecated/src7/op/actf.jl#L103

+0

私は現在、いくつかのサイズの問題について質問していますが、正しく選択された回答にコメントとして追加した質問を参照してください。 – hockeybro

答えて

4

あなたは2つのソフトマックス、対応する損失を計算するためにoutput[0]と呼ばdynamic_rnnの出力に次の操作を行うことができます

with tf.variable_scope("softmax_0"): 
    # Transform you RNN output to the right output size = 10 
    W = tf.get_variable("kernel_0", [output[0].get_shape()[1], 10]) 
    logits_0 = tf.matmul(inputs, W) 
    # Apply the softmax function to the logits (of size 10) 
    output_0 = tf.nn.softmax(logits_0, name = "softmax_0") 
    # Compute the loss (as you did in your question) with softmax_cross_entropy_with_logits directly applied on logits 
    loss_0 = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits_0, labels=labels[0])) 

with tf.variable_scope("softmax_1"): 
    # Transform you RNN output to the right output size = 20 
    W = tf.get_variable("kernel_1", [output[0].get_shape()[1], 20]) 
    logits_1 = tf.matmul(inputs, W) 
    # Apply the softmax function to the logits (of size 20) 
    output_1 = tf.nn.softmax(logits_1, name = "softmax_1") 
    # Compute the loss (as you did in your question) with softmax_cross_entropy_with_logits directly applied on logits 
    loss_1 = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits_1, labels=labels[1])) 

それが関連している場合は、2つの損失を組み合わせることができます何のyについてのコメントで、あなたの質問に答えるために

total_loss = loss_0 + loss_1 

EDIT :アプリケーションへOUは、特に2つのソフトマックスの出力を実行する必要があります。あなたは、およそ次の操作を行うことができます。

with tf.variable_scope("second_part"): 
    W1 = tf.get_variable("W_1", [output_1.get_shape()[1], n]) 
    W2 = tf.get_variable("W_2", [output_2.get_shape()[1], n]) 
    prediction = tf.matmul(output_1, W1) + tf.matmul(output_2, W2) 
with tf.variable_scope("optimization_part"): 
    loss = tf.reduce_mean(tf.squared_difference(prediction, label)) 

あなたは、定義されたnにW1とW2の列数を必要とします。

+0

お返事ありがとうございます。これを拡張したいのであれば、各softmaxの出力に別の行列を掛けて、最終的な出力を得るために結果の行列を加算します。これも行列です。私は最終的な成果に関してどのように損失を処理するのか混乱しています。 'output_0'と' output_1'で操作して、結果を追加するだけでいいですか?私はその損失を最小限に抑えるためにどうすればよいでしょうか?あなたの答えでは、2つのラベルセット( 'labels [0]'、 '[labels [1]')を使って各softmaxの損失を計算していますが、最終結果である出力ラベルは1つのみです。 – hockeybro

+0

ご協力ありがとうございます。私は今、関連しているが異なる質問をしている。 TensorflowのRNNセルのドキュメントでは、入力テンソルは形状[batch_size x input_size]のものでなければならないと述べています。しかし、私は文章を一つずつ通して理解しようとしているので、サイズ[batch_size x maxlength x features]のものがあります。 Maxlengthは、最長の文章の長さを表します。このケースではこれはどのように機能しますか?今はランク2にする必要があるというエラーが表示されます。埋め込みは、サイズフィーチャx 256の標準マトリックスです。LSTMの前です。私のコードは私がOPで持っているものです。 – hockeybro

5

あなたのコードでは、サイズ10のsoftmaxレイヤーのログを定義していないので、明示的にそれを行う必要があります。

これが完了したら、tf.nn.softmaxを使用して、両方のロジットテンソルに別々に適用することができます。例えば

、あなたの20クラスのソフトマックステンソルのために:他の層には

softmax20 = tf.nn.softmax(logits[0]) 

、あなたができる:

output_layer[1] = Layer.W(1 * hidden_layer_size, 10, 'OutputLayer10') 
output_bias[1] = Layer.b(10, 'OutputBias10') 

logits[1] = tf.matmul(tf.concat([f.h for f in fstate[0]], 1), 
output_layer[1]) + output_bias[1] 

softmax10 = tf.nn.softmax(logits[1]) 

あなたはソフトマックスを適用することができますtf.contrib.layers.softmaxもあります2次元以上のテンソルの最終軸上にありますが、そのようなものは必要ないように見えます。 tf.nn.softmaxはここで動作します。

サイドノート:output_layerは、そのリストの最大の名前ではありません。重みを含むものである必要があります。これらの重みと偏り(output_layeroutput_bias)も、ネットワークの出力レイヤーを表すものではありません(あなたのsoftmax出力に何をしているのでしょうか?)。 [申し訳ありません、自分自身を助けることができませんでした。]

+0

お返事ありがとうございます。私は結果としてこれらを出力しようとしているのではなく、それらと実際の結果を計算するためにいくつかの操作を行うので、これらのsoftmaxの結果に関する損失をどのように処理するかについて今混乱しています。他の答えに私のコメントを参照してください、あなたはそれを行う方法のアイデアはありますか? – hockeybro

+0

@MehtaiPhoneApps:あなたが使用したいと思っている損失の詳細を教えていただけますか?一般的には、TensorFlowオペレーションを使って損失関数を表現し、[オプティマイザ](https://www.tensorflow.org/api_docs/python/tf/train/Optimizer)を使用して最小化/最大化します。 –

+0

あなたが答えているような2つのsoftmaxレイヤーを持っていたら、そのうちの1つに行列を掛けて、もう1つに(W * x)演算を使ったウェイトベクトルを掛けて、次に2つの出力に 'prediction_1'と 'prediction_2'です。これらの行列を追加して最終的な出力を得ることができます。それから、私はこれのように損失関数を使います: '' 'loss = tf.reduce_mean(tf.squared_difference(prediction、label))' ''。私は好奇心を持っています。ソフトマックスで損失を直接使用しないので、ソフトマックスを通しても、グラデーションを正確に伝播させることができます。 – hockeybro

関連する問題