採用 TensorFlow 的時候,有時候咱們須要加載的不止是一個模型,那麼如何加載多個模型呢?git
原文:bretahajek.com/2017/04/imp…github
關於 TensorFlow 能夠有不少東西能夠說。但此次我只介紹如何導入訓練好的模型(圖),由於我作不到導入第二個模型並將它和第一個模型一塊兒使用。而且,這種導入很是慢,我也不想重複作第二次。另外一方面,將一切東西都放到一個模型也不實際。bash
在這個教程中,我會介紹如何保存和載入模型,更進一步,如何加載多個模型。微信
在介紹加載多個模型以前,咱們先介紹下如何加載單個模型,官方文檔:www.tensorflow.org/programmers…session
首先,咱們須要建立一個模型,訓練並保存它。這部分我不想過多介紹細節,只須要關注如何保存模型以及不要忘記給每一個操做命名。dom
建立一個模型,訓練並保存的代碼以下:機器學習
import tensorflow as tf
### Linear Regression 線性迴歸###
# Input placeholders
x = tf.placeholder(tf.float32, name='x')
y = tf.placeholder(tf.float32, name='y')
# Model parameters 定義模型的權值參數
W1 = tf.Variable([0.1], tf.float32)
W2 = tf.Variable([0.1], tf.float32)
W3 = tf.Variable([0.1], tf.float32)
b = tf.Variable([0.1], tf.float32)
# Output 模型的輸出
linear_model = tf.identity(W1 * x + W2 * x**2 + W3 * x**3 + b,
name='activation_opt')
# Loss 定義損失函數
loss = tf.reduce_sum(tf.square(linear_model - y), name='loss')
# Optimizer and training step 定義優化器運算
optimizer = tf.train.AdamOptimizer(0.001)
train = optimizer.minimize(loss, name='train_step')
# Remember output operation for later aplication
# Adding it to a collections for easy acces
# This is not required if you NAME your output operation
# 記得將輸出操做添加到一個集合中,但如何你命名了輸出操做,這一步能夠省略
tf.add_to_collection("activation", linear_model)
## Start the session ##
sess = tf.Session()
sess.run(tf.global_variables_initializer())
# CREATE SAVER
saver = tf.train.Saver()
# Training loop 訓練
for i in range(10000):
sess.run(train, {x: data, y: expected})
if i % 1000 == 0:
# You can also save checkpoints using global_step variable
saver.save(sess, "models/model_name", global_step=i)
# SAVE TensorFlow graph into path models/model_name
# 保存模型到指定路徑並命名模型文件名字
saver.save(sess, "models/model_name")
複製代碼
注意,這裏是第一個重點--對變量和運算命名。這是爲了在加載模型後可使用指定的一些權值參數,若是不命名的話,這些變量會自動命名爲相似「Placeholder_1」的名字。在複雜點的模型中,使用領域(scopes)是一個很好的作法,但這裏不作展開。ide
總之,==重點就是爲了在加載模型的時候可以調用權值參數或者某些運算操做,你必須給他們命名或者是放到一個集合中。==函數
當保存模型後,在指定保存模型的文件夾中就應該包含這些文件:model_name.index
、model_name.meta
以及其餘文件。若是是採用checkpoints
後綴命名模型名字,還會有名字包含model_name-1000
的文件,其中的數字是對應變量global_step
,也就是當前訓練迭代次數。oop
如今咱們就能夠開始加載模型了。加載模型其實很簡單,咱們須要的只是兩個函數便可:tf.train.import_meta_graph
和saver.restore()
。此外,就是提供正確的模型保存路徑位置。另外,若是咱們但願在不一樣機器使用模型,那麼還須要設置參數:clear_device=True
。
接着,咱們就能夠經過以前命名的名字或者是保存到的集合名字來調用保存的運算或者是權值參數了。若是使用了領域,那麼還須要包含領域的名字才行。而在實際調用這些運算的時候,還必須採用相似{'PlaceholderName:0': data}
的輸入佔位符,不然會出現錯誤。
加載模型的代碼以下:
sess = tf.Session()
# Import graph from the path and recover session
# 加載模型並恢復到會話中
saver = tf.train.import_meta_graph('models/model_name.meta', clear_devices=True)
saver.restore(sess, 'models/model_name')
# There are TWO options how to access the operation (choose one)
# 兩種方法來調用指定的運算操做,選擇其中一個均可以
# FROM SAVED COLLECTION: 從保存的集合中調用
activation = tf.get_collection('activation')[0]
# BY NAME: 採用命名的方式
activation = tf.get_default_graph.get_operation_by_name('activation_opt').outputs[0]
# Use imported graph for data
# You have to feed data as {'x:0': data}
# Don't forget on ':0' part!
# 採用加載的模型進行操做,不要忘記輸入佔位符
data = 50
result = sess.run(activation, {'x:0': data})
print(result)
複製代碼
上述介紹瞭如何加載單個模型的操做,但如何加載多個模型呢?
若是使用加載單個模型的方式去加載多個模型,那麼就會出現變量衝突的錯誤,也沒法工做。這個問題的緣由是由於一個默認圖的緣故。衝突的發生是由於咱們將全部變量都加載到當前會話採用的默認圖中。當咱們採用會話的時候,咱們能夠經過tf.Session(graph=MyGraph)
來指定採用不一樣的已經建立好的圖。所以,若是咱們但願加載多個模型,那麼咱們須要作的就是把他們加載在不一樣的圖,而後在不一樣會話中使用它們。
這裏,自定義一個類來完成加載指定路徑的模型到一個局部圖的操做。這個類還提供run
函數來對輸入數據使用加載的模型進行操做。這個類對於我是有用的,由於我老是將模型輸出放到一個集合或者對它命名爲activation_opt
,而且將輸入佔位符命名爲x
。你能夠根據本身實際應用需求對這個類進行修改和拓展。
代碼以下:
import tensorflow as tf
class ImportGraph():
""" Importing and running isolated TF graph """
def __init__(self, loc):
# Create local graph and use it in the session
self.graph = tf.Graph()
self.sess = tf.Session(graph=self.graph)
with self.graph.as_default():
# Import saved model from location 'loc' into local graph
# 從指定路徑加載模型到局部圖中
saver = tf.train.import_meta_graph(loc + '.meta',
clear_devices=True)
saver.restore(self.sess, loc)
# There are TWO options how to get activation operation:
# 兩種方式來調用運算或者參數
# FROM SAVED COLLECTION:
self.activation = tf.get_collection('activation')[0]
# BY NAME:
self.activation = self.graph.get_operation_by_name('activation_opt').outputs[0]
def run(self, data):
""" Running the activation operation previously imported """
# The 'x' corresponds to name of input placeholder
return self.sess.run(self.activation, feed_dict={"x:0": data})
### Using the class ###
# 測試樣例
data = 50 # random data
model = ImportGraph('models/model_name')
result = model.run(data)
print(result)
複製代碼
若是你理解了 TensorFlow 的機制的話,加載多個模型並非一件困難的事情。上述的解決方法可能不是完美的,可是它簡單且快速。最後給出總結整個過程的樣例代碼,這是在 Jupyter notebook 上的,代碼地址以下:
最後,給出文章中幾個代碼例子的 github 地址:
歡迎關注個人微信公衆號--機器學習與計算機視覺或者掃描下方的二維碼,在後臺留言,和我分享你的建議和見解,指正文章中可能存在的錯誤,你們一塊兒交流,學習和進步!
推薦閱讀