bert模型參數簡化

  咱們下載下來的預訓練的bert模型的大小大概是400M左右,可是咱們本身預訓練的bert模型,或者是咱們在開源的bert模型上fine-tuning以後的模型的大小大約是1.1G,咱們來看看究竟是什麼緣由形成的,首先咱們能夠經過下一段代碼來輸出咱們訓練好的模型的參數變量。python

  下面這段代碼能夠輸出咱們下載的官方預訓練模型的參數變量算法

import tensorflow as tf
from tensorflow.python import pywrap_tensorflow


model_reader = pywrap_tensorflow.NewCheckpointReader("chinese_L-12_H-768_A-12/bert_model.ckpt")
var_dict = model_reader.get_variable_to_shape_map()
for key in var_dict:
    print(key)

  咱們截取了部分參數以下:優化

  

  如今換成咱們本身預訓練的bert模型,代碼和上面同樣spa

from tensorflow.python import pywrap_tensorflow


model_reader = pywrap_tensorflow.NewCheckpointReader("H_12_768_L12_vocab5/model.ckpt-1500000")
var_dict = model_reader.get_variable_to_shape_map()
for key in var_dict:
    print(key)

   咱們一樣截取部分參數3d

  

  咱們能夠看到這裏混入了很多帶有"adam"的變量,咱們來看adam優化算法,在計算一階矩和二階矩時,咱們是要保存以前時刻的滑動平均值的,而每一個須要經過梯度更新的參數,都要維護這樣一個一階矩和二階矩以前時刻的滑動平均值,也就是對應上面的 "adam_m" (一階矩) 和 「adam_v」 (二階矩),所以致使咱們本身預訓練的模型的大小大約是官方預訓練模型的大小的3倍。而這些參數變量只有訓練模型的時候有用,在以後預測的時候以及fine-tuning階段都是沒有用的(fine-tuning時咱們只是用到了以前預訓練好的模型的參數來做爲初始化值,並不會用到優化算法中的中間值),所以咱們能夠在訓練完或者fine-tuning完bert模型以後,在保存模型時將這些參數去掉,也能夠在保存了完整的參數以後,再加載去掉這些參數,而後從新保存,這樣就不須要改動bert的源碼,具體的實現以下:rest

import re
import tensorflow as tf
from tensorflow.contrib.slim import get_variables_to_restore


# 將bert中和adam相關的參數的值去掉,較小模型的內存
graph = tf.Graph()
with graph.as_default():
    sess = tf.Session()
    checkpoint_file = tf.train.latest_checkpoint("H_12_768_L12_vocab5/")
    saver = tf.train.import_meta_graph("{}.meta".format(checkpoint_file))
    saver.restore(sess, checkpoint_file)

    variables = get_variables_to_restore()
    other_vars = [variable for variable in variables if not re.search("adam", variable.name)]
    var_saver = tf.train.Saver(other_vars)
    var_saver.save(sess, "light_bert/model.ckpt")

  以後就能夠直接加載這個去掉帶"adam"的變量的模型用來作預測。這樣雖然不能提高模型的預測速度,可是能夠減少模型的內存。code

相關文章
相關標籤/搜索