it-swarm.com.de

Gibt es in TensorFlow eine Möglichkeit, nicht initialisierte Variablen zu initialisieren?

Die Standardmethode zum Initialisieren von Variablen in TensorFlow ist

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

Nachdem ich einige Zeit etwas gelernt hatte, erstelle ich einen neuen Satz von Variablen, aber sobald ich sie initialisiert habe, werden alle meine vorhandenen Variablen zurückgesetzt. Im Moment ist es mein Weg, um alle Variablen zu speichern, die ich brauche, und sie nach dem Aufruf von tf.initalize_all_variables erneut anzuwenden. Das funktioniert, ist aber etwas hässlich und klobig. Ich kann so etwas in den Dokumenten nicht finden ...

Kennt jemand eine gute Möglichkeit, die nicht initialisierten Variablen nur zu initialisieren? 

42
Daniel Slater

Es gibt keine elegante * Möglichkeit, die nicht initialisierten Variablen in einem Diagramm aufzulisten. Wenn Sie jedoch Zugriff auf die neuen Variablenobjekte haben (nennen wir sie v_6, v_7 und v_8), können Sie sie selektiv mit tf.initialize_variables()

init_new_vars_op = tf.initialize_variables([v_6, v_7, v_8])
sess.run(init_new_vars_op)

* Durch Versuch und Irrtum können die nicht initialisierten Variablen wie folgt identifiziert werden:

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)
# ...

... aber ich würde ein solches Verhalten nicht gutheißen :-).

31
mrry

UPDATE: TensorFlow 0.9 hat eine neue Methode, die all dies "repariert", jedoch nur, wenn Sie einen VariableScope verwenden und reuse auf True gesetzt ist. tf.report_uninitialized_variables die in einer Zeile mit sess.run( tf.initialize_variables( list( tf.get_variable(name) for name in sess.run( tf.report_uninitialized_variables( tf.all_variables( ) ) ) ) ) ) verwendet werden können

oder intelligenter durch die Möglichkeit, die Variablen anzugeben, deren Initialisierung erwartet wird:

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

Dies ist immer noch weniger ideal als tatsächlich zu wissen, welche Variablen initialisiert sind und welche nicht, und kümmert sich darum richtig, aber im Falle einer Fehlleitung wie den optim-Klassen (siehe unten) kann es schwierig sein, dies zu vermeiden.

Beachten Sie auch, dass tf.initialize_variables tf.report_uninitialized_variables nicht auswerten kann. Daher müssen beide im Kontext der Sitzung ausgeführt werden, um zu funktionieren.


Es gibt einen uneleganten, aber prägnanten Weg, dies zu tun. Bevor Sie Ihre neuen Variablen einführen, führen Sie temp = set(tf.all_variables()) und anschließend sess.run(tf.initialize_variables(set(tf.all_variables()) - temp)) aus. Diese zusammen initialisieren nur alle Variablen, die nach der Zuweisung des temporären Werts erstellt wurden.

Ich habe mit Transfer-Lernen gespielt, also wollte ich auch einen schnellen Weg, aber dies ist der beste Weg, den ich finden konnte. Vor allem, wenn Sie Dinge wie AdamOptimizer verwenden, der Ihnen keinen einfachen (oder auch nicht sicheren) Zugriff auf die verwendeten Variablen bietet. Das Folgende zeigt sich also tatsächlich in meinem Code. (Ich initialisiere die Variablen der neuen Ebene explizit und führe sie einmal aus, um den Anfangsfehler vor dem Übungslernen anzuzeigen. Nur zur Überprüfung der Integrität.)

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

Und es löst alle meine Probleme.

EDIT:@ Lifu_Huangs Antwort gibt den richtigen Weg an, um mein Problem zu beheben. Theoretisch sollten Sie tf.train.Optimizer.get_slot_names und tf.train.Optimizer.get_slot verwenden:

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()])

Dies gibt mir jedoch AttributeError: 'NoneType' object has no attribute 'initializer'. Ich werde Änderungen vornehmen, wenn ich herausgefunden habe, was ich falsch gemacht habe, damit Sie meine Fehler nicht machen.

31
Poik

TF hat keine Funktion, die genau das tut, was Sie wollen , aber Sie können leicht eine schreiben:

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

Hier extrahiere ich alle globale Variablen , iteriere sie alle und überprüfe, ob sie bereits initialisiert sind. Danach erhalte ich eine Liste von nicht initialisierten Variablen, die ich initialisieren . Ich drucke auch Variablen, die ich zum Debuggen initialisieren werde.


Sie können leicht überprüfen, ob es wie erwartet funktioniert:

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

Dadurch werden alle unitialisierten Variablen gedruckt, bevor sie initialisiert werden, und der letzte sess.run stellt sicher, dass Sie davon überzeugt sind, dass alle Variablen initialisiert wurden.


Sie können auch tf.report_uninitialized_variables() verwenden, um eine ähnliche Funktion zu schreiben. Eine Skizze davon ist hier .

26
Salvador Dali

Ich habe mir eine Methode für TensorFlow r0.11 ausgedacht:

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]
4
平芜泫

Für den Fall @Poik, wenn Variablen von Optimierern erstellt werden, sodass auf sie nicht direkt zugegriffen werden kann, ist eine sauberere Lösung die Verwendung von tf.train.Optimizer.get_slot

Einige Optimierungsunterklassen, wie MomentumOptimizer und AdagradOptimizer, ordnen und verwalten zusätzliche Variablen, die den zu trainierenden Variablen zugeordnet sind. Diese werden als Slots bezeichnet. Sie können tf.train.Optimizer.get_slot_names() verwenden, um alle Slot-Namen eines Optimierers abzurufen, und anschließend tf.train.Optimizer.get_slot, um die für diese Slots zugewiesene Variable zu erhalten.

4
Lifu Huang

Wenn Sie nur einen einzelnen Tensor (z. B. tf.Variable) initialisieren möchten, der nicht mit tf.global_variables_initializer() initialisiert wurde, können Sie your_tensor.initializer in sess.run() wie im folgenden Beispiel verwenden:

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.]]
1
kmario23

Ich denke, der einfachste Weg besteht darin, zuerst alle Trainingsoperatoren zu erstellen und anschließend Variablen zu initialisieren.

Ich habe zum Beispiel das Problem des schichtweisen Trainings mit Adam Optimizer folgendermaßen gelöst:

 # 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())
0