2017-10-09 23 views
7

Tôi đang cố gắng tạo mạng trong lưu lượng tensor với nhiều đầu ra softmax, mỗi đầu ra có kích thước khác nhau. Kiến trúc mạng là: Nhập -> LSTM -> Bỏ học. Sau đó, tôi có 2 lớp softmax: Softmax của 10 đầu ra và Softmax 20 đầu ra. Lý do cho điều này là bởi vì tôi muốn tạo ra hai bộ kết quả đầu ra (10 và 20), và sau đó kết hợp chúng để tạo ra một đầu ra cuối cùng. Tôi không chắc chắn làm thế nào để làm điều này trong Tensorflow.Làm thế nào để có nhiều đầu ra Softmax trong Tensorflow?

Trước đây, để tạo một mạng như mô tả, nhưng với một softmax, tôi nghĩ tôi có thể làm một cái gì đó như thế này.

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

Tuy nhiên, bây giờ, tôi muốn đầu ra RNN (sau khi bỏ học) chảy vào 2 lớp softmax, một kích thước 10 và kích thước khác 20. Có ai có ý tưởng về cách thực hiện việc này không?

Cảm ơn

Edit: Lý tưởng nhất là tôi muốn sử dụng một phiên bản của softmax như những gì được định nghĩa ở đây trong thư viện Knet Julia này. Tensorflow có tương đương không? https://github.com/denizyuret/Knet.jl/blob/1ef934cc58f9671f2d85063f88a3d6959a49d088/deprecated/src7/op/actf.jl#L103

+0

Tôi hiện có câu hỏi với một số vấn đề về kích thước, hãy xem câu hỏi tôi đã thêm làm nhận xét cho câu trả lời được chọn chính xác. – hockeybro

Trả lời

4

Bạn có thể làm như sau trên đầu ra của dynamic_rnn mà bạn gọi là output[0] để tính toán hai softmax và những tổn thất tương ứng:

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

Sau đó bạn có thể kết hợp hai lỗ nếu nó có liên quan để ứng dụng của bạn:

total_loss = loss_0 + loss_1 

EDIT để trả lời câu hỏi của bạn trong nhận xét về những gì y ou đặc biệt cần phải làm gì với hai kết quả đầu ra softmax: bạn có thể làm như sau xấp xỉ:

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

Bạn chỉ cần định nghĩa n, số cột của W1 và W2.

+0

Cảm ơn bạn đã trả lời. Điều gì xảy ra nếu tôi muốn mở rộng điều này, bằng cách nhân đầu ra của mỗi softmax với một ma trận khác, sau đó thêm các ma trận kết quả để có được kết quả cuối cùng của tôi, đó cũng là một ma trận. Tôi bối rối như thế nào tôi sẽ xử lý sự mất mát liên quan đến kết quả cuối cùng đó. Tôi có nên thực hiện các hoạt động của mình trên 'output_0' và' output_1', sau đó thêm kết quả không? Làm thế nào để tôi chắc chắn rằng tôi đang giảm thiểu tổn thất đó? Trong câu trả lời của bạn, bạn đang tính toán sự mất mát trên mỗi softmax với hai bộ nhãn ('nhãn [0]', '[nhãn [1]'), nhưng tôi chỉ có một nhãn đầu ra là kết quả cuối cùng. – hockeybro

+0

Cảm ơn sự giúp đỡ của bạn. Tôi có một câu hỏi liên quan, nhưng khác bây giờ. Tài liệu di động RNN cho Tensorflow nói rằng tensor đầu vào phải là một với hình dạng [batch_size x input_size]. Tuy nhiên, tôi có một cái có kích thước [batch_size x maxlength x features] vì tôi đang cố gắng hiểu một câu bằng cách chuyển từng từ một. Độ dài đại diện cho độ dài của câu dài nhất. Làm thế nào điều này sẽ làm việc trong trường hợp này, ngay bây giờ nó ném cho tôi một lỗi nói rằng tôi phải có thứ hạng 2? Nhúng là ma trận chuẩn có các đặc điểm kích thước x 256. Nó nằm trước LSTM. Mã của tôi là những gì tôi có trong OP. – hockeybro

5

Bạn không xác định nhật ký của mình cho lớp softmax có kích thước 10 trong mã của bạn và bạn sẽ phải làm điều đó một cách rõ ràng.

Khi đã hoàn tất, bạn có thể sử dụng tf.nn.softmax, áp dụng riêng biệt cho cả hai dây dẫn đăng nhập của bạn.

Ví dụ, đối với 20 lớp tensor softmax của bạn:

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

Đối với các lớp khác, bạn có thể làm:

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

Ngoài ra còn có một tf.contrib.layers.softmax cho phép bạn áp dụng các softmax trên trục cuối cùng của một tensor với lớn hơn 2 kích thước, nhưng nó không giống như bạn cần bất cứ điều gì như thế. tf.nn.softmax sẽ hoạt động ở đây.

Lưu ý phụ:output_layer không phải là tên lớn nhất cho danh sách đó - phải là thứ liên quan đến trọng số. Những trọng số và thiên vị (output_layer, output_bias) cũng không đại diện cho lớp đầu ra của mạng của bạn (vì điều đó sẽ đến từ bất kỳ điều gì bạn làm với các đầu ra softmax của bạn, phải không?). [Xin lỗi, không thể giúp bản thân mình.]

+0

Cảm ơn bạn đã trả lời. Tôi bây giờ bối rối như thế nào để xử lý sự mất mát liên quan đến các kết quả softmax như tôi không cố gắng để sản lượng này như là một kết quả mà là làm một số hoạt động với họ để tính toán kết quả thực tế. Xem nhận xét của tôi về câu trả lời khác, bạn có ý tưởng về cách thực hiện điều đó không? – hockeybro

+0

@MehtaiPhoneApps: Bạn có thể cung cấp thêm chi tiết về sự mất mát mà bạn muốn sử dụng không? Nói chung, bạn sẽ phải đại diện cho chức năng mất của bạn bằng cách sử dụng các ops TensorFlow và sử dụng [trình tối ưu hóa] (https://www.tensorflow.org/api_docs/python/tf/train/Optimizer) để giảm thiểu/tối đa hóa nó. –

+0

Ok, sau khi có hai lớp softmax như bạn có trong câu trả lời, tôi có thể nhân một lớp với ma trận, một lớp khác bằng vectơ trọng lượng bằng cách sử dụng thao tác (W * x), và sau đó tôi có 2 kết quả đầu ra là 'dự đoán_1' và 'dự đoán_2'. Tôi có thể thêm các ma trận này để có được kết quả cuối cùng, 'dự đoán'. Sau đó, tôi sẽ sử dụng một hàm mất trên này, như sau: '' 'loss = tf.reduce_mean (tf.squared_difference (dự đoán, nhãn))' ''. Tôi tò mò, sẽ làm điều này trở lại tuyên truyền gradients một cách chính xác, thậm chí thông qua softmax, vì tôi không sử dụng sự mất mát trên softmax trực tiếp. – hockeybro

Các vấn đề liên quan