2017-04-04 67 views
2

我想加載以前保存的TENSOFLOW模型(圖形和變量)。Tenorflow加載模型錯誤

以下是我的訓練

tf.global_variables_initializer().run() 
y = tf.matmul(x, W) + b 

cross_entropy = tf.reduce_mean(
    tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y)) 
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy) 

for batch_index in range(batch_size): 
    batch_xs, batch_ys = sample_dataframe(train_df, N=batch_size) 
    #print(batch_xs.shape) 
    #print(batch_ys.shape) 
    sess.run(train_step, feed_dict = {x: batch_xs, y_:batch_ys}) 

    if batch_index % 100 == 0: 
     print("Batch "+str(batch_index)) 
     correct_predictions = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1)) 
     accuracy = tf.reduce_mean(tf.cast(correct_predictions, tf.float32)) 
     print("Accuracy: "+str(sess.run(accuracy, 
                feed_dict = {x: batch_xs, y_: batch_ys}))) 
     #print("Predictions "+str(y)) 
     #print("Training accuracy: %.1f%%" %accuracy()) 
    if batch_index + 1 == batch_size: 
     #Save the trained model 
     print("Exporting trained model") 
     builder = saved_model_builder.SavedModelBuilder(EXPORT_DIR) 
     builder.add_meta_graph_and_variables(sess, ['simple-MNIST']) 
     builder.save(as_text=True) 

請忽略如何模型定義(這只是一個玩具爲例),並檢查只在被調用保存方法的最後幾行中導出的模型。一切都很順利,模型正確保存在FS中。

當我嘗試LO加載導出模型,我總是得到以下錯誤:

TypeError: Can not convert a MetaGraphDef into a Tensor or Operation.

下面是我加載模型:

with tf.Session() as sess: 
    print(tf.saved_model.loader.maybe_saved_model_directory(export_dir)) 
    saved_model = tf.saved_model.loader.load(sess, ['simple-MNIST'], export_dir) 

    sess.run(saved_model) 

任何想法如何解決呢?看來該模型已經以錯誤的格式導出,但我無法弄清楚如何改變它。

下面是一個用於加載模型並對其進行評分的簡單腳本。

with tf.device("/cpu:0"): 
    x = tf.placeholder(tf.float32, shape =(batch_size, 784)) 
    W = tf.Variable(tf.truncated_normal(shape=(784, 10), stddev=0.1)) 
    b = tf.Variable(tf.zeros([10])) 
    y_ = tf.placeholder(tf.float32, shape=(batch_size, 10)) 

with tf.Session() as sess: 
    tf.global_variables_initializer().run() 

    print(tf.saved_model.loader.maybe_saved_model_directory(export_dir)) 
    saved_model = tf.saved_model.loader.load(sess, ['simple-MNIST'], export_dir) 

    batch_xs, batch_ys = sample_dataframe(train_df, N=batch_size) 
    y = tf.matmul(x, W) + b 
    correct_predictions = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1)) 
    accuracy = tf.reduce_mean(tf.cast(correct_predictions, tf.float32))  

print("Test Accuracy: "+ str(sess.run(accuracy, feed_dict = {x: batch_xs, y_: batch_ys}))) 

運行在一個全新的PYTHON背景下,這個腳本,將比分以非常低精度模型(似乎負荷模型方法還沒有正確設置圖形變量)

謝謝!

回答

2

我認爲問題是,你不能傳遞到saved_modelsess.run。從saved_model.loader.load文檔:

Returns: The MetaGraphDef protocol buffer loaded in the provided session. This can be used to further extract signature-defs, collection-defs, etc.

那麼,到底你會從sess.run(saved_model)期望時saved_modelMetaGraphDef?如果我已經正確理解load的機制,那麼圖表以及相關變量將在您傳遞給load(..)的會話中恢復,因此您的模型在完成load(..)後即可使用。因此,您應該可以像往常一樣通過(默認)圖來訪問變量,操作和張量,並且不需要進一步處理返回的對象MetaGraphDef

這裏是關於什麼MetaGraphDef是詳細信息:What is the TensorFlow checkpoint meta file?。由此可見,與sess.run()一起使用它是沒有意義的。

編輯

跟進您的編輯:功能tf.saved_model.loader.load內部調用其次是saver.restoretf.import_meta_graph,即它恢復,曲線圖存在於圖中的變量的值。因此,在您添加的代碼片段開始時,您不必自己重新定義變量。事實上,它可能會導致未定義的行爲,因爲某些節點可能會在默認圖中存在兩次。檢查這個stackoverflow後的更多信息:Restoring Tensorflow model and viewing variable value。所以我猜這裏發生的是:推理步驟使用您手動創建的未經訓練的變量W,而不是您通過saved_model.loader加載的預訓練變量,這就是爲什麼您看到精度低的原因。

所以,我的猜測是,如果你省略開始的xWby_的定義和恢復的圖形檢索它們例如通過調用tf.get_default_graph().get_tensor_by_name('variable_name'))它應該工作正常。

PS:如果要還原的模型是沒有必要運行初始化(雖然我認爲它不會傷害任何)。

PPS:在你的腳本,你正在計算「手」的準確性,但我認爲這種操作已經存在於模型,因爲它是在訓練中最有可能需要爲好,不是嗎?因此,不需要再次手工計算精度,您可以從圖中取出相應的節點並使用它。

+0

謝謝您的回答。我認爲你是對的,但我仍然在努力尋找解決方案。 我試圖模型加載到一個單獨的筆記本電腦,但這些變量似乎未初始化(我也HADO到redifined他們爲了使代碼的功能)。 如果我在相同的上下文(本例中爲筆記本)中加載模型,則模型會正確記錄新條目,但不會在我嘗試將其加載到全新筆記本中時得到新條目。 – luke035

+0

一旦加載模型,您想如何處理(繼續訓練,用它進行推理,檢索一些特定的變量/張量...)? – kaufmanu

+0

我想用它來推理新條目。當我保存模型時,我認爲它是完整的。再次感謝你! – luke035