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:
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)
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)
Just for Sanity werde ich den Unterschied zwischen den beiden Grundstücke sein, dass sie die gleichen sind ...
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)
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)
Sie sehen sich ziemlich ähnlich. Aber (denke ich) sollten sie genau gleich sein. Schauen wir uns den Unterschied sehen ...
plot_values(resultA - resultB)
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?
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. –