2016-10-25 2 views
1

Ich versuche, den ersten Teil des Google Blogeintrags Inceptionism: Going Deeper into Neural Networks in TensorFlow zu implementieren. Bis jetzt habe ich mehrere Quellen gefunden, die es entweder in natural language erklären oder auf other parts or give code snippets for other frameworks konzentrieren. Ich verstehe die Idee der Optimierung eines zufälligen Eingabebildes in Bezug auf eine Klasse vor und auch die Mathematik dahinter in diesem paper, section 2 gegeben, aber ich bin nicht in der Lage, es selbst mit TensorFlow zu implementieren.Eingabebild mit Klasse vor optimieren

Von this SO question und nützlichen Kommentar von etarion, ich weiß jetzt, dass Sie eine Liste von Variablen für das Optimierungsprogramm geben können, während alle anderen Variablen unberührt sind. Wenn jedoch der Optimierer ein zufälliges Bild geben als eine Variable führt zu

File "mnist_test.py", line 101, in main 
    optimizer2 = tf.train.AdamOptimizer(learning_rate).minimize(-cost, var_list=[rnd_img]) 
File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/training/optimizer.py", line 198, in minimize 
    name=name) 
File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/training/optimizer.py", line 309, in apply_gradients 
    (converted_grads_and_vars,)) 
ValueError: No gradients provided for any variable: ((None,<tensorflow.python.ops.variables.Variable object at 0x7feac1870410>),) 

Für Testzwecke verwendete ich eine abgespeckte MNIST Beispiel. Ich habe versucht, es so kurz wie möglich zu halten, während immer noch lesbar und ausführbar sein:

def main(): 
    # parameters 
    learning_rate = 0.001 
    train_batches = 1000 
    batch_size = 128 
    display_step = 50 

    # net parameters 
    n_input = 784 #28x28 
    n_classes = 10 
    keep_prob = 0.75 

    weights = { 
     'wc1': tf.Variable(tf.truncated_normal([5, 5, 1, 32])), 
     'wc2': tf.Variable(tf.truncated_normal([5, 5, 32, 64])), 
     'wd1': tf.Variable(tf.truncated_normal([7*7*64, 1024])), 
     'out': tf.Variable(tf.truncated_normal([1024, n_classes])) 
    } 

    biases = { 
     'bc1': tf.Variable(tf.constant(0.1, shape=[32])), 
     'bc2': tf.Variable(tf.constant(0.1, shape=[64])), 
     'bd1': tf.Variable(tf.constant(0.1, shape=[1024])), 
     'out': tf.Variable(tf.constant(0.1, shape=[n_classes])) 
    } 

    # tf inputs 
    x = tf.placeholder(tf.float32, [None, n_input]) 
    y = tf.placeholder(tf.float32, [None, n_classes]) 
    dropout = tf.placeholder(tf.float32) 

    # create net 
    net = create_net(x, weights, biases, keep_prob) 

    # define loss 
    cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(net, y)) 

    # define optimizer 
    optimizer = tf.train.AdamOptimizer(learning_rate).minimize(cost) 

    # evaluation 
    pred_correct = tf.equal(tf.argmax(net, 1), tf.argmax(y, 1)) 
    accuracy = tf.reduce_mean(tf.cast(pred_correct, tf.float32)) 

    print "loading mnist data" 
    from tensorflow.examples.tutorials.mnist import input_data 
    mnist = input_data.read_data_sets("/tmp/data/", one_hot=True) 

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

    for i in xrange(train_batches): 
     batch_x, batch_y = mnist.train.next_batch(batch_size) 

     sess.run(optimizer, feed_dict={x: batch_x, y: batch_y, dropout: keep_prob}) 

     if i % display_step == 0: 
      loss, acc = sess.run([cost, accuracy], feed_dict={x: batch_x, y: batch_y, dropout: 1.0}) 
      print "batch: %i, loss: %.5f, accuracy: %.5f" % (i, loss, acc) 

    acc = sess.run(accuracy, feed_dict={x: mnist.test.images, y: mnist.test.labels, dropout: 1.0}) 
    print "test accuracy: %.5f" % (acc) 

    # ====== this is where the reconstruction begins ===== 

    rnd_img = tf.Variable(tf.random_normal([1, n_input])) 
    one_hot = np.zeros(10) 
    one_hot[4] = 1; 

    # the next line causes the error 
    optimizer2 = tf.train.AdamOptimizer(learning_rate).minimize(-cost, var_list=[rnd_img]) 

    for i in xrange(1000): 
     session.run(optimizer2, feed_dict={x: rnd_img, y: one_hot, dropout: 1.0}) 

    sess.close() 

if __name__ == "__main__": 
    main() 

Die Helferfunktionen I verwendet:

def create_net(x, weights, biases, dropout): 
    x = tf.reshape(x, shape=[-1, 28, 28, 1]) 

    conv1 = conv2d_relu(x, weights['wc1'], biases['bc1']) 
    conv1 = maxpool2d(conv1, 2) 

    conv2 = conv2d_relu(conv1, weights['wc2'], biases['bc2']) 
    conv2 = maxpool2d(conv2, 2) 

    fc1 = fullyconnected_relu(conv2, weights['wd1'], biases['bd1']) 
    fc1 = tf.nn.dropout(fc1, dropout) 

    out = tf.add(tf.matmul(fc1, weights['out']), biases['out']) 

    return out 

def conv2d_relu(x, W, b, stride=1): 
    conv = tf.nn.conv2d(x, W, strides=[1, stride, stride, 1], padding='SAME') 
    conv = tf.nn.bias_add(conv, b) 
    return tf.nn.relu(conv) 

def maxpool2d(x, k=2, stride=2, padding='VALID'): 
    return tf.nn.max_pool(x, ksize=[1, k, k, 1], strides=[1, stride, stride, 1], padding=padding) 

def fullyconnected_relu(x, W, b): 
    fc = tf.reshape(x, [-1, W.get_shape().as_list()[0]]) 
    fc = tf.add(tf.matmul(fc, W), b) 
    fc = tf.nn.relu(fc) 

Ich habe einige Quellen gefunden sagen, dass dieser Fehler auftritt, wenn es Kein Pfad innerhalb des Berechnungsgraphen zwischen der Ausgabe und den zu optimierenden Variablen, aber ich sehe nicht, warum dies hier der Fall sein sollte.

Meine Fragen sind:

  1. Warum ist nicht der Optimierer keine Steigungen anwenden können?
  2. Ist das der richtige Weg, um die Visualisierung einer Klasse zu implementieren?

Vielen Dank im Voraus.

Edit:

Hier ist der vollständige Code wieder, nach dem Einbau der akzeptierten Antwort (für jeden, der interessiert ist). Wie auch immer, die Ergebnisse sind immer noch nicht wie erwartet, da das Skript im Grunde nach 100000 Rekonstruktionsrunden zufällige Bilder erzeugt. Ideen sind willkommen.

import tensorflow as tf 
import numpy as np 
import skimage.io 

def conv2d_relu(x, W, b, stride=1): 
    conv = tf.nn.conv2d(x, W, strides=[1, stride, stride, 1], padding='SAME') 
    conv = tf.nn.bias_add(conv, b) 
    return tf.nn.relu(conv) 

def maxpool2d(x, k=2, stride=2, padding='VALID'): 
    return tf.nn.max_pool(x, ksize=[1, k, k, 1], strides=[1, stride, stride, 1], padding=padding) 

def fullyconnected_relu(x, W, b): 
    fc = tf.reshape(x, [-1, W.get_shape().as_list()[0]]) 
    fc = tf.add(tf.matmul(fc, W), b) 
    fc = tf.nn.relu(fc) 

    return fc; 

def create_net(x, weights, biases, dropout): 
    x = tf.reshape(x, shape=[-1, 28, 28, 1]) 

    conv1 = conv2d_relu(x, weights['wc1'], biases['bc1']) 
    conv1 = maxpool2d(conv1, 2) 

    conv2 = conv2d_relu(conv1, weights['wc2'], biases['bc2']) 
    conv2 = maxpool2d(conv2, 2) 

    fc1 = fullyconnected_relu(conv2, weights['wd1'], biases['bd1']) 
    fc1 = tf.nn.dropout(fc1, dropout) 

    out = tf.add(tf.matmul(fc1, weights['out']), biases['out']) 

    return out 

def save_image(img_data, name): 
    img = img_data.reshape(28,28) 

    mi = np.min(img) 
    ma = np.max(img) 

    img = (img-mi)/(ma-mi) 
    skimage.io.imsave(name, img) 

def main(): 
    # parameters 
    learning_rate = 0.001 
    train_batches = 1000 
    batch_size = 100 
    display_step = 50 

    # net parameters 
    n_input = 784 #28x28 
    n_classes = 10 
    keep_prob = 0.75 

    weights = { 
     'wc1': tf.Variable(tf.truncated_normal([5, 5, 1, 32])), 
     'wc2': tf.Variable(tf.truncated_normal([5, 5, 32, 64])), 
     'wd1': tf.Variable(tf.truncated_normal([7*7*64, 1024])), 
     'out': tf.Variable(tf.truncated_normal([1024, n_classes])) 
    } 

    biases = { 
     'bc1': tf.Variable(tf.constant(0.1, shape=[32])), 
     'bc2': tf.Variable(tf.constant(0.1, shape=[64])), 
     'bd1': tf.Variable(tf.constant(0.1, shape=[1024])), 
     'out': tf.Variable(tf.constant(0.1, shape=[n_classes])) 
    } 

    # tf inputs 
    x = tf.placeholder(tf.float32, [None, n_input]) 
    y = tf.placeholder(tf.float32, [None, n_classes]) 
    dropout = tf.placeholder(tf.float32) 

    # create net 
    net = create_net(x, weights, biases, dropout) 

    # define loss 
    cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(net, y)) 

    # define optimizer 
    optimizer = tf.train.AdamOptimizer(learning_rate).minimize(cost) 

    # evaluation 
    pred_correct = tf.equal(tf.argmax(net, 1), tf.argmax(y, 1)) 
    accuracy = tf.reduce_mean(tf.cast(pred_correct, tf.float32)) 

    print "loading mnist data" 
    from tensorflow.examples.tutorials.mnist import input_data 
    mnist = input_data.read_data_sets("/tmp/data/", one_hot=True) 

    sess = tf.Session() 

    sess.run(tf.initialize_all_variables()) 

    for i in xrange(train_batches): 
     batch_x, batch_y = mnist.train.next_batch(batch_size) 

     sess.run(optimizer, feed_dict={x: batch_x, y: batch_y, dropout: keep_prob}) 

     if i % display_step == 0: 
      loss, acc = sess.run([cost, accuracy], feed_dict={x: batch_x, y: batch_y, dropout: 1.0}) 
      print "batch: %i, loss: %.5f, accuracy: %.5f" % (i, loss, acc) 

    acc = sess.run(accuracy, feed_dict={x: mnist.test.images, y: mnist.test.labels, dropout: 1.0}) 
    print "test accuracy: %.5f" % (acc) 

    # reconstruction part 
    rnd_img = tf.Variable(tf.random_normal([1, n_input])) 

    one_hot = np.zeros((1, 10)) 
    one_hot[0,1] = 1; 

    net2 = create_net(rnd_img, weights, biases, dropout) 
    cost2 = -tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(net2, y)) 
    optimizer2 = tf.train.AdamOptimizer(learning_rate).minimize(cost2, var_list=[rnd_img]) 

    init_var_list = [] 

    for var in tf.all_variables(): 
     if(not tf.is_variable_initialized(var).eval(session=sess)): 
      init_var_list.append(var) 

    sess.run(tf.initialize_variables(init_var_list)) 

    save_image(rnd_img.eval(sess), "bevor.tiff") 

    for i in xrange(100000): 
     _, loss = sess.run([optimizer2, cost2], feed_dict={y: one_hot, dropout: 1.0}) 
     if(i%10000 == 0): 
      cur_img = rnd_img.eval(session=sess) 
      print "loss:", loss, "mi:", np.min(cur_img), "ma:", np.max(cur_img) 

    save_image(rnd_img.eval(sess), "after.tiff") 

    sess.close() 

if __name__ == "__main__": 
    main() 

Einige Erklärung: Nachdem die Grafik mit dem neuen Eingangsgröße und Optimierer Wiederaufbau, hatte ich die neuen Variablen zu initialisieren, dh die rnd_img und einige Hilfsvariablen, die vom Adam-Optimierer verwendet, damit die Schleife über all_variables() und Überprüfen auf Initialisierungsstatus. Wenn jemand einen eleganteren Weg kennt, lass es mich wissen. Oder vielleicht ist das der Grund, warum ich keine Ergebnisse bekomme?

Antwort

1

Der rnd_img muss Teil des Diagramms sein, das Sie optimieren. In Ihrem Fall erstellen Sie einfach eine Variable und weisen den Optimierer an, sie zu optimieren, aber die Variable ist nicht mit dem Verlust in der Grafik verbunden. Was Sie zum Beispiel tun können, ist einen anderen Aufruf von create_net mit rnd_image anstelle von x zu verwenden (aber mit den gleichen Gewichten!), Erstellen Sie die Kosten dafür und erstellen Sie dann eine Minimierungsoperation für diese Kosten. Dann füttern Sie zur Optimierung nur y ein.

+0

Das war es, danke. Alles läuft gut, aber leider nicht wie erwartet, d. H. Selbst nach 100000 Rekonstruktionen bekomme ich grundsätzlich noch ein zufälliges Bild, leicht modifiziert. Ist 100000 Runde nicht genug? Ich werde meine Frage aktualisieren und den geänderten Code hinzufügen. – thomas

+0

Ich habe gerade festgestellt, dass möglicherweise die Tatsache, dass ich die L2-Normalisierung auf dem Eingabebild in der Kostenfunktion weggelassen habe, das Problem verursachen könnte. Und ich habe auch über den Satz in dem Artikel nachgedacht, der besagt, dass sie den nicht normalisierten Klassenwert minimieren und nicht die Klasse posterior. Also versuchen Sie etwas wie cost2 = -tf.reduce_mean (tf.mul (net2, y)) + tf.nn.l2_loss (rnd_img). Macht das Sinn, oder? – thomas