在使用Tensorflow時,我們經常要將以訓練好的模型保存到本地或者使用別人已訓練好的模型,因此,作此筆記記錄下來。
TensorFlow通過tf.train.Saver類實現神經網絡模型的保存和提取。tf.train.Saver對象saver的save方法將TensorFlow模型保存到指定路徑中,如:saver.save(sess, "/Model/model"), 執行完,在相應的目錄下將會有4個文件:
meta:文件保存的是圖結構信息,meta文件是pb(protocol buffer)格式文件,包含變量、op、集合等。
ckpt保存每個變量的取值,此處文件名的寫入方式會因不同參數的設置而不同。是二進制文件,保存了所有的weights、biases、gradients等變量。在tensorflow 0.11之 前,保存在.ckpt文件中。0.11后,通過兩個文件保存,如:.data-00000-of-00001和.index文件
checkpoint文件:checkpoint_dir目錄下還有checkpoint文件,該文件是個文本文件,里面記錄了保存的最新的checkpoint文件以及其它checkpoint文件列表。在inference時,可以通過修改這個文件,指定使用哪個model。加載restore時的文件路徑名是以checkpoint文件中的“model_checkpoint_path”值決定的。
保存模型時,只會保存變量的值,placeholder里面的值不會被保存。
關於save()方法的參數記錄:
- sess:在tensorflow中,變量是存在於Session環境中,即只有在Session環境下才會存有變量值,因此,保存模型時需要傳入session
- global_step:在n次迭代后,再保存模型,只需設置
global_step參數即可 - 由於圖是不變的,沒必要每次都去保存,可以在多次迭代過程中只用保存一次模型即可,可以通過設置write_meta_graph=False即可
- keep_checkpoint_every_n_hours:用來設置間隔時間來保存
- max_to_keep: 用來設置保存最近模型文件的個數
- 如果不想保存所有變量,而只保存一部分變量,可以通過指定variables/collections,默認是保存所有的變量。
tf.train.Saver類也支持在保存和加載時給變量重命名,聲明Saver類對象的時候使用一個字典dict重命名變量即可,{"已保存的變量的名稱name": 重命名變量名}。
導入模型
加載圖:saver=tf.train.import_meta_graph(.meta文件)即可。
加載模型參數:aver.restore(sess, tf.train.latest_checkpoint('./checkpoint_dir'))
graph = tf.get_default_graph()
w1 = graph.get_tensor_by_name("w1:0")
w2 = graph.get_tensor_by_name("w2:0")
feed_dict = {w1: 13.0, w2: 17.0}
注意w1:0是tensor的name,既可以指定變量名稱,也可以指定操作名稱。
其實,我們也可以只恢復圖的一部分,並且再加入其它的op用於fine-tuning。只需通過graph.get_tensor_by_name()方法獲取需要的op,並且在此基礎上建立圖即可。例如:假設我們想使用已經訓練好的VGG模型,並且要更改部分層,如下:
saver = tf.train.import_meta_graph('vgg.meta')
# 訪問圖
graph = tf.get_default_graph()
#訪問用於fine-tuning的output
fc7= graph.get_tensor_by_name('fc7:0')
#如果你想修改最后一層梯度,需要如下
fc7 = tf.stop_gradient(fc7) # It's an identity function
fc7_shape= fc7.get_shape().as_list()
new_outputs=2
weights = tf.Variable(tf.truncated_normal([fc7_shape[3], num_outputs], stddev=0.05))
biases = tf.Variable(tf.constant(0.05, shape=[num_outputs]))
output = tf.matmul(fc7, weights) + biases
pred = tf.nn.softmax(output)
