【Tensorflow】スーパーパラメトリック調整時のモデル再負荷軽量化試験

15774 ワード

0 x 00はじめに


各種類のモデルは着地使用時に多かれ少なかれいくつかのスーパーパラメータの調整(学名調参、通称錬丹)が必要であるが、少量のスーパーパラメータを修正するたびに、ネットワークとモデルを再初期化しなければならないので、時間がかかるので、できるだけ減らして、一度に初期化して、N個のforサイクルの形式でスーパーパラメータテストを解決できるかどうかを考えている.

0 x 01テストコード

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})

0 x 03テスト出力


テストにより,事前生成を実現する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]

スーパーパラメータの変更


また、optionsの転送は実際にはコピーではなく参照であるため、クラス外の修正を直接実現しても同様の効果が得られる.注意:update/appendなどの方法を使用するべきで、例化を再実行しないでください.例えばf_opt = {'a': 0.3}は辞書を再開いて値を割り当てます.
import numpy as np
arr = np.random.rand(5)
print arr
f_opt = {'a': 0.7}
tc = test_class(f_opt)
print tc.show(arr)
f_opt.update({'a': 0.3})
# But `f_opt = {'a': 0.3}` is Wrong
print tc.show(arr)
tc.update_options(f_opt)
print tc.show(arr)

"""
[0.03253315 0.60373154 0.55212969 0.52420715 0.67525966]
option is: {'a': 0.7}
[False False False False False]
option is: {'a': 0.3}
[False  True  True  True  True]
option is: {'a': 0.3}
[False  True  True  True  True]
"""

0 x 04結論


定数でもTensorflowのコードによりtfに変換する.Constantは計算図を書き込みますので、計算図を変更せずにスーパーパラメータを入力する方法を変更することでスーパーパラメータの修正が効果的にならないので、スーパーパラメータを修正してスーパーパラメータの位置で初期化すればいいのですが、他の部分は階層ごとの参照なので最下位を更新すればいいのです(テスト前にめまいがして、テストが終わって・・・当たり前じゃないですか!QvQ):
  • (Network∈subset∈Model∈subset∈Apiのアーキテクチャを採用)
  • スーパーパラメトリック計算図:計算図のみを初期化(dropoutスーパーパラメトリックなど)
  • スーパーパラメータ計算図外:clip、greaterスーパーパラメータなどのモデルのみを初期化
  • スーパーパラメータは計算図の内外で使用されている:初期化計算図&モデル(maskスーパーパラメータなど)