2017-10-13 3 views
1

Ich hatte ein Problem mit der korrekten Wiederherstellung des gespeicherten Modells in Tensorflow. Ich habe die Bidirektionale RNN-Modell in tensorflow mit folgendem Code:So stellen Sie das gespeicherte BiRNN-Modell in Tensorflow wieder her, so dass alle Ausgabe-Neuronen korrekt zu den entsprechenden Ausgabeklassen gebündelt wurden

batchX_placeholder = tf.placeholder(tf.float32, [None, timesteps, 1], 
            name="batchX_placeholder")]) 
batchY_placeholder = tf.placeholder(tf.float32, [None, num_classes], 
            name="batchY_placeholder") 
weights = tf.Variable(np.random.rand(2*STATE_SIZE, num_classes), 
         dtype=tf.float32, name="weights") 
biases = tf.Variable(np.zeros((1, num_classes)), dtype=tf.float32, 
        name="biases") 
logits = BiRNN(batchX_placeholder, weights, biases) 
with tf.name_scope("prediction"): 
    prediction = tf.nn.softmax(logits) 
loss_op = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(
logits=logits, labels=batchY_placeholder)) 
lr = tf.Variable(learning_rate, trainable=False, dtype=tf.float32, 
       name='lr') 
optimizer = tf.train.AdamOptimizer(learning_rate=lr) 
train_op = optimizer.minimize(loss_op) 
init_op = tf.initialize_all_variables() 
saver = tf.train.Saver() 

Die Architektur von BiRNN mit der folgenden Funktion erstellt:

def BiRNN(x, weights, biases): 
    # Unstack to get a list of 'time_steps' tensors of shape (batch_size, 
    # num_input) 
    x = tf.unstack(x, time_steps, 1) 
    # Forward and Backward direction cells 
    lstm_fw_cell = rnn.BasicLSTMCell(STATE_SIZE, forget_bias=1.0) 
    lstm_bw_cell = rnn.BasicLSTMCell(STATE_SIZE, forget_bias=1.0) 
    outputs, _, _ = rnn.static_bidirectional_rnn(lstm_fw_cell, 
     lstm_bw_cell, x, dtype=tf.float32) 
    # Linear activation, using rnn inner loop last output 
    return tf.matmul(outputs[-1], weights) + biases 

Dann habe ich ein Modell trainieren und es nach jeweils 200 Stufen sparen:

with tf.Session() as sess: 
    sess.run(init_op) 
    current_step = 0 
    for batch_x, batch_y in get_minibatch(): 
     sess.run(train_op, feed_dict={batchX_placeholder: batch_x, 
             batchY_placeholder: batch_y}) 
     current_step += 1 
     if current_step % 200 == 0: 
      saver.save(sess, os.path.join(model_dir, "model") 

Um das gespeicherte Modell in Inferenz-Modus laufen I tensorflow graph in "model.meta" Datei Verwendung gespeichert:

graph = tf.get_default_graph() 
saver = tf.train.import_meta_graph(os.path.join(model_dir, "model.meta")) 
sess = tf.Session() 
saver.restore(sess, tf.train.latest_checkpoint(model_dir) 
weights = graph.get_tensor_by_name("weights:0") 
biases = graph.get_tensor_by_name("biases:0") 
batchX_placeholder = graph.get_tensor_by_name("batchX_placeholder:0") 
batchY_placeholder = graph.get_tensor_by_name("batchY_placeholder:0") 
logits = BiRNN(batchX_placeholder, weights, biases) 
prediction = graph.get_operation_by_name("prediction/Softmax") 
argmax_pred = tf.argmax(prediction, 1) 
init = tf.global_variables_initializer() 
sess.run(init) 
for x_seq, y_gt in get_sequence(): 
    _, y_pred = sess.run([prediction, argmax_pred], 
        feed_dict={batchX_placeholder: [x_seq]], 
           batchY_placeholder: [[0.0, 0.0]]}) 
    print("Y ground true: " + str(y_gt) + ", Y pred: " + str(y_pred[0])) 

Und wenn ich den Code im Inferenz-Modus ausführen, bekomme ich jedes Mal, wenn ich es starte, unterschiedliche Ergebnisse. Es scheint, dass Ausgabe-Neuronen von der Softmax-Schicht zufällig mit verschiedenen Ausgabeklassen gebündelt sind.

Also, meine Frage ist: Wie kann ich das Modell in Tensorflow speichern und dann korrekt wiederherstellen, so dass alle Neuronen ordnungsgemäß mit entsprechenden Ausgabeklassen gebündelt?

Antwort

2

Es gibt keine Notwendigkeit zu rufen tf.global_variables_initializer(), ich denke, das ist dein Problem.

Ich entfernte einige Operationen: logits, weights und biases, da Sie sie nicht benötigen, sind, graph.get_tensor_by_name verwenden alle bereits geladen, sie zu erhalten.

Für die prediction, erhalten die Tensor anstelle des Betrieb. (Siehe diese answer):

Dies ist der Code:

graph = tf.get_default_graph() 
saver = tf.train.import_meta_graph(os.path.join(model_dir, "model.meta")) 
sess = tf.Session() 
saver.restore(sess, tf.train.latest_checkpoint(model_dir)) 

batchX_placeholder = graph.get_tensor_by_name("batchX_placeholder:0") 
batchY_placeholder = graph.get_tensor_by_name("batchY_placeholder:0") 
prediction = graph.get_tensor_by_name("prediction/Softmax:0") 
argmax_pred = tf.argmax(prediction, 1) 

Edit 1: Ich merke, dass ich war nicht klar, warum Sie unterschiedliche Ergebnisse bekommen.

Und wenn ich den Code im Inferenz-Modus ausführen, bekomme ich jedes Mal, wenn ich es starte, unterschiedliche Ergebnisse .

Beachten Sie, dass obwohl Sie die Gewichte aus dem geladenen Modell verwendet, können Sie die BiRNN wieder schaffen, und die BasicLSTMCell haben auch Gewichte und andere Variablen, die Sie nicht von Ihrem geladenen Modell festgelegt, daher müssen sie sein initialisiert (mit neuen Zufallswerten), was wiederum zu einem untrainierten Modell führt.

Verwandte Themen