Как иметь несколько выходов Softmax в Tensorflow?

Я пытаюсь создать сеть в тензорном потоке с несколькими выходами softmax, каждый разного размера. Архитектура сети: Вход - > LSTM - > отсев. Затем у меня есть 2 слоя softmax: Softmax 10 выходов и Softmax 20 выходов. Причина этого в том, что я хочу создать два набора выходов (10 и 20), а затем объединить их для создания конечной продукции. Я не уверен, как это сделать в Tensorflow.

раньше, чтобы сделать сеть, как описано, но с один softmax, я думаю, что могу сделать что-то вроде этого.

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 слоя softmax, один размером 10 и другой размером 20. Кто-нибудь знает, как это сделать?

спасибо

Edit: в идеале я хотел бы использовать версию softmax, такую как то, что определено здесь, в этой библиотеке Knet Julia. Имеет ли Tensorflow эквивалент? https://github.com/denizyuret/Knet.jl/blob/1ef934cc58f9671f2d85063f88a3d6959a49d088/deprecated/src7/op/actf.jl#L103

2 ответов


вы можете сделать следующее На выходе dynamic_rnn что вы назвали output[0] для вычисления двух softmax и соответствующих потерь:

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]))

затем вы можете объединить две потери, если это имеет отношение к вашему приложению:

total_loss = loss_0 + loss_1

редактировать Чтобы ответить на ваш вопрос в комментариях о том, что вам конкретно нужно сделать с двумя выходами softmax: вы можете сделать следующее Примерно:

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.


вы не определяете свои логиты для слоя softmax размера 10 в своем коде, и вам придется сделать это явно.

как только это будет сделано, вы можете использовать tf.НН.softmax, применяя его отдельно к обоим тензорам logit.

например, для вашего тензора 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.ВНО.слои.softmax что позволяет примените softmax на конечной оси тензора с размерами больше 2, но не похоже, что вам нужно что-то подобное. tf.НН.softmax должны работать здесь.

Примечание: output_layer не самое большое имя для этого списка-должно быть что-то, связанное с весами. Эти веса и предубеждения (output_layer, output_bias) также не представляют выходной слой вашей сети (как это будет происходить от того, что вы делаете с выходами softmax, верно?). - "Прости, не смог удержаться.]