1. 程式人生 > >【Tensorflow】超參調整時對於模型更新輕量化的測試

【Tensorflow】超參調整時對於模型更新輕量化的測試

0x00 前言

由於各類模型在落地使用時都或多或少地需要一些超參的調整(學名調參、俗稱煉丹),
但如果每次修改少量超參之後,都要把網路和模型重新初始化一遍,這樣就太花時間了,
所以考慮能否儘量減少,甚至可以一次初始化,N個 for 迴圈的形式來解決超參測試呢?

0x01 測試程式碼

import os
import tensorflow as tf

class test_class(object):
    def __init__(self, options):
        self.sess = self.init_session()
        self.options =
options # init placeholders self.x = tf.placeholder( tf.float32, [None], name='x') # init network self.output = self.network_ge() def init_session(dynamic_gpu=False): # only use GPU:0 os.environ['CUDA_VISIBLE_DEVICES'
] = '0' tf_config = tf.ConfigProto() # access GPU capacity on demand tf_config.allow_soft_placement = True if dynamic_gpu: # automatically swap to empty GPU tf_config.gpu_options.allow_growth = True return tf.Session(config=tf_config) def network_ge
(self): # y is the hyper-parameter here. return tf.greater_equal( x=self.x, y=self.options.get('a', 0.), name='judge_ge') def network_drop(self): return tf.nn.dropout( x=self.x, keep_prob=self.options.get('a', 0.), name='judge_drop') def update_options(self, options): self.options = options def show(self, x): opt = self.options print 'option is:', opt with tf.name_scope('infer'): return self.sess.run( # `fetches=self.output` will not work here. fetches=self.network_ge(), # need re-generate network feed_dict={self.x: x})

0x03 測試輸出

通過測試我們可以看出,如果使用實現預生成的 output,即不重新生成計算圖的情況下
網路是不會因為更新了傳入的超參而改變的,需要再 call 一次計算圖的生成函式才起效

測試用例

import numpy as np
arr = np.random.rand(5)
print arr
tc = test_class({'a': 0.7})
print tc.show(arr)
tc.update_options({'a': 0.3})
print tc.show(arr)

未重建網路時

# `fetches=self.output` doesn't work here.
[0.27085583 0.47824313 0.03399892 0.79969376 0.22676119]
option is: {'a': 0.7}
[False False False  True False]
option is: {'a': 0.3}
[False False False  True False]

重建網路時

# `fetches=self.network_ge()` works here
[0.3715132  0.97066691 0.05802148 0.38615892 0.61126987]
option is: {'a': 0.7}
[False  True False False False]
option is: {'a': 0.3}
[ True  True False  True  True]

0x04 結論

即便是常數也會被Tensorflow的程式碼轉化為 tf.Constant 寫入計算圖,
所以在不改動計算圖的情況下通過修改傳入超參的方式會導致超參的修改不起效果,
故修改超參後按超參所在位置初始化即可,其他部分由於是逐層引用所以更新底層即可,
(測試前繞暈了,測試完……這不是理所當然嘛!QvQ):

  • (採用的是 Network \subset Model \subset Api 的架構)
  • 超參在計算圖中: 僅初始化計算圖 即可 (如 dropout 超參)
  • 超參在計算圖外: 僅初始化模型 即可 (如 clip、greater 超參)
  • 超參在計算圖內外都有使用: 初始化計算圖&模型(如 mask 超參)