2016-11-22 5 views
0

In dem Versuch, etwas über Tensorflow zu lernen, hatte ich einen Variations Auto Encoder gebaut, der funktioniert, aber ich bemerkte, dass ich nach dem Training unterschiedliche Ergebnisse von den Decodern bekam teilen sich die gleichen Variablen.Tensorflow Variablen wiederverwenden vor und nach dem Training

Ich habe zwei Decoder erstellt, weil ich zuerst gegen meinen Datensatz trainiere, den zweiten möchte ich schließlich eine neue Z-Codierung einspeisen, um neue Werte zu erzeugen.

Meine Überprüfung ist, dass ich in der Lage sein sollte, die Z-Werte, die aus dem Kodierungsprozess generiert wurden, an beide Decoder zu senden und gleiche Ergebnisse zu erhalten.

Ich habe 2 Decoder (D, D_new). D_new teilt den Variablenbereich von D.

vor dem Training, kann ich Werte in den Encoder (E) senden, um Ausgabewerte sowie die Z-Werte zu generieren, die es generiert (Z_gen).

Wenn ich Z_gen als Eingabe für D_new vor dem Training verwende, dann ist seine Ausgabe identisch mit der Ausgabe von D, was erwartet wird.

Nach einigen Iterationen des Trainings beginnt jedoch die Ausgabe von D verglichen mit D_new zu divergieren (obwohl sie ziemlich ähnlich sind).

Ich habe dies auf eine einfachere Version meines Codes gepaart, der den Fehler noch reproduziert. Ich frage mich, ob andere das gefunden haben und wo ich es korrigieren könnte.

Der folgende Code kann in einem jupyter Notebook ausgeführt werden. Ich verwende Tensorflow r0.11 und Python 3.5.0



    import numpy as np 
    import tensorflow as tf 
    import matplotlib 
    import matplotlib.pyplot as plt 
    import os 
    import pylab as pl 
    mgc = get_ipython().magic 
    mgc(u'matplotlib inline') 
    pl.rcParams['figure.figsize'] = (8.0, 5.0) 



    ##-- Helper function Just for visualizing the data 
    def plot_values(values, file=None): 
     t = np.linspace(1.0,len(values[0]),len(values[0])) 
     for i in range(len(values)): 
      plt.plot(t,values[i]) 
     if file is None: 
      plt.show() 
     else: 
      plt.savefig(file) 
     plt.close() 



    def encoder(input, n_hidden, n_z): 
     with tf.variable_scope("ENCODER"): 
      with tf.name_scope("Hidden"): 
       n_layer_inputs = input.get_shape()[1].value 
       n_layer_outputs = n_hidden 
       with tf.name_scope("Weights"): 
        w = tf.get_variable(name="E_Hidden", shape=[n_layer_inputs, n_layer_outputs], dtype=tf.float32) 
       with tf.name_scope("Activation"): 
        a = tf.tanh(tf.matmul(input,w)) 
       prevLayer = a 

      with tf.name_scope("Z"): 
       n_layer_inputs = prevLayer.get_shape()[1].value 
       n_layer_outputs = n_z 
       with tf.name_scope("Weights"): 
        w = tf.get_variable(name="E_Z", shape=[n_layer_inputs, n_layer_outputs], dtype=tf.float32) 
       with tf.name_scope("Activation"): 
        Z_gen = tf.matmul(prevLayer,w) 
     return Z_gen 

    def decoder(input, n_hidden, n_outputs, reuse=False): 
     with tf.variable_scope("DECODER", reuse=reuse): 
      with tf.name_scope("Hidden"): 
       n_layer_inputs = input.get_shape()[1].value 
       n_layer_outputs = n_hidden 
       with tf.name_scope("Weights"): 
        w = tf.get_variable(name="D_Hidden", shape=[n_layer_inputs, n_layer_outputs], dtype=tf.float32) 
       with tf.name_scope("Activation"): 
        a = tf.tanh(tf.matmul(input,w)) 
       prevLayer = a 

      with tf.name_scope("OUTPUT"): 
       n_layer_inputs = prevLayer.get_shape()[1].value 
       n_layer_outputs = n_outputs 
       with tf.name_scope("Weights"): 
        w = tf.get_variable(name="D_Output", shape=[n_layer_inputs, n_layer_outputs], dtype=tf.float32) 
       with tf.name_scope("Activation"): 
        out = tf.sigmoid(tf.matmul(prevLayer,w)) 
     return out 

Hier ist, wo die Tensorflow Graph-Setup ist:



    batch_size = 3 
    n_inputs = 100 
    n_hidden_nodes = 12 
    n_z = 2 

    with tf.variable_scope("INPUT_VARS"): 
     with tf.name_scope("X"): 
      X = tf.placeholder(tf.float32, shape=(None, n_inputs)) 
     with tf.name_scope("Z"): 
      Z = tf.placeholder(tf.float32, shape=(None, n_z)) 

    Z_gen = encoder(X,n_hidden_nodes,n_z) 

    D = decoder(Z_gen, n_hidden_nodes, n_inputs) 
    D_new = decoder(Z, n_hidden_nodes, n_inputs, reuse=True) 

    with tf.name_scope("COST"): 
     loss = -tf.reduce_mean(X * tf.log(1e-6 + D) + (1-X) * tf.log(1e-6 + 1 - D)) 
     train_step = tf.train.AdamOptimizer(0.001, beta1=0.5).minimize(loss) 

Ich Erzeugung eines Trainingssatz von 3 Proben von normalem Verteilungsrauschen mit 100 Datenpunkten und dann sortieren, um einfacher zu visualisieren:

enter image description here

Inbetriebnahme der Sitzung:



    sess = tf.InteractiveSession() 
    sess.run(tf.group(tf.initialize_all_variables(), tf.initialize_local_variables())) 

Schauen wir uns nur auf das, was das Netz erzeugt zunächst vor dem Training ...



    resultA, Z_vals = sess.run([D, Z_gen], feed_dict={X:train_data}) 
    plot_values(resultA) 

enter image description here

die Z erzeugten Werte Ziehen und Füttern sie zu D_new, die die Variablen von D wiederverwenden:



    resultB = sess.run(D_new, feed_dict={Z:Z_vals}) 
    plot_values(resultB) 

enter image description here

Just for Sanity werde ich den Unterschied zwischen den beiden Grundstücke sein, dass sie die gleichen sind ... enter image description here

Jetzt laufen 1000 Trainings Epochen und zeichnen das Ergebnis ...



    for i in range(1000): 
     _, resultA, Z_vals = sess.run([train_step, D, Z_gen], feed_dict={X:train_data}) 
    plot_values(resultA) 

enter image description here

können nun die gleichen Z-Werte zu D_new füttern und diese Ergebnisse zeichnen ...



    resultB = sess.run(D_new, feed_dict={Z:Z_vals}) 
    plot_values(resultB) 

enter image description here

Sie sehen sich ziemlich ähnlich. Aber (denke ich) sollten sie genau gleich sein. Schauen wir uns den Unterschied sehen ...



    plot_values(resultA - resultB) 

enter image description here

können Sie sehen, dass es jetzt eine gewisse Variation ist. Dies wird mit einem größeren Netzwerk bei komplexeren Daten viel dramatischer, zeigt sich aber immer noch in diesem einfachen Beispiel. Irgendwelche Hinweise auf was ist los?

+0

Ich bin nicht sicher, dass dies eine tatsächliche Antwort ist, denn ich sehe diese Ergebnisse immer noch in meinem komplexeren Beispiel. Aber ich finde, dass, wenn ich die Z_gen-Werte nach der Trainingsschleife wieder abspiele, die Ergebnisse von D und D_new übereinstimmen. Wenn ich dies mit komplexeren Daten (einem Trainingssatz von Sinuswellen) versuche, sehe ich immer noch etwas Variation. Es sieht so aus, als ob die Werte nach der Ausführung der run() - Methode sehr geringfügig geändert werden. –

Antwort

0

Es gibt einige Methoden (weiß nicht welche), die mit einem Startwert geliefert werden können. Abgesehen davon, bin ich nicht einmal sicher, ob der Trainingsprozess vollständig deterministisch ist, besonders wenn die GPU is involved einfach durch die Art der Parallelisierung.

Siehe this question.

0

Während ich keine vollständige Erklärung für den Grund, warum konnte ich mein Problem lösen, indem:

for i in range(1000): 
    _, resultA, Z_vals = sess.run([train_step, D, Z_gen], feed_dict={X:train_data}) 
plot_values(resultA) 

resultB = sess.run(D_new, feed_dict={Z:Z_vals}) 
plot_values(resultB) 
plot_values(resultA - resultB) 

zu ...

for i in range(1000): 
    _, resultA, Z_vals = sess.run([train_step, D, Z_gen], feed_dict={X:train_data}) 

resultA, Z_vals = sess.run([D, Z_gen], feed_dict={X:train_data}) 

plot_values(resultA) 

resultB = sess.run(D_new, feed_dict={Z:Z_vals}) 
plot_values(resultB) 
plot_values(resultA - resultB) 

Beachten Sie, dass ich einfach ran und extrahiert das Ergebnis und Z_vals ein letztes Mal, ohne die train_step.

Der Grund war ich immer noch Probleme in meinem komplexen Setup zu sehen, dass ich Bias-Variablen hatte (auch wenn sie auf 0,0 eingestellt wurden), die mit ...

b = tf.Variable(tf.constant(self.bias_k, shape=[n_layer_outputs], dtype=tf.float32)) 

erzeugt wurden Und das ist irgendwie bei der Verwendung von reuse mit tf.variable_scope nicht berücksichtigt. Also wurden Variablen technisch nicht wiederverwendet. Warum haben sie so ein Problem dargestellt, wenn sie auf 0,0 gesetzt sind? Ich bin mir nicht sicher.

Verwandte Themen