2017-11-02 2 views
1

Dies ist mein erster Beitrag hier, also hoffe ich, dass er den Richtlinien entspricht und auch für andere Menschen außer mir selbst interessant ist.Fügen Sie dem Rekonstruktionsverlust des Autoencoders einen benutzerdefinierten Verlust hinzu

Ich baue einen CNN-Autoencoder, der als Eingabe Matrizen von festen Größen mit dem Ziel verwendet, eine niederdimensionale Darstellung von ihnen zu bekommen (ich nenne sie Hashes hier). Ich möchte diese Hashes ähnlich machen, wenn die Matrizen ähnlich sind. Da nur ein paar meiner Daten beschriftet sind, möchte ich die Verlustfunktion zu einer Kombination aus zwei separaten Funktionen machen. Ein Teil wird der Rekonstruktionsfehler des Autoencoders sein (Dieser Teil arbeitet korrekt). Der andere Teil, ich will es für die etikettierten Daten sein. Da ich drei verschiedene Klassen haben werde, möchte ich, dass bei jedem Batch der Abstand zwischen Hash-Werten berechnet wird, die zur selben Klasse gehören (ich habe Probleme, dies zu implementieren).

Meine Bemühungen bisher:

X = tf.placeholder(shape=[None, 512, 128, 1], dtype=tf.float32) 
class1_indices = tf.placeholder(shape=[None], dtype=tf.int32) 
class2_indices = tf.placeholder(shape=[None], dtype=tf.int32) 
hashes, reconstructed_output = self.conv_net(X, weights, biases_enc, biases_dec, keep_prob) 
class1_hashes = tf.gather(hashes, class1_indices) 
class1_cost = self.calculate_within_class_loss(class1_hashes) 
class2_hashes = tf.gather(hashes, class2_indices) 
class2_cost = self.calculate_within_class_loss(class2_hashes) 
loss_all = tf.reduce_sum(tf.square(reconstructed_output - X)) 
loss_labeled = class1_cost + class2_cost 
loss_op = loss_all + loss_labeled 
optimizer = tf.train.AdagradOptimizer(learning_rate=learning_rate) 
train_op = optimizer.minimize(loss_op) 

Wo calclulate_within_class_loss eine separate Funktion, die ich erstellt. Ich habe es derzeit nur für den Unterschied des ersten Hashs einer Klasse mit anderen Hashes dieser Klasse im selben Batch implementiert, allerdings bin ich mit meiner aktuellen Implementierung nicht zufrieden und es scheint, dass es nicht funktioniert.

def calculate_within_class_loss(self, hash_values): 
    first_hash = tf.slice(hash_values, [0, 0], [1, 256]) 
    total_loss = tf.foldl(lambda d, e: d + tf.sqrt(tf.reduce_sum(tf.square(tf.subtract(e, first_hash)))), hash_values, initializer=0.0) 
    return total_loss 

Also, ich habe zwei Fragen/Themen:

  1. Gibt es eine einfache Möglichkeit, den Abstand von jedem rohen mit allen anderen raws in einem Tensor zu berechnen?
  2. Meine aktuelle Implementierung von innerhalb der Klasse berechnen Entfernung, auch wenn es nur für das erste Element mit anderen Elementen ist, wird mir eine "Nan" geben, wenn ich versuche, es zu optimieren.

Vielen Dank für Ihre Zeit und :)

+0

Was ist die Form von 'Klasse? _hashes'? –

+0

Entschuldigung. Ich habe hier nur einen Teil des Codes veröffentlicht, von dem ich dachte, dass er für die Frage relevant wäre. Da Hashes die Form [None, 256] haben, hat die Klasse? _hashs auch die Form [?, 256], abhängig davon, wie viele Indizes dieser Klasse ich im aktuellen Batch habe. –

Antwort

0

Im Beispielcode hilft, kalkulieren Sie die Summe des euklidischen Abstandes zwischen den Punkten.

Dazu werden Sie in einer Schleife über den gesamten Datensatz haben und O(n^2 * m) Berechnungen und O(n^2 * m) Raum, das heißt Tensorflow Graph Operationen haben. Hier , n ist die Anzahl der Vektoren und m ist die Größe des Hash, also 256.

Wenn Sie jedoch Ihr Objekt in den folgenden ändern könnten:

Dann können Sie verwenden Sie die nifty relationship between the squared Euclidean distance and the variance und schreiben Sie die gleiche Berechnung wie

Wo mu_k ist der Durchschnittswert der kten Koordinate für den Cluster.

Damit können Sie den Wert in O(n * m) Zeit und O(n * m) Tensorflow-Operationen berechnen.

Dies wäre der Weg zu gehen, wenn Sie diese Änderung denken (d. H.von euklidischer Distanz zu quadrierter euklidischer Distanz) wirkt sich nicht nachteilig auf Ihre Verlustfunktion aus.

Verwandte Themen