TensorFlow-Tutorial (TensorFlow-Mechanik 101) https://www.tensorflow.org/versions/master/tutorials/mnist/tf/index.html#tensorflow-mechanics-101 Es ist eine Übersetzung von. Wir freuen uns darauf, auf Übersetzungsfehler hinzuweisen.
Code: tensorflow / examples / tutorials / mnist /
Das Ziel dieses Tutorials ist es, Ihnen zu zeigen, wie Sie mit TensorFlow ein einfaches neuronales Feedforward-Netzwerk zum Klassifizieren handgeschriebener Zahlen mithilfe eines (klassischen) MNIST-Datensatzes trainieren und auswerten können. Die Zielgruppe für dieses Tutorial sind diejenigen mit Erfahrung im maschinellen Lernen, die an der Verwendung von TensorFlow interessiert sind.
Diese Tutorials sind nicht dazu gedacht, maschinelles Lernen im Allgemeinen zu lehren.
Stellen Sie sicher, dass Sie die Prozedur Install TensorFlow (http://www.tensorflow.org/get_started/os_setup.html) befolgen.
In diesem Tutorial beziehen wir uns auf die folgenden Dateien:
Datei | Zweck |
---|---|
mnist.py | Vollständig gekoppelter MNIST-Modellbaucode. |
fully_connected_feed.py | Der Hauptcode, der das mit dem Feed-Wörterbuch erstellte MNIST-Modell mit dem heruntergeladenen Datensatz trainiert. |
Führen Sie die Datei full_connected_feed.py direkt aus, um mit dem Training zu beginnen:
python fully_connected_feed.py
MNIST ist ein klassisches Problem beim maschinellen Lernen. Das Problem besteht darin, ein 28 x 28 Pixel großes Graustufenbild handgeschriebener Zahlen zu betrachten und zu bestimmen, welche der Zahlen 0 bis 9 das Bild darstellt.
Weitere Informationen finden Sie auf der MNIST-Seite von Yann LeCun (http://yann.lecun.com/exdb/mnist/) oder in der MNIST-Visualisierung von Chris Olah (http://colah.github.io/posts/). 2014-10-Visualizing-MNIST /).
Zu Beginn der Methode run_training () überprüft die Funktion input_data.read_data_sets (), ob die richtigen Daten in den lokalen Trainingsordner heruntergeladen wurden, entpackt die Daten und gibt ein Wörterbuch mit DataSet-Instanzen zurück.
data_sets = input_data.read_data_sets(FLAGS.train_dir, FLAGS.fake_data)
Hinweis: Das Flag fake_data wird für Unit-Tests verwendet und kann hier ignoriert werden.
Datensatz | Zweck |
---|---|
data_sets.train | 55.000 Bilder und Etiketten für das Haupttraining. |
data_sets.validation | 5000 Bilder und Etiketten zur iterativen Überprüfung der Trainingsgenauigkeit. |
data_sets.test | 10000 Bilder und Etiketten für den endgültigen Test der Trainingsgenauigkeit. |
Weitere Informationen zu den Daten finden Sie im Download-Tutorial (http://www.tensorflow.org/tutorials/mnist/download/index.html).
Die Funktion placeholder_inputs () definiert zwei tf.placeholder, die die Form der Eingabe definieren, z. B. batch_size, im Rest des Diagramms. ) Erstellen Sie eine Operation. Das eigentliche Trainingsmuster wird darin eingespeist.
images_placeholder = tf.placeholder(tf.float32, shape=(batch_size,
IMAGE_PIXELS))
labels_placeholder = tf.placeholder(tf.int32, shape=(batch_size))
In der folgenden Trainingsschleife werden alle Bild- und Etikettendatensätze bei jedem Schritt so geschnitten, dass sie zu batch_size passen, an diese Platzhalter angepasst und dann mit dem Parameter feed_dict sess.run (). An die Funktion übergeben.
Nach dem Erstellen der Datenplatzhalter wird das Diagramm aus der Datei mnist.py nach einem dreistufigen Muster erstellt: Inferenz (), Verlust (), Training ().
Die Funktion inference () erstellt nach Bedarf ein Diagramm, um einen Tensor zurückzugeben, der die vorhergesagte Ausgabe enthält.
Diese Funktion verwendet einen Bildplatzhalter als Eingabe. Erstellen Sie zunächst eine vollständig verbundene Schicht mit ReLu-Aktivierung, gefolgt von einer linearen Schicht mit 10 Knoten, die das Ausgabeprotokoll identifiziert.
Jede Ebene wird unter einem eindeutigen tf.name_scope erstellt. tf.name_scope fungiert als Präfix für Elemente, die in diesem Bereich erstellt wurden.
with tf.name_scope('hidden1'):
Innerhalb des definierten Bereichs werden die auf jeder Ebene verwendeten Gewichte und Verzerrungen als tf.Variable Instanzen gesucht. In Form erzeugt:
weights = tf.Variable(
tf.truncated_normal([IMAGE_PIXELS, hidden1_units],
stddev=1.0 / math.sqrt(float(IMAGE_PIXELS))),
name='weights')
biases = tf.Variable(tf.zeros([hidden1_units]),
name='biases')
Wenn sie beispielsweise im Bereich hidden1 erstellt werden, lautet der eindeutige Name für die Variable weight "hidden1 / weight".
Jede Variable erhält im Rahmen ihrer Konstruktion eine Initialisierungsoperation.
In den häufigsten Fällen wie dem obigen werden die Gewichte mit tf.truncated_normal initialisiert, um die Form des zweidimensionalen Tensors zu erhalten. halt. Die erste Dimension ist die Anzahl der Einheiten in der Ebene, aus der die Gewichte kombiniert werden, und die zweite Dimension ist die Anzahl der Einheiten in der Ebene, zu der die Gewichte kombiniert werden. In der ersten Ebene mit dem Namen hidden1 lautet das Gewicht [IMAGE_PIXELS, hidden1_units], da die Bildeingabe und die Ebene hidden1 kombiniert werden. Der Initialisierer tf.truncated_normal erzeugt eine zufällige Verteilung mit einem gegebenen Mittelwert und einer gegebenen Standardabweichung.
Die Verzerrung wird mit tf.zeros initialisiert, um sicherzustellen, dass alles mit Nullwerten beginnt. Seine Form ist einfach die Anzahl der Einheiten in der Ebene, an die er gebunden ist.
Drei Hauptoperationen beim Umschließen von zwei [tf.matmul] für verborgene Ebenen (http://www.tensorflow.org/api_docs/python/math_ops.html#matmul) tf.nn.relu und tf.matmul für die Protokollierung wiederum tf verbunden mit Eingabeplatzhaltern oder Ausgabetensoren für jede Ebene Erstellt mit einer .Variable-Instanz.
hidden1 = tf.nn.relu(tf.matmul(images, weights) + biases)
hidden2 = tf.nn.relu(tf.matmul(hidden1, weights) + biases)
logits = tf.matmul(hidden2, weights) + biases
Schließlich wird ein Logit-Tensor zurückgegeben, der die Ausgabe enthält.
Die Funktion loss () erstellt das Diagramm weiter, indem die erforderlichen Verlustoperationen hinzugefügt werden.
Zunächst wird der Wert von label_placeholder in eine 64-Bit-Ganzzahl konvertiert. Anschließend werden automatisch 1-Hot-Labels aus label_placeholder und [tf.nn.sparse_softmax_cross_entropy_with_logits](https: // www.) Erstellt, um diese 1-Hot-Labels mit dem Ausgabeprotokoll der Funktion inference () zu vergleichen. tensorflow.org/versions/master/api_docs/python/nn.html#sparse_softmax_cross_entropy_with_logits) Operation wurde hinzugefügt.
labels = tf.to_int64(labels)
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(
logits, labels, name='xentropy')
Dann als Gesamtverlust tf.reduce_mean, um den Durchschnitt der Kreuzentropiewerte entlang der Batch-Dimension (erste Dimension) zu erhalten. ) Verwenden Sie die.
loss = tf.reduce_mean(cross_entropy, name='xentropy_mean')
Es gibt dann einen Tensor zurück, der den Verlustwert enthält.
Hinweis: Cross-Entropy ist eine auf Informationstheorie basierende Idee, die zeigt, wie schlecht es ist, an Vorhersagen neuronaler Netze für eine bestimmte Wahrheit zu glauben. Weitere Informationen finden Sie im Blogbeitrag zum Visual Information Theorem. (Http://colah.github.io/posts/2015-09-Visual-Information/ )
Die Funktion training () fügt die erforderlichen Operationen hinzu, um den Verlust aufgrund der Gradientenabstiegsmethode zu minimieren.
Nehmen Sie zunächst den Verlusttensor aus der Funktion loss () und übergeben Sie ihn an tf.scalar_summary. Diese Operation erzeugt bei Verwendung mit SummaryWriter (siehe unten) einen Zusammenfassungswert in der Ereignisdatei. Hier veröffentlichen wir bei jedem Export der Zusammenfassung eine Momentaufnahme des Verlustwerts.
tf.scalar_summary(loss.op.name, loss)
Instanziieren Sie anschließend tf.train.GradientDescentOptimizer. tf.train.GradientDescentOptimizer wendet den Gradienten entsprechend der angeforderten Lernrate an.
optimizer = tf.train.GradientDescentOptimizer(learning_rate)
Generieren Sie dann eine Variable, die die Zähler für die globalen Trainingsschritte enthält, und verwenden Sie die Operation minimieren (). .. Die Operation minim () aktualisiert die trainierbaren Gewichte des Systems und erhöht die Schritte. Konventionell wird diese Operation als train_op bezeichnet und von einer TensorFlow-Sitzung ausgeführt, um einen vollständigen Trainingsschritt auszulösen (siehe unten).
global_step = tf.Variable(0, name='global_step', trainable=False)
train_op = optimizer.minimize(loss, global_step=global_step)
Gibt einen Tensor zurück, der die Ausgabe der Trainingsoperation enthält.
Sobald das Diagramm erstellt wurde, kann es iterativ trainiert und in einer Schleife ausgewertet werden, die vom Benutzercode in full_connected_feed.py gesteuert wird.
Die Funktion run_training () beginnt mit dem Befehl python with. Hierbei handelt es sich um einen globalen tf.Graph, der standardmäßig alle erstellten Operationen verwendet. #Graph) Gibt an, dass es einer Instanz zugeordnet wird.
with tf.Graph().as_default():
tf.Graph ist eine Sammlung von Operationen, die zusammen als Gruppe ausgeführt werden können. Meistens verwenden Sie TensorFlow und verlassen sich nur auf ein einziges Standarddiagramm.
Eine komplexere Verwendung mit mehreren Diagrammen ist möglich, geht jedoch über den Rahmen dieses einfachen Lernprogramms hinaus.
Wenn Sie alle bereit sind, alle erforderlichen Vorgänge zu erstellen und zu generieren, erstellen Sie eine tf.Session, um das Diagramm auszuführen. Ich werde.
sess = tf.Session()
Alternativ können Sie es in einem with-Block für den Gültigkeitsbereich generieren:
with tf.Session() as sess:
Ein leeres Sitzungsargument gibt an, dass Sie die lokale Standardsitzung anhängen (oder erstellen) möchten, wenn sie nicht erstellt wurde.
Unmittelbar nach dem Erstellen der Sitzung werden alle tf.Variable-Instanzen einzeln aufgerufen, indem sess.run () aufgerufen wird. Es wird durch die Initialisierungsoperation von initialisiert.
init = tf.initialize_all_variables()
sess.run(init)
Die Methode sess.run () führt die vollständige Teilmenge der Diagramme aus, die den als Parameter übergebenen Operationen entsprechen. Ich werde. In diesem ersten Aufruf lautet die Init-Operation tf.group und enthält nur variable Initialisierer. Der Rest des Diagramms wird hier nicht ausgeführt, sondern in der folgenden Trainingsschleife.
Nach dem Initialisieren der Variablen in der Sitzung können Sie mit dem Training beginnen.
Der Benutzercode steuert die schrittweise Schulung. Im Folgenden finden Sie die einfachste Schleife für nützliche Schulungen:
for step in xrange(FLAGS.max_steps):
sess.run(train_op)
Die Schleife in diesem Tutorial ist jedoch etwas kompliziert. Dies liegt daran, dass Sie bei jedem Schritt die Eingabedaten so aufteilen müssen, dass sie zu den zuvor generierten Platzhaltern passen.
Erstellen Sie bei jedem Schritt ein Feed-Wörterbuch. Dieses Wörterbuch enthält den im Trainingsschritt verwendeten Beispielsatz und wird von den Platzhaltern eingegeben, die ihn darstellen.
Die Funktion fill_feed_dict () fragt das angegebene DataSet ab, um den nächsten Satz von Bildern und Beschriftungen in Batchgröße zu erhalten. Der Tensor, der zum Platzhalter passt, ist mit dem folgenden Bild oder Etikett gefüllt.
images_feed, labels_feed = data_set.next_batch(FLAGS.batch_size,
FLAGS.fake_data)
Erstellt ein Python-Wörterbuchobjekt mit dem Platzhalter als Schlüssel und dem entsprechenden Feed-Tensor als Wert.
feed_dict = {
images_placeholder: images_feed,
labels_placeholder: labels_feed,
}
Dieses Wörterbuch wird an den Parameter feed_dict der Funktion sess.run () übergeben, um ein Eingabebeispiel für die Trainingsschritte bereitzustellen.
Der Code gibt zwei Werte an, die beim Ausführen des Aufrufs abgerufen werden sollen: [train_op, loss].
for step in xrange(FLAGS.max_steps):
feed_dict = fill_feed_dict(data_sets.train,
images_placeholder,
labels_placeholder)
_, loss_value = sess.run([train_op, loss],
feed_dict=feed_dict)
Da zwei Werte abgerufen werden müssen, gibt sess.run () einen Taple mit zwei Elementen zurück. Jeder Tensor in der abgerufenen Werteliste, der dem numpy-Array im zurückgegebenen Taple entspricht, wird während dieses Trainingsschritts mit dem Wert dieses Tensors gefüllt. Da train_op eine Operation ohne Ausgabewert ist, ist das entsprechende Element des zurückgegebenen Taples None, sodass es verworfen wird. Der Wert des Verlusttensors ist jedoch NaN, wenn das Modell während des Trainings abweicht. Erfassen Sie ihn daher zur Protokollierung.
Selbst wenn das Training erfolgreich ist, ohne NaN zu werden, gibt die Trainingsschleife alle 100 Schritte einen kurzen Statustext aus, um den Benutzer über den Trainingsstatus zu informieren.
if step % 100 == 0:
print 'Step %d: loss = %.2f (%.3f sec)' % (step, loss_value, duration)
Alle Zusammenfassungen (in diesem Fall nur eine) sind Diagramme, da sie die von [TensorBoard] verwendeten Ereignisdateien veröffentlichen (http://www.tensorflow.org/how_tos/summaries_and_tensorboard/index.html). In einem einzigen Vorgang während der Erstellungsphase von gesammelt.
summary_op = tf.merge_all_summaries()
Nachdem die Sitzung erstellt wurde, können Sie tf.train.SummaryWriter instanziieren, um eine Ereignisdatei zu schreiben, die das Diagramm selbst und die Zusammenfassungswerte enthält.
summary_writer = tf.train.SummaryWriter(FLAGS.train_dir, sess.graph)
Schließlich wird die Ereignisdatei bei jeder Ausführung von summary_op mit einem neuen Zusammenfassungswert aktualisiert und die Ausgabe an die Funktion add_summary () des Schreibers übergeben.
summary_str = sess.run(summary_op, feed_dict=feed_dict)
summary_writer.add_summary(summary_str, step)
Sobald die Ereignisdatei geschrieben wurde, kann TensorBoard für den Trainingsordner ausgeführt werden, um die Zusammenfassungswerte anzuzeigen.
Hinweis: Weitere Informationen zum Erstellen und Ausführen von Tensorboard finden Sie im beiliegenden Tutorial Tensorboard: Trainingsvisualisierung (http://www.tensorflow.org/how_tos/summaries_and_tensorboard/index.html).
[Tf.train.Saver](http://www.tensorflow.org/api_docs/python/state_ops.html], um eine Prüfpunktdatei zu veröffentlichen, mit der das Modell für zusätzliche Schulungen und Bewertungen wiederhergestellt werden kann. #Saver) wird instanziiert.
saver = tf.train.Saver()
Die Trainingsschleife ruft regelmäßig die Methode saver.save () auf, um eine Prüfpunktdatei unter Verwendung der aktuellen Werte aller trainierbaren Variablen in das Trainingsverzeichnis zu schreiben.
saver.save(sess, FLAGS.train_dir, global_step=step)
In Zukunft können Sie das Training mit der Methode saver.restore () fortsetzen, mit der die Modellparameter neu geladen werden.
saver.restore(sess, FLAGS.train_dir)
Der Code versucht, das Modell für jeden Trainings- und Testdatensatz alle 1000 Schritte auszuwerten. Die Funktion do_eval () wird dreimal für die Trainings-, Validierungs- und Testdatensätze aufgerufen.
print 'Training Data Eval:'
do_eval(sess,
eval_correct,
images_placeholder,
labels_placeholder,
data_sets.train)
print 'Validation Data Eval:'
do_eval(sess,
eval_correct,
images_placeholder,
labels_placeholder,
data_sets.validation)
print 'Test Data Eval:'
do_eval(sess,
eval_correct,
images_placeholder,
labels_placeholder,
data_sets.test)
Beachten Sie, dass Auswertungen für data_sets.test normalerweise für eine komplexere Verwendung isoliert sind. Dies liegt daran, dass data_sets.test erst nach einer erheblichen Menge an Hypertuning überprüft wird. Bewerten Sie alle Daten auf einfache und kleine MNIST-Probleme.
Bevor wir in die Trainingsschleife eintreten können, müssen wir eine Eval-Operation erstellen. Rufen Sie zum Erstellen einer Eval-Operation die Evaluierungsfunktion () von mnist.py mit denselben Logistik- / Label-Parametern wie die Funktion loss () auf.
eval_correct = mnist.evaluation(logits, labels_placeholder)
Die Evaluierungsfunktion () generiert einfach die Operation tf.nn.in_top_k. tf.nn.in_top_k betrachtet die Ausgabe jedes Modells als korrekt und bewertet automatisch, wenn das wahre Label in den Top-K-Vorhersagen der Möglichkeit enthalten ist. Wir setzen den Wert von K auf 1, weil wir ihn nur dann für richtig halten, wenn die Vorhersage mit der wahren Bezeichnung übereinstimmt.
eval_correct = tf.nn.in_top_k(logits, labels, 1)
Sie können jetzt eine Schleife erstellen. Die Schleife füllt feed_dict und ruft sess.run () für die Operation eval_correct auf. Die Operation eval_correct wertet das Modell für einen bestimmten Datensatz aus.
for step in xrange(steps_per_epoch):
feed_dict = fill_feed_dict(data_set,
images_placeholder,
labels_placeholder)
true_count += sess.run(eval_correct, feed_dict=feed_dict)
Die Variable true_count aggregiert einfach alle Vorhersagen, die die Operation in_top_k korrekt ermittelt. Die Genauigkeit kann einfach berechnet werden, indem diese durch die Gesamtzahl der Proben dividiert wird.
precision = true_count / num_examples
print(' Num examples: %d Num correct: %d Precision @ 1: %0.04f' %
(num_examples, true_count, precision))
Recommended Posts