TensorFlow saved_model 模塊

      網友投稿 848 2022-05-30

      因為最近嘗試在modelarts中,使用常用框架(這里是TF)來自己開發算法和訓練模型、部署模型等,

      在“常用框架”的示例中,在訓練結束后保存模型時,是這樣用的

      對這一塊呢,我很陌生,所以在網上查找資料時,找到一篇對此講解很不錯的文章,特轉載如下。原文地址

      saved_model模塊主要用于TensorFlow Serving。TF Serving是一個將訓練好的模型部署至生產環境的系統,主要的優點在于可以保持Server端與API不變的情況下,部署新的算法或進行試驗,同時還有很高的性能。

      保持Server端與API不變有什么好處呢?有很多好處,我只從我體會的一個方面舉例子說明一下,比如我們需要部署一個文本分類模型,那么輸入和輸出是可以確定的,輸入文本,輸出各類別的概率或類別標簽。為了得到較好的效果,我們可能想嘗試很多不同的模型,CNN,RNN,RCNN等,這些模型訓練好保存下來以后,在inference階段需要重新載入這些模型,我們希望的是inference的代碼有一份就好,也就是使用新模型的時候不需要針對新模型來修改inference的代碼。這應該如何實現呢?

      在TensorFlow 模型保存/載入的兩種方法中總結過。

      1. 僅用Saver來保存/載入變量。這個方法顯然不行,僅保存變量就必須在inference的時候重新定義Graph(定義模型),這樣不同的模型代碼肯定要修改。即使同一種模型,參數變化了,也需要在代碼中有所體現,至少需要一個配置文件來同步,這樣就很繁瑣了。

      2. 使用tf.train.import_meta_graph導入graph信息并創建Saver, 再使用Saver restore變量。相比第一種,不需要重新定義模型,但是為了從graph中找到輸入輸出的tensor,還是得用graph.get_tensor_by_name()來獲取,也就是還需要知道在定義模型階段所賦予這些tensor的名字。如果創建各模型的代碼都是同一個人完成的,還相對好控制,強制這些輸入輸出的命名都一致即可。如果是不同的開發者,要在創建模型階段就強制tensor的命名一致就比較困難了。這樣就不得不再維護一個配置文件,將需要獲取的tensor名稱寫入,然后從配置文件中讀取該參數。

      經過上面的分析發現,要實現inference的代碼統一,使用原來的方法也是可以的,只不過TensorFlow官方提供了更好的方法,并且這個方法不僅僅是解決這個問題,所以還是得學習使用saved_model這個模塊。

      TensorFlow saved_model 模塊

      saved_model 保存/載入模型

      先列出會用到的API

      class tf.saved_model.builder.SavedModelBuilder # 初始化方法 __init__(export_dir) # 導入graph與變量信息 add_meta_graph_and_variables( sess, tags, signature_def_map=None, assets_collection=None, legacy_init_op=None, clear_devices=False, main_op=None ) # 載入保存好的模型 tf.saved_model.loader.load( sess, tags, export_dir, **saver_kwargs )

      (1) 最簡單的場景,只是保存/載入模型

      保存

      要保存一個已經訓練好的模型,使用下面三行代碼就可以了。

      builder = tf.saved_model.builder.SavedModelBuilder(saved_model_dir) builder.add_meta_graph_and_variables(sess, ['tag_string']) builder.save()

      首先構造SavedModelBuilder對象,初始化方法只需要傳入用于保存模型的目錄名,目錄不用預先創建。

      add_meta_graph_and_variables方法導入graph的信息以及變量,這個方法假設變量都已經初始化好了,對于每個SavedModelBuilder這個方法一定要執行一次用于導入第一個meta graph。

      第一個參數傳入當前的session,包含了graph的結構與所有變量。

      第二個參數是給當前需要保存的meta graph一個標簽,標簽名可以自定義,在之后載入模型的時候,需要根據這個標簽名去查找對應的MetaGraphDef,找不到就會報如RuntimeError: MetaGraphDef associated with tags 'foo' could not be found in SavedModel這樣的錯。標簽也可以選用系統定義好的參數,如tf.saved_model.tag_constants.SERVING與tf.saved_model.tag_constants.TRAINING。

      save方法就是將模型序列化到指定目錄底下。

      保存好以后到saved_model_dir目錄下,會有一個saved_model.pb文件以及variables文件夾。顧名思義,variables保存所有變量,saved_model.pb用于保存模型結構等信息。

      載入

      使用tf.saved_model.loader.load方法就可以載入模型。如

      meta_graph_def = tf.saved_model.loader.load(sess, ['tag_string'], saved_model_dir)

      第一個參數就是當前的session,第二個參數是在保存的時候定義的meta graph的標簽,標簽一致才能找到對應的meta graph。第三個參數就是模型保存的目錄。

      load完以后,也是從sess對應的graph中獲取需要的tensor來inference。如

      x = sess.graph.get_tensor_by_name('input_x:0') y = sess.graph.get_tensor_by_name('predict_y:0') # 實際的待inference的樣本 _x = ... sess.run(y, feed_dict={x: _x})

      這樣和之前的第二種方法一樣,也是要知道tensor的name。那么如何可以在不知道tensor name的情況下使用呢? 那就需要給add_meta_graph_and_variables方法傳入第三個參數,signature_def_map。

      (2) 使用SignatureDef

      關于SignatureDef我的理解是,它定義了一些協議,對我們所需的信息進行封裝,我們根據這套協議來獲取信息,從而實現創建與使用模型的解耦。SignatureDef的結構以及相關詳細的文檔在:https://github.com/tensorflow/serving/blob/master/tensorflow_serving/g3doc/signature_defs.md

      相關API

      # 構建signature tf.saved_model.signature_def_utils.build_signature_def( inputs=None, outputs=None, method_name=None ) # 構建tensor info tf.saved_model.utils.build_tensor_info(tensor)

      SignatureDef,將輸入輸出tensor的信息都進行了封裝,并且給他們一個自定義的別名,所以在構建模型的階段,可以隨便給tensor命名,只要在保存訓練好的模型的時候,在SignatureDef中給出統一的別名即可。

      TensorFlow的關于這部分的例子中用到了不少signature_constants,這些constants的用處主要是提供了一個方便統一的命名。在我們自己理解SignatureDef的作用的時候,可以先不用管這些,遇到需要命名的時候,想怎么寫怎么寫。

      保存

      假設定義模型輸入的別名為“input_x”,輸出的別名為“output” ,使用SignatureDef的代碼如下

      builder = tf.saved_model.builder.SavedModelBuilder(saved_model_dir) # x 為輸入tensor, keep_prob為dropout的prob tensor inputs = {'input_x': tf.saved_model.utils.build_tensor_info(x), 'keep_prob': tf.saved_model.utils.build_tensor_info(keep_prob)} # y 為最終需要的輸出結果tensor outputs = {'output' : tf.saved_model.utils.build_tensor_info(y)} signature = tf.saved_model.signature_def_utils.build_signature_def(inputs, outputs, 'test_sig_name') builder.add_meta_graph_and_variables(sess, ['test_saved_model'], {'test_signature':signature}) builder.save()

      上述inputs增加一個keep_prob是為了說明inputs可以有多個, build_tensor_info方法將tensor相關的信息序列化為TensorInfo protocol buffer。

      inputs,outputs都是dict,key是我們約定的輸入輸出別名,value就是對具體tensor包裝得到的TensorInfo。

      然后使用build_signature_def方法構建SignatureDef,第三個參數method_name暫時先隨便給一個。

      創建好的SignatureDef是用在add_meta_graph_and_variables的第三個參數signature_def_map中,但不是直接傳入SignatureDef對象。事實上signature_def_map接收的是一個dict,key是我們自己命名的signature名稱,value是SignatureDef對象。

      載入

      載入與使用的代碼如下

      ## 略去構建sess的代碼 signature_key = 'test_signature' input_key = 'input_x' output_key = 'output' meta_graph_def = tf.saved_model.loader.load(sess, ['test_saved_model'], saved_model_dir) # 從meta_graph_def中取出SignatureDef對象 signature = meta_graph_def.signature_def # 從signature中找出具體輸入輸出的tensor name x_tensor_name = signature[signature_key].inputs[input_key].name y_tensor_name = signature[signature_key].outputs[output_key].name # 獲取tensor 并inference x = sess.graph.get_tensor_by_name(x_tensor_name) y = sess.graph.get_tensor_by_name(y_tensor_name) # _x 實際輸入待inference的data sess.run(y, feed_dict={x:_x})

      TensorFlow 機器學習

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:HarmonyOS實戰—Text組件寬高三種值的寫法和顏色屬性
      下一篇:人像摳圖:算法概述及工程實現(二)
      相關文章
      亚洲成a人片77777老司机| 亚洲欧美日韩综合久久久| 亚洲网址在线观看你懂的| 最新国产AV无码专区亚洲 | 国产av无码专区亚洲av桃花庵| 色九月亚洲综合网| 亚洲第一第二第三第四第五第六| 亚洲一级片在线观看| 亚洲国产午夜精品理论片| 亚洲黄色在线播放| 亚洲高清中文字幕综合网| 亚洲美女精品视频| 精品亚洲成AV人在线观看| 日产亚洲一区二区三区| 亚洲熟妇无码久久精品| 亚洲国产av美女网站| xxx毛茸茸的亚洲| 亚洲神级电影国语版| 久久久亚洲裙底偷窥综合| 亚洲精品视频在线| 亚洲视频在线一区二区三区| 亚洲精品午夜在线观看| 亚洲一级免费视频| 中文无码亚洲精品字幕| 亚洲精品无码永久在线观看男男| 亚洲av永久无码一区二区三区| 亚洲AV无码成人精品区狼人影院| 全亚洲最新黄色特级网站| 久久精品国产精品亚洲下载| 亚洲香蕉网久久综合影视| 亚洲AV无码国产精品色午友在线| 亚洲国产国产综合一区首页| 亚洲视频在线观看| 亚洲人和日本人jizz| 亚洲综合av一区二区三区不卡| 国产精品亚洲专区无码WEB| 亚洲国产精品日韩| 国产亚洲3p无码一区二区| 亚洲人成电影在线天堂| 亚洲一本之道高清乱码| 亚洲GV天堂GV无码男同|