fine-tuning 預訓練的模型文件

首先介紹tensorflow 版本的,當你有完整的訓練好的tensorflow 模型時你的文件夾裏邊會出現四個文件 

1、checkpoint 文件,這個文件當中存放的時預訓練好的模型地址

2、model.ckpt.meta 文件,這個文件當中存放的是你預訓練好的模型的grah,解析這個文件你能得到當初保存模型時所存儲的變量的名稱和形狀

3、model.ckpt.index 文件和model.ckpt.data-00000-of-00001 之類的文件(具體名稱可能有出入)。之所以將這兩個文件一起介紹

  是因爲這兩個文件在重載 checkpoint文件讀取其中的參數值時 這兩個文件缺一不可。

import tensorflow as tf

new_saver = tf.train.import_meta_graph("./model.ckpt-1000.meta")
#此處的‘model.ckpt-1000.meta’對應特定的*.ckpt.meta文件
print "ModelV construct"
all_vars = tf.trainable_variables()

config = tf.ConfigProto()
config.gpu_options.allow_growth = True

with tf.Session(config = config) as sess:
    for v in all_vars:
        print v.name, ':', v.shape, sess.run(tf.shape(v))
#以下的部分則是依據從graph中解析出的變量對參數值進行重載
    new_saver.restore(sess, tf.train.latest_checkpoint('./'))

    for v in all_vars:
        print v.name,v.eval(sess)
下面貼出session上半部分的print內容


依據以上的文件所打印的內容可以得知預訓練模型所保存的變量名稱

然後依據所得知的變量名,構建自己的新的graph,(保證自己新的graph中變量的名稱和預訓練模型的變量名稱一致)

然後構建一個saver將新的graph中變量存到saver中,用這個saver 去restore預訓練模型。

下面貼出一個根據上邊的預訓練模型中的參數給新的graph的部分變量進行初始化的code

import tensorflow as tf

list_restore = []
with tf.name_scope('conv1'):
    v1 = tf.Variable(tf.random_normal([16]), name="biases")
    list_restore.append(v1)
with tf.name_scope('conv2'):
    v1 = tf.Variable(tf.random_normal([16]), name = 'biases')
    list_restore.append(v1)
with tf.name_scope('softmax_linear'):
    v1 = tf.Variable(tf.random_normal([2]), name = 'biases')
init = tf.global_variables_initializer()
all_vars = tf.trainable_variables()
new_saver = tf.train.Saver(list_restore)

config = tf.ConfigProto()
config.gpu_options.allow_growth = True

with tf.Session(config = config) as sess:
    sess.run(init)
    new_saver.restore(sess, tf.train.latest_checkpoint('./'))
    
    for v in list_restore:
        print v.name,v.eval(sess)
    print('*'*18)
    
    for var in all_vars:
        print var.name, var.shape, var.eval(sess)

我新構建的graph中前兩個v1變量的name與預訓練模型保存參數name相同,並且我將這兩個變量放在一個list中構建saver。

再用這個saver去restore預訓練模型;注意,最後一個name爲“softmax_linear/biases:0”的變量v1雖然與預訓練模型的變量名(name)一樣

但是我並沒有將其加入saver中,所以最終我得到的三個變量是前兩個v1初始化是由預訓練模型的參數對其進行初始化,

而最後一個v1變量初始化是由其變量原先構建時指定的初始化方式進行初始化


********************************************分割線*********************************************************************************

下面介紹如何對預訓練好的caffemodel文件進行新網絡的初始化

直接附一個github抓的代碼#來自於Drsleep先生的deeplabv1版本的tensorflow實現


"""Extract parameters of the DeepLab-LargeFOV model
   from the provided .caffemodel file.
   
This scripts extracts and saves the network skeleton 
with names and shape of the parameters, 
as well as all the corresponding weights.

To run the script, PyCaffe should be installed.
"""

from __future__ import print_function

import argparse
import os
import sys

from six.moves import cPickle

def get_arguments():
    """Parse all the arguments provided from the CLI.
    
    Returns:
      A list of parsed arguments.
    """
    parser = argparse.ArgumentParser(description="Extract model parameters of DeepLab-LargeFOV from the provided .caffemodel.")
    parser.add_argument("--caffemodel", type=str, default = "train2_iter_8000.caffemodel",
                        help="Caffemodel from which the parameters will be extracted.")
    parser.add_argument("--output_dir", type=str, default="/home/yanyu/deeplab-lfov/util/",
                        help="Whether to store the network skeleton and weights.")
    parser.add_argument("--pycaffe_path", type=str, default="/home/yanyu/caffe/python",
                        help="Path to PyCaffe (e.g., 'CAFFE_ROOT/python').")
    return parser.parse_args()

def main():
    """Extract and save network skeleton with the corresponding weights.
    
    Raises:
      ImportError: PyCaffe module is not found."""
    args = get_arguments()
    sys.path.append(args.pycaffe_path)
    try:
        import caffe
    except ImportError:
        raise
    # Load net definition.
    net = caffe.Net('deploy.prototxt', args.caffemodel, caffe.TEST)
 #關鍵在這一句,對於 caffemodel進行解析, 此處的*.prototxt文件是你自己新構建的網絡
    
    # Check the existence of output_dir.
    if not os.path.exists(args.output_dir):
        os.makedirs(args.output_dir)
    
    # Net skeleton with parameters names and shapes.
    # In TF, the filter shape is as follows: [ks, ks, input_channels, output_channels],
    # while in Caffe it looks like this: [output_channels, input_channels, ks, ks].
    net_skeleton = list() 
    for name, item in net.params.iteritems():
        net_skeleton.append([name + '/w', item[0].data.shape[::-1]]) # See the explanataion on filter formats above.
        net_skeleton.append([name + '/b', item[1].data.shape])
    
    with open(os.path.join(args.output_dir, 'net_skeleton_yen.ckpt'), 'wb') as f:
        cPickle.dump(net_skeleton, f, protocol=cPickle.HIGHEST_PROTOCOL)
    
    # Net weights. 
    net_weights = dict()
    for name, item in net.params.iteritems():
        net_weights[name + '/w'] = item[0].data.transpose(2, 3, 1, 0) # See the explanation on filter formats above.
        net_weights[name + '/b'] = item[1].data
    with open(os.path.join(args.output_dir,'net_weights_yen.ckpt'), 'wb') as f:
        cPickle.dump(net_weights, f, protocol=cPickle.HIGHEST_PROTOCOL)
    del net, net_skeleton, net_weights

if __name__ == '__main__':
    main()

這個代碼直接將一個新的網絡用預訓練好的caffemodel文件對其進行初始化,而返回的兩個文件一個是list<保存的是參數的name和shape>保存文件名爲‘net_skeleton_yen.ckpt’

另外一個是dirt<保存的時name 和相應的參數值> 保存文件名爲‘net_weights_yen.ckpt’

需要注意的是,你新構建的prototxt文件的layer中的變量(weigts 和biases)的name 只有和生成caffemodel文件的所定義的一致時














發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章