2016-11-05 70 views
3

儘管這裏有很多問題提出了重複使用經過訓練的tensorflow模型的問題,但使用最主流的模型Inception-v3罰款仍然是一個挑戰調整自定義數據集以僅預測某個單一圖像的概率。使用微調的Inception-v3模型來預測單個圖像

在對這個話題做了一些研究之後(最相似的SO-thread肯定是Tensorflow: restoring a graph and model then running evaluation on a single image)我可以得出結論,有一些訓練有素的模型的凍結graph.pb文件就像有一個聖盃,因爲你沒有需要重建圖形,選擇要恢復的張量或其他 - 只需撥打tf.import_graph_def並通過sess.graph.get_tensor_by_name獲取所需的輸出圖層。

但問題是,配備tensorflow(如classify_image.py),這樣的«凍結圖»例子的有精心準備的輸入和輸出點像DecodeJpeg/contents:0softmax:0分別在那裏你可以養活你的自定義圖像,並檢索答案來自於,而您在使用自定義微調模型時沒有這樣好的切入點。

例如,微調啓-V3模型冷凍圖表將收到實際卷積層張量的FIFOQueueQueueDequeueMany和類似的打讀取來自TFRecord的與輸出張量將看起來像tower_0/logits/predictions與不可用的形狀含有批量大小批次,所以你只是沒有適當的點來提供一個新的JPEG圖像,並得到預測。

是否有任何成功的故事報道這種批量饋送的微調模型與新圖像的使用?或者,也許有關於將TFRecord/batch節點的輸入包更改爲JPEG的想法?

P.S.還有一種替代方式可以運行預訓練模型,比如TF Serving,但是建立一個巨大的github回購庫,每個其他步驟都有大量的依賴關係,這對我來說似乎壓倒一切。

+0

您需要加載專門構建的推理圖,而不是訓練圖。 Slim,tf.contrib.learn.Estimator,keras和其他框架都允許您構建一個很好的推理圖。 –

回答

0

我沒有使用Inception-v3模型,但是我找到了解決類似情況的方法。 對於培訓,我使用自定義多進程/多線程設置將我的樣本分批加載並將它們送入FIFOQueue。在凍結圖上運行推理總是無限期地掛起。 這裏是我的方法:

創建凍結推理模型:

  1. 建立一個完全獨立的推理圖。爲您的輸入創建佔位符[in1,in2,...](形狀對應於1個樣本),並以與培訓相同的方式創建模型。您的模型的輸出在下文中將被稱爲[out1,out2...]
  2. 使用tf.train.Saver()加載您的訓練模型參數(爲此,新模型中的名稱必須與您的訓練模型中的名稱相匹配)。喜歡的東西:

    loader = tf.train.Saver() 
    graph = tf.get_default_graph() 
    input_graph_def = graph.as_graph_def() 
    with tf.Session() as sess: 
        loader.restore(sess, input_checkpoint) 
    
  3. 創建一個凍結圖:

    frozen_graph_def = graph_util.convert_variables_to_constants(
        sess, 
        input_graph_def, 
        output_node_names) 
    
  4. 優化模型:

    optimized_graph_def = optimize_for_inference_lib.optimize_for_inference(
        frozen_graph_def, 
        input_node_names, 
        output_node_names, tf.float32.as_datatype_enum) 
    
  5. 保存模型:

    with tf.gfile.GFile(filename, "wb") as f: 
        f.write(optimized_graph_def.SerializeToString()) 
    

執行推斷與凍結模式:

  1. 負荷模型到

    with tf.gfile.GFile(frozen_graph_filename, "rb") as f: 
        graph_def = tf.GraphDef() 
        graph_def.ParseFromString(f.read()) 
    with tf.Graph().as_default() as graph: 
        tf.import_graph_def(
         graph_def, 
         input_map=None, 
         return_elements=None, 
         name='', 
         op_dict=None, 
         producer_op_list=None 
        ) 
    
  2. 訪問您的輸入/輸出:

    in1 = graph.get_tensor_by_name(input_tensor_names[0]) 
    in2 = graph.get_tensor_by_name(input_tensor_names[1]) 
    ... 
    out1 = graph.get_tensor_by_name(output_tensor_names[0]) 
    ... 
    
  3. 運行推論:

    with tf.Session(graph=graph) as sess: 
        sess.run([out1], feed_dict={in1: {data}, in2: {data}) 
    

提示:如何讓輸入/輸出節點/張的名字:

inputs = [in1, in2...] 
outputs = [out1, out2...] 

output_tensor_names = [n.name for n in outputs] 
input_tensor_names = [n.name for n in inputs] 

output_node_names = [n[:str(n).find(":")] for n in output_tensor_names] 
input_node_names = [n[:str(n).find(":")] for n in input_tensor_names] 

我希望這有助於。

相關問題