[PYTHON] Das MNIST-Tutorial von TensorFlow wurde mit der Bildeingabe kompatibel gemacht

Nachdem ich das TensorFlow MNIST-Tutorial ausprobiert hatte, dachte ich. .. .. "Es macht keinen großen Spaß, weil nur diese Genauigkeit angezeigt wird ..."

Mit anderen Worten, ich möchte so etwas tun

I "Welche Nummer denkst du ist das?" test.png

PC "Ich denke das ist 2 !!" Ich "richtige Antwort! Mein Partner !!"

Also habe ich ein Programm erstellt, das eine Vorhersage dafür zurückgibt, wenn ich ein handgeschriebenes Zahlenbild eingebe.

Ich habe gerade den Code des MNIST-Tutorials ein wenig geändert, damit ich [Deep MNIST for Experts] ausführen kann (http://tensorflow.classcat.com/2016/02/16/tensorflow-tutorials-deep-mnist-for-experts/). Muss.

Da ich am 5. zum ersten Mal Anfänger von TensorFlow bin, denke ich, dass es Fehler gibt, aber in diesem Fall würde ich es begrüßen, wenn Sie mir in den Kommentaren einen Rat geben könnten. Aber vorerst funktioniert das Programm gut.

Gesamtdurchfluss

  1. Lernen Sie die Verwendung des MNIST-Datensatzes und speichern Sie die Parameter
  2. Lesen Sie die gelernten Parameter und führen Sie eine handschriftliche Nummernerkennung durch

Nur das. Richtig? Ist es nicht einfach

Lernen Sie mit MNIST

train_mnist.py


import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import cv2
import numpy as np
#Laden Sie MNIST-Daten herunter
mnist = input_data.read_data_sets("MNIST_data", one_hot=True)

NUM_CLASSES = 10    #Anzahl der Modellklassen

sess = tf.InteractiveSession()


def interence(imegs_placeholder, keep_prob):
    """Funktionen, die Vorhersagemodelle erstellen

Streit:
      images_placeholder:Platzhalter fuer Bild
      keep_prob:Platzhalter für Abbrecherquote

Rückgabewert:
      y_conv:Wahrscheinlichkeit jeder Klasse(Etwas wie)

     with tf.name_scope("xxx") as scope:
Jetzt wird es als Knotenblock auf dem TensorBoard angezeigt
    """


    #Gewichtsstandardabweichung 0.Initialisiert mit einer Normalverteilung von 1
    def weight_variable(shape):
        inital = tf.truncated_normal(shape, stddev=0.1)
        return tf.Variable(inital)

    #Vorspannung zur Standardabweichung 0.Initialisiert mit einer Normalverteilung von 1
    def bias_variable(shape):
        inital = tf.constant(0.1, shape=shape)
        return tf.Variable(inital)

    #Faltschicht
    def conv2d(x, W):
        return tf.nn.conv2d(x, W, strides=[1,1,1,1], padding="SAME")

    #Pooling-Schicht
    def max_pool_2x2(x):
        return tf.nn.max_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding="SAME")

    #28 Eingabeebenen*28*In 1 umgewandelt
    x_image = tf.reshape(imegs_placeholder, [-1, 28, 28, 1])

    #Erzeugung der Faltungsschicht 1
    with tf.name_scope("conv1") as scope:
        W_conv1 = weight_variable([3,3,1,16])
        b_conv1 = bias_variable([16])
        h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)

    #Erzeugung der Faltungsschicht 2
    with tf.name_scope("conv2") as scope:
        W_conv2 = weight_variable([3,3,16,16])
        b_conv2 = bias_variable([16])
        h_conv2 = tf.nn.relu(conv2d(h_conv1, W_conv2) + b_conv2)

    #Erstellung der Pooling-Schicht 1
    with tf.name_scope("pool1") as scope:
        h_pool1 = max_pool_2x2(h_conv2)

    #Erzeugung der Faltungsschicht 3
    with tf.name_scope("conv3") as scope:
        W_conv3 = weight_variable([3,3,16,32])
        b_conv3 = bias_variable([32])
        h_conv3 = tf.nn.relu(conv2d(h_pool1, W_conv3) + b_conv3)

    #Erzeugung der Faltungsschicht 4
    with tf.name_scope("conv4") as scope:
        W_conv4 = weight_variable([3,3,32,32])
        b_conv4 = bias_variable([32])
        h_conv4 = tf.nn.relu(conv2d(h_conv3, W_conv4) + b_conv4)

    #Erstellung der Pooling-Schicht 2
    with tf.name_scope("pool2") as scope:
        h_pool2 = max_pool_2x2(h_conv4)

    #Erzeugung der Faltungsschicht 5
    with tf.name_scope("conv5") as scope:
        W_conv5 = weight_variable([3,3,32,64])
        b_conv5 = bias_variable([64])
        h_conv5 = tf.nn.relu(conv2d(h_pool2, W_conv5) + b_conv5)

    #Erzeugung der Faltungsschicht 6
    with tf.name_scope("conv6") as scope:
        W_conv6 = weight_variable([3,3,64,64])
        b_conv6 = bias_variable([64])
        h_conv6 = tf.nn.relu(conv2d(h_conv5, W_conv6) + b_conv6)

    #Erstellung der Pooling-Schicht 3
    with tf.name_scope("pool3") as scope:
        h_pool3 = max_pool_2x2(h_conv6)

    #Bildung der Bindungsschicht 1
    with tf.name_scope("fc1") as scope:
        W_fc1 = weight_variable([4*4*64, 1024])   
        b_fc1 = bias_variable([1024])
        h_pool3_flat = tf.reshape(h_pool3, [-1, 4*4*64])
        h_fc1 = tf.nn.relu(tf.matmul(h_pool3_flat, W_fc1) + b_fc1)
        #Dropout1-Einstellung
        h_fc_1_drop = tf.nn.dropout(h_fc1, keep_prob)

    #Bildung der Bindungsschicht 2
    with tf.name_scope("fc2") as scope:
        W_fc2 = weight_variable([1024, NUM_CLASSES])
        b_fc2 = bias_variable([NUM_CLASSES])

    #Normalisierung durch Softmax-Funktion
    with tf.name_scope("softmax") as scope:
        y_conv = tf.nn.softmax(tf.matmul(h_fc_1_drop, W_fc2) + b_fc2)

    #Gibt so etwas wie die Wahrscheinlichkeit jedes Etiketts zurück
    return y_conv

def loss(logits, labels):
    """Funktion zur Berechnung des Verlustes
Streit:
      logits:Logit Tensor, float - [batch_size, NUM_CLASSES]
      labels:Tensor beschriften, int32 - [batch_size, NUM_CLASSES]

Rückgabewert:
      cross_entropy:Gekreuzter Entropietensor, float
    """
    #Berechnung der gekreuzten Entropie
    cross_entropy = -tf.reduce_sum(labels*tf.log(logits))
    #Geben Sie an, dass in TensorBoard angezeigt werden soll
    tf.summary.scalar("cross_entropy", cross_entropy)   #v0.12 bis tf.summary.scalar()Wurde#Referenz: https://teratail.com/questions/68531
    return cross_entropy

def training(loss, learning_rate):
    """Funktionen, die Trainingsoperationen definieren

Streit:
      loss:Verlusttensor, loss()Ergebnis von
      learning_rate:Lernkoeffizient

Rückgabewert:
      train_step:Training op

    """

    train_step = tf.train.AdamOptimizer(learning_rate).minimize(loss)
    return train_step

def accuracy(logits, labels):
    """Richtige Antwortrate(accuracy)Funktion zum Berechnen
Streit:
        logits: inference()Ergebnis von
        labels:Tensor beschriften, int32 - [batch_size, NUM_CLASSES]
Rückgabewert:
        accuracy:Richtige Antwortrate(float)
    """

    correct_prediction = tf.equal(tf.argmax(logits, 1), tf.arg_max(labels, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
    tf.summary.scalar("accuracy", accuracy)
    return accuracy

if __name__=="__main__":
    with tf.Graph().as_default():
        #In Ausdrücken verwendete Variableneinstellungen
        x_image = tf.placeholder("float", shape=[None, 784])    #Eingang
        y_label = tf.placeholder("float", shape=[None, 10])
        W = tf.Variable(tf.zeros([784,10]))
        b = tf.Variable(tf.zeros([10]))
        #y_label = tf.nn.softmax(tf.matmul(x_image,W)+b)     # y=softmax(Wx+b)Die Differenzierung erfolgt ebenfalls ohne Erlaubnis
        keep_prob = tf.placeholder("float")
        #init_op = tf.global_variables_initializer()    #Variable Initialisierung(Muss erforderlich sein, wenn Variablen verwendet werden)
        logits = interence(x_image, keep_prob) # inference()So erstellen Sie ein Modell
        loss_value = loss(logits, y_label)     # loss()Den Verlust berechnen
        train_op = training(loss_value,1e-4)   # training()Rufen Sie an und trainieren Sie (1e-4 ist die Lernrate)
        accur = accuracy(logits, y_label)      # accuracy()Berechnung der Genauigkeit
        init_op = tf.global_variables_initializer()
        sess = tf.Session()
        sess.run(init_op)
        #Festlegen des Werts, der auf TensorBoard angezeigt werden soll
        summary_op = tf.summary.merge_all()
        summary_writer = tf.summary.FileWriter("./tmp/data", graph=sess.graph)

        saver = tf.train.Saver()    #Es wurde ein lahmes OP hinzugefügt, das alle Variablen speichert und wiederherstellt

        init = tf.global_variables_initializer()
        sess.run(init) #Variablen initialisieren und ausführen

        #Durchführung von Schulungen
        for step in range(20000)
            batch = mnist.train.next_batch(50)
            if step % 100 == 0:
                train_accury = sess.run(accur, feed_dict={x_image: batch[0], y_label: batch[1], keep_prob: 1.0})
                print("step%d, train_accury : %g"%(step, train_accury))
            sess.run(train_op, feed_dict={x_image: batch[0], y_label: batch[1], keep_prob:0.5})
            #Fügen Sie nach jedem Schritt einen Wert hinzu, der auf dem TensorBoard angezeigt werden soll
            summary_str = sess.run(summary_op, feed_dict={x_image: batch[0], y_label: batch[1], keep_prob: 1.0})
            summary_writer.add_summary(summary_str, step)
            summary_writer.flush()

        #Ergebnisanzeige
        print("test accuracy : %g" %sess.run(accur, feed_dict={x_image: mnist.test.images, y_label: mnist.test.labels, keep_prob: 1.0}))
        saver.save(sess, ".\ckpt\model.ckpt") #Variable Datenspeicherung

Das Wichtigste hier ist

 saver = tf.train.Saver () # Fügen Sie ein lahmes OP hinzu, das alle Variablen speichert und wiederherstellt
 saver.save (sess, ". \ Ckpt \ model.ckpt") # Variable Daten speichern

Diese beiden speichern die Parameter, wenn das Lernen beendet ist. Ohne dies beginnen zig Minuten maschinelles Lernen, selbst wenn Sie nur die Vorhersage jedes Bildes zurückgeben möchten. Ich habe auf diese Site verwiesen → Speichern und Laden von Tensorflow-Lernparametern

Bild laden und Vorhersage zurückgeben

input_num.py


import tensorflow as tf
import cv2
import numpy as np

NUM_CLASSES = 10

def interence(imegs_placeholder, keep_prob):
    """Funktionen, die Vorhersagemodelle erstellen

Streit:
      images_placeholder:Platzhalter fuer Bild
      keep_prob:Platzhalter für Abbrecherquote

Rückgabewert:
      y_conv:Wahrscheinlichkeit jeder Klasse(Etwas wie)

     with tf.name_scope("xxx") as scope:
Jetzt wird es als Knotenblock auf dem TensorBoard angezeigt
    """


    #Gewichtsstandardabweichung 0.Initialisiert mit einer Normalverteilung von 1
    def weight_variable(shape):
        inital = tf.truncated_normal(shape, stddev=0.1)
        return tf.Variable(inital)

    #Vorspannung zur Standardabweichung 0.Initialisiert mit einer Normalverteilung von 1
    def bias_variable(shape):
        inital = tf.constant(0.1, shape=shape)
        return tf.Variable(inital)

    #Faltschicht
    def conv2d(x, W):
        return tf.nn.conv2d(x, W, strides=[1,1,1,1], padding="SAME")

    #Pooling-Schicht
    def max_pool_2x2(x):
        return tf.nn.max_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding="SAME")

    #28 Eingabeebenen*28*In 1 umgewandelt
    x_image = tf.reshape(imegs_placeholder, [-1, 28, 28, 1])

    #Erzeugung der Faltungsschicht 1
    with tf.name_scope("conv1") as scope:
        W_conv1 = weight_variable([3,3,1,16])
        b_conv1 = bias_variable([16])
        h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)

    #Erzeugung der Faltungsschicht 2
    with tf.name_scope("conv2") as scope:
        W_conv2 = weight_variable([3,3,16,16])
        b_conv2 = bias_variable([16])
        h_conv2 = tf.nn.relu(conv2d(h_conv1, W_conv2) + b_conv2)

    #Erstellung der Pooling-Schicht 1
    with tf.name_scope("pool1") as scope:
        h_pool1 = max_pool_2x2(h_conv2)

    #Erzeugung der Faltungsschicht 3
    with tf.name_scope("conv3") as scope:
        W_conv3 = weight_variable([3,3,16,32])
        b_conv3 = bias_variable([32])
        h_conv3 = tf.nn.relu(conv2d(h_pool1, W_conv3) + b_conv3)

    #Erzeugung der Faltungsschicht 4
    with tf.name_scope("conv4") as scope:
        W_conv4 = weight_variable([3,3,32,32])
        b_conv4 = bias_variable([32])
        h_conv4 = tf.nn.relu(conv2d(h_conv3, W_conv4) + b_conv4)

    #Erstellung der Pooling-Schicht 2
    with tf.name_scope("pool2") as scope:
        h_pool2 = max_pool_2x2(h_conv4)

    #Erzeugung der Faltungsschicht 5
    with tf.name_scope("conv5") as scope:
        W_conv5 = weight_variable([3,3,32,64])
        b_conv5 = bias_variable([64])
        h_conv5 = tf.nn.relu(conv2d(h_pool2, W_conv5) + b_conv5)

    #Erzeugung der Faltungsschicht 6
    with tf.name_scope("conv6") as scope:
        W_conv6 = weight_variable([3,3,64,64])
        b_conv6 = bias_variable([64])
        h_conv6 = tf.nn.relu(conv2d(h_conv5, W_conv6) + b_conv6)

    #Erstellung der Pooling-Schicht 3
    with tf.name_scope("pool3") as scope:
        h_pool3 = max_pool_2x2(h_conv6)

    #Bildung der Bindungsschicht 1
    with tf.name_scope("fc1") as scope:
        W_fc1 = weight_variable([4*4*64, 1024])
        b_fc1 = bias_variable([1024])
        h_pool3_flat = tf.reshape(h_pool3, [-1, 4*4*64])
        h_fc1 = tf.nn.relu(tf.matmul(h_pool3_flat, W_fc1) + b_fc1)
        #Dropout1-Einstellung
        h_fc_1_drop = tf.nn.dropout(h_fc1, keep_prob)

    #Bildung der Bindungsschicht 2
    with tf.name_scope("fc2") as scope:
        W_fc2 = weight_variable([1024, NUM_CLASSES])
        b_fc2 = bias_variable([NUM_CLASSES])

    #Normalisierung durch Softmax-Funktion
    with tf.name_scope("softmax") as scope:
        y_conv = tf.nn.softmax(tf.matmul(h_fc_1_drop, W_fc2) + b_fc2)

    #Gibt so etwas wie die Wahrscheinlichkeit jedes Etiketts zurück
    return y_conv

if __name__ == "__main__":

    #Bild wird geladen
    img = input("Bitte geben Sie den Bildpfad ein>")
    img = cv2.imread(img, cv2.IMREAD_GRAYSCALE)
    img = cv2.resize(img, (28, 28))
    ximage = img.flatten().astype(np.float32)/255.0 #Format ändern

    #In Ausdrücken verwendete Variableneinstellungen
    x_image = tf.placeholder("float", shape=[None, 784])    #Eingang
    y_label = tf.placeholder("float", shape=[None, 10])
    keep_prob = tf.placeholder("float")

    logits = interence(x_image, keep_prob)
    sess = tf.InteractiveSession()

    saver = tf.train.Saver()
    sess.run(tf.global_variables_initializer())
    ckpt = tf.train.get_checkpoint_state('./ckpt')
    saver.restore(sess, ckpt.model_checkpoint_path) #Variable Daten lesen

    pred = np.argmax(logits.eval(feed_dict={x_image: [ximage], keep_prob: 1.0})[0])
    print(pred)

Wie Sie vielleicht hier bemerkt haben, ist die erste Hälfte fast dieselbe. Dies liegt daran, dass Sie zuerst die zu verwendenden Variablen bestimmen müssen, bevor Sie die gelernten Parameter eingeben.

** Bildverarbeitung **

 #Bild laden
 img = Eingabe ("Bildpfad eingeben>")
    img = cv2.imread(img, cv2.IMREAD_GRAYSCALE)
    img = cv2.resize(img, (28, 28))
 ximage = img.flatten (). astype (np.float32) /255.0 # change format

Nachdem Sie das Bild mit cv2 gelesen haben, ändern Sie die Größe auf 28 * 28, machen Sie das Format eindimensional und teilen Sie die Graustufen von 0 auf 255 durch 255. Dann wird Weiß [255] zu 1 und Schwarz [0] zu [0]. Subtile Farben (Grau usw.) sind Float-Brüche. Mit anderen Worten lag es im Bereich von 0 bis 1. Auf diese Weise können Sie anhand der zuvor erlernten Informationen Vorhersagen treffen.

    saver = tf.train.Saver()
    sess.run(tf.global_variables_initializer())
    ckpt = tf.train.get_checkpoint_state('./ckpt')
 saver.restore (sess, ckpt.model_checkpoint_path) # Variable Daten lesen

Initialisieren Sie die Variablen, bevor Sie die vom ersten Trainingsprogramm gespeicherten trainierten Parameter laden, und laden Sie dann die Parameter.

    pred = np.argmax(logits.eval(feed_dict={x_image: [ximage], keep_prob: 1.0})[0])
    print(pred)

Schließlich werden das verarbeitete Bild, die Abbrecherquote usw. an das Netzwerk übergeben und das größte zurückgegebene Ergebnis angezeigt.

test.png Wenn Sie es ausführen und ein Bild wie dieses übergeben (obwohl es möglicherweise etwas anders ist), sollte es wie das folgende aussehen.

C:\User\...\MNIST > python input_num.py
 Bitte geben Sie den Bildpfad ein> (Bildpfad)
3

Dies ist das Ende des Programms, das die Vorhersage zurückgibt, wenn Sie den Bildpfad eingeben. Bitte probieren Sie es aus!

Ergänzung

Wenn das "Bild" beim Übergeben von Bilddaten dünn ist und die Dicke der Zeichen gering ist, verschwindet es, wenn die Größe auf 28 * 28 geändert wird. Schreiben Sie es daher bitte ziemlich dick.

Ich habe den Code vorerst auch auf GitHub gestellt. Code für diesen Artikel

Websites usw., auf die ich mich bezog

Identifizieren Sie die Produktionsfirma von Anime Yuruyuri durch TensorFlow Speichern und Laden von Lernparametern von ensorflow Laden grundlegender Bilder von Python OpenCV (Standbild)

Recommended Posts

Das MNIST-Tutorial von TensorFlow wurde mit der Bildeingabe kompatibel gemacht
GUI-Bildschneidewerkzeug mit Python + Tkinter
MNIST-Bildklassifizierung (handschriftliche Nummer) mit mehrschichtigem Perzeptron
Erstellung eines MNIST-Bilderzeugungsprogramms durch DCGAN (Tensorflow-Tutorial)
Fordern Sie die Bildklassifizierung mit TensorFlow2 + Keras 3 heraus ~ Visualisieren Sie MNIST-Daten ~