2016-02-02 71 views
34

標準的な方法は、しばらくの間、いくつかの学習を実行した後、私は変数の新しいセットを作成しますが、私はそれらを初期化したら、それは私のすべての既存の変数をリセットしますTensorFlowでは、初期化されていない変数を初期化する方法はありますか? TensorFlowで変数を初期化する

init = tf.initialize_all_variables() 
sess = tf.Session() 
sess.run(init) 

です。現時点では、私が必要とする変数をすべて保存してから、tf.initalize_all_variables呼び出しの後に再適用します。これは動作しますが、少し醜いとclunkyです。私はこのような文書を見つけることができません...

誰もが初期化されていない変数を初期化する良い方法を知っていますか?

+0

ここあなたが望むものを正確に行う[シンプルな関数](http://stackoverflow.com/a/43601894/1090562)の例です。 –

+0

'tf.train.Optimizer.minimize(loss)'関数は[ドキュメントに記載されています](https://www.tensorflow.org/versions/r0.11/api_docs/python/train.html#Optimizer .minimize) 'optim.apply_gradients(optim.compute_gradients(損失))'。これはあなたのすべての 'None'を投げることを除いてあなたの例を私のものと同じにします。その後、 'train_step'を実行できますか?私が走った時、すべてのスロットは 'None'だったので、オプティマイザは初期化されず、ニューラルネットワークは動かなかった。 – Poik

答えて

24

グラフに初期化されていない変数を列挙するエレガントな方法はありません。

試行錯誤のプロセスは可能性*  
init_new_vars_op = tf.initialize_variables([v_6, v_7, v_8]) 
sess.run(init_new_vars_op) 

:しかし、あなたは新しい変数オブジェクトへのアクセス権を持っている場合は、選択tf.initialize_variables()を使用してそれらを初期化することができますのはv_6v_7、およびv_8 —それらを呼びましょう—初期化されていない変数を識別するために使用されます:

uninitialized_vars = [] 
for var in tf.all_variables(): 
    try: 
     sess.run(var) 
    except tf.errors.FailedPreconditionError: 
     uninitialized_vars.append(var) 

init_new_vars_op = tf.initialize_variables(uninitialized_vars) 
# ... 

...しかし、私はこのような動作を許しません:-)。

+3

Tensorflow 0.9には便利なtf.report_uninitialized_variables()関数があります。 – user3391229

26

UPDATE: TensorFlow 0.9は、「修正」このすべてをいますが、TrueからVariableScopereuseとのセットを使用している場合にのみ、という新しい方法を持っています。あなたが初期化されることを期待する変数を指定する機能を通じてsess.run(tf.initialize_variables(list(tf.get_variable(name) for name in sess.run(tf.report_uninitialized_variables(tf.all_variables())))))

またはよりインテリジェントに1行で使用することができtf.report_uninitialized_variables

def guarantee_initialized_variables(session, list_of_variables = None): 
    if list_of_variables is None: 
     list_of_variables = tf.all_variables() 
    uninitialized_variables = list(tf.get_variable(name) for name in 
            session.run(tf.report_uninitialized_variables(list_of_variables))) 
    session.run(tf.initialize_variables(uninitialized_variables)) 
    return unintialized_variables 

これはまだ実際に変数があるとされている知っているよりも少ない理想的です初期化されず、適切に処理されますが、optimクラス(後述)のような誤った指示の場合、回避するのは難しいかもしれません。

また、tf.initialize_variablesはtf.report_uninitialized_variablesを評価できないため、両方ともセッションのコンテキスト内で動作する必要があります。


これを行うには、洗練されていませんが簡潔な方法があります。あなたの新しい変数を導入する前に、temp = set(tf.all_variables())を実行してから、sess.run(tf.initialize_variables(set(tf.all_variables()) - temp))を実行してください。これらは一緒になって、一時値が割り当てられた後に作成された変数のみを初期化します。

私はトランスファーラーニングで遊んでいたので、すばやくそれをやりたかったのですが、これが私が見つける最良の方法です。特に、AdamOptimizerのようなものを使用している場合、使用する変数へのアクセスが容易ではありません(またはわかりません)。だから実際に私のコードに次のように現れます。 (私は明示的に新しいレイヤーの変数を初期化し、転移学習前の初期のエラーを表示するには、一度それを実行します。ただ、健全性チェックのために。)

temp = set(tf.all_variables()) 
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy) 
#I honestly don't know how else to initialize ADAM in TensorFlow. 
sess.run(tf.initialize_variables(set(tf.all_variables()) - temp)) 

をそして、それはすべて私の問題を解決します。

編集:@Lifu_Huang's answerは、私の問題を解決する適切な方法を述べています。理論的には、tf.train.Optimizer.get_slot_namestf.train.Optimizer.get_slotを使用する必要があります。

optim = tf.train.AdadeltaOptimizer(1e-4) 
loss = cross_entropy(y,yhat) 
train_step = optim.minimize(loss) 
sess.run(tf.initialize_variables([optim.get_slot(loss, name) 
            for name in optim.get_slot_names()]) 

これは、しかし、私AttributeError: 'NoneType' object has no attribute 'initializer'できます。私が間違っていたことを理解したときに編集を行いますので、間違いをしないでください。

+1

私は 'AttributeError: 'NoneType'オブジェクトに属性 'initializer''の問題がありません。 – rafaelcosman

+2

スロットにもかかわらず、オプティマイザによって作成された他のバーがあることに注意してください。私のために 'AdamOptimizer'は、vars' [ ] 'に対応していないので、スロットとして取得することはできません。 – Albert

4

@Poikの場合、変数がオプティマイザによって直接アクセスできないように作成されている場合、よりクリーンな解決策はtf.train.Optimizer.get_slotを使用することです。

MomentumOptimizerAdagradOptimizerなどの一部のオプティマイザサブクラスでは、訓練する変数に関連付けられた追加の変数を割り当てて管理します。これらはスロットと呼ばれます。 tf.train.Optimizer.get_slot_names()を使用すると、オプティマイザが持つすべてのスロット名を取得し、tf.train.Optimizer.get_slotを使用して、これらのスロットに割り当てられた変数を取得できます。

+2

'tf.train.Optimizer.get_slot'はオプティマイザが必要な変数を作成するまで' tf.train.Optimizer.get_slot'が 'None'を返すので、実際には使用できません。これは' minimize'が初めて実行されたときに起こります。これを回避するには、ドキュメント化された関数 'tf.train.Optimizer._zeros_slot()'や、ドキュメント化されたサポートが必要な場合や、TensorFlowの将来の更新を利用できるようにするためには、決して行うべきでない関数を呼び出す必要があります。 – Poik

+1

スロットにもかかわらず、オプティマイザによって作成された他のバーがあることに注意してください。私のために 'AdamOptimizer'は、vars' [ ] 'に対応していないので、スロットとして取得することはできません。 – Albert

4

私はTensorFlow r0.11ための方法を作ってみた:私は、最も簡単な方法は、最初にすべてのトレーニングの演算子を作成し、その後、変数を初期化することだと思い

def get_uninitialized_variables(variables=None): 
    """Get uninitialized variables as a list. 

    Parameters 
    ---------- 
    variables : collections.Iterable[tf.Variable] 
     Return only uninitialized variables within this collection. 
     If not specified, will return all uninitialized variables. 

    Returns 
    ------- 
    list[tf.Variable] 
    """ 
    sess = tf.get_default_session() 
    if variables is None: 
     variables = tf.all_variables() 
    else: 
     variables = list(variables) 
    init_flag = sess.run(
     tf.pack([tf.is_variable_initialized(v) for v in variables])) 
    return [v for v, f in zip(variables, init_flag) if not f] 
0

# create an optimizer 
pretrain_optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate) 

# Make an array of the trainers for all the layers 
trainers=[pretrain_optimizer.minimize(loss_reconstruction(ae.run_less_layers(ae._input_, i+1), ae.run_less_layers(ae._input_, i+1, is_target=True)), global_step=tf.contrib.framework.get_or_create_global_step(), name='Layer_wise_optimizer_'+str(i)) for i in xrange(len(ae_shape) - 2)] 

# Initialize all the variables 
sess.run(tf.global_variables_initializer()) 
13

TF does not have a function that does exactly what you wantをしますが、簡単に1を書くことができます:

は例えば、私は次のようにアダム・オプティマイザと層状事前訓練の問題を解決し

import tensorflow as tf 

def initialize_uninitialized(sess): 
    global_vars   = tf.global_variables() 
    is_not_initialized = sess.run([tf.is_variable_initialized(var) for var in global_vars]) 
    not_initialized_vars = [v for (v, f) in zip(global_vars, is_not_initialized) if not f] 

    print [str(i.name) for i in not_initialized_vars] # only for testing 
    if len(not_initialized_vars): 
     sess.run(tf.variables_initializer(not_initialized_vars)) 

ここで私は、すべてglobal variablesを抽出し、すべてを反復してare already initializedかどうかを確認します。この後、私はinitializeという初期化されていない変数のリストを取得します。また、デバッグのために初期化する変数も表示します。


あなたは簡単に予想通りに動作することを確認することができます

a = tf.Variable(3, name='my_var_a') 
b = tf.Variable(4, name='my_var_b') 

sess = tf.Session() 
initialize_uninitialized(sess) 
initialize_uninitialized(sess) 

c = tf.Variable(5, name='my_var_a') # the same name, will be resolved to different name 
d = tf.Variable(6, name='my_var_d') 
initialize_uninitialized(sess) 

print '\n\n', sess.run([a, b, c, d]) 

これは、すべての変数が初期化されていることを確認説得行います彼らと最後sess.runを初期化する前にすべて初期化されない変数を出力します。


同様の機能を書き込むには、tf.report_uninitialized_variables()を使用することもできます。そのスケッチはhereです。ところで

+0

すばらしい答え。あなたは私の投票権を持っています。 'tf.report_uninitialized_variables()'を使う方が良いでしょうか? –

+0

@PaulO私の意見では両方のアプローチが似ていると私はそれらのいずれかが良いと言うことはできません。 –

1

、あなたは、あなたが次の例のようにsess.run()your_tensor.initializerを使用することができ、tf.global_variables_initializer()を使用して初期化されていない(例えばtf.Variable用)のみの単一テンソルを初期化したい場合:

In [196]: weights = tf.Variable(tf.zeros(shape=(3, 4)), name='weights') 

In [197]: with tf.Session() as sess: 
    ...:  sess.run(weights.initializer) 
    ...:  print(weights.eval()) 
    ...:  

# the result 
[[ 0. 0. 0. 0.] 
[ 0. 0. 0. 0.] 
[ 0. 0. 0. 0.]] 
関連する問題