2017-10-23 3 views
1

Ich würde es sehr schätzen, wenn mir jemand Hinweise geben könnte, was ich reparieren muss. Ich bin TensorFlow neu und ich habe keine Ahnung, was schief läuft.Ich habe keine Ahnung, was mit meinem TensorFlow-Programm falsch ist

der Code:

from PIL import ImageFont, Image, ImageDraw 
import tensorflow as tf 
import random 
import numpy as np 

x = tf.placeholder(tf.float32, [None,48,48,1]) 
y = tf.placeholder(tf.float32, [None,26]) 

def initW(shape): 
    return tf.Variable(tf.random_normal(shape, stddev=0.01)) 

w1 = initW([5,5,1,32]) 
w2 = initW([5,5,32,64]) 
w3 = initW([64*12*12,26]) 
keep_prob = tf.placeholder(tf.float32) 

saver = tf.train.Saver() 

def model(x,w1,w2,w3,keep_prob): 
    l1c = tf.nn.relu(tf.nn.conv2d(x, w1, strides = [1,1,1,1], padding = "SAME")) 
    l1p = tf.nn.max_pool(l1c, ksize = [1,2,2,1], strides = [1,2,2,1], padding = "SAME") 
    l2c = tf.nn.relu(tf.nn.conv2d(l1p, w2, strides = [1,1,1,1], padding = "SAME")) 
    l2p = tf.nn.max_pool(l2c, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME") 
    l2r = tf.reshape(l2p,[-1,64*12*12]) 
    l2d = tf.nn.dropout(l2r, keep_prob) 
    l3f = tf.matmul(l2d,w3) 

    return l3f 

model = model(x,w1,w2,w3,keep_prob) 

cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels = y, logits = model)) 

op = tf.train.AdamOptimizer(0.000002).minimize(cost) 

def imgData(char): 
    img = Image.new("L", (48, 48), color=255) 
    f = ImageFont.truetype("Arial.ttf", 50) 
    ImageDraw.Draw(img).text((25 - f.getsize("W")[0]/2, 0), "W", font=f) 
    return np.reshape(img.getdata(),[48,48,1]) 

def oneHot(C,reshape=False): 
    arr = [0] * 26 
    arr[charToInt(C)] = 1 
    if reshape: 
     return np.reshape(arr,[1,26]) 
    else: 
     return arr 

def charToInt(C): 
    return ord(C) - ord("A") 

def accuracy(): 
    alphabet = list("ABCDEFGHIJKLMNOPQRSTUVWXYZ") 
    testSet = np.array([imgData(C) for C in alphabet]) 
    testLabels = np.array([oneHot(C) for C in alphabet]) 
    accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(model,1),tf.argmax(y,1)),tf.float32)) 
    print (sess.run(accuracy,feed_dict={x:testSet,y:testLabels,keep_prob:1.0})) 

def predict(char): 
    probabilities = sess.run(model, feed_dict= {x:[imgData(char)], keep_prob: 0.5})[0] 
    for n in range(26): 
     print (chr(ord("A") + n) + ": " + "{0:.2f}".format(probabilities[n])) 

with tf.Session() as sess: 
    tf.global_variables_initializer().run() 

    alphabet = list("ABCDEFGHIJKLMNOPQRSTUVWXYZ") 
    random.shuffle(alphabet) 

    train = True 
    if train: 
     for n in range(20): 
      for C in alphabet: 
       sess.run(op, feed_dict = { 
        x: [imgData(C)], 
        y: oneHot(C,reshape=True), 
        keep_prob: 0.5 
       }) 
      print("cost: " + str(sess.run(cost,feed_dict={ 
       x:[imgData(C)], 
       y:oneHot(C,reshape=True), 
       keep_prob: 1.0 
      }))) 
      saver.save(sess,"./model") 

    else: 
     saver.restore(sess,"./model") 
     accuracy() 
     # predict("B") 

Dies ist ein einfaches neuronales Netzwerk Faltungsprogramm, das ein Bild von einem Großbuchstaben nimmt, und gibt das vorausgesagte Zeichen. x ist der Eingangstensor für das 48x48-Bild, das von imgData(char) generiert wird, und y ist die Ausgabe, die ein Großbuchstabe darstellt.

Das cnn-Modell befindet sich in model(x,w1,w2,w3,keep_prob). Trotz der verschiedenen Zahlen für die Lernrate und die Epoche konvergieren die Kosten immer auf etwa 3,3.

accuracy() gibt die gemessene Genauigkeit des Modells mit einem Testset aus. Es sagt immer 0,0384615. Ich möchte predict() zeigen, welche Wahrscheinlichkeiten eines gegebenen Bildes verschiedene Charaktere sein können, aber gerade jetzt gibt es alle Arten von seltsamen Zahlen.

Vielen Dank.

Antwort

1

Ihre imgData Methode hat einen Tippfehler: Sie char statt W schreiben sollen, wenn ich mich richtig (siehe Dokumentation von ImageDraw.draw.text) zu verstehen. Andernfalls wird Ihr goldenes Label immer das Zeichen W haben. Aus diesem Grund erhalten Sie immer eine Genauigkeit von 0,0384, also 1/26, d. H. Sie lernen nur eines der 26 Zeichen zu erkennen (was erwartet wird, weil Sie niemals andere Zeichen als W kennzeichnen).

def imgData(char): 
    img = Image.new("L", (48, 48), color=255) 
    f = ImageFont.truetype("/tmp/arial.ttf", 50) 
    ImageDraw.Draw(img).text((25 - f.getsize("W")[0]/2, 0), char, font=f) 
    return np.reshape(img.getdata(),[48,48,1]) 

Ich erhöhe auch Ihre Lernrate um 10x. Dann überbrückt das Modell in ~ 10 Iterationen:

0, cost: 4.96586 accu 0.0769231 
1, cost: 5.01186 accu 0.115385 
2, cost: 3.9491 accu 0.230769 
3, cost: 2.56 accu 0.384615 
4, cost: 1.99173 accu 0.423077 
5, cost: 2.51248 accu 0.576923 
6, cost: 2.19388 accu 0.730769 
7, cost: 3.79979 accu 0.769231 
8, cost: 2.25762 accu 0.807692 
9, cost: 1.27227 accu 0.884615 
10, cost: 0.964877 accu 0.884615 
11, cost: 2.15709 accu 0.923077 
12, cost: 0.482007 accu 0.961538 
13, cost: 0.733133 accu 1.0 
+0

Ah, schießen, das ist ein großer Fehler von meiner Seite: P Danke! – ME914

+0

np. Übrigens, deine Art, deine Trainingsdaten on the fly zu erstellen, ist interessant! Wenn du etwas Lärm hinzufügen könntest, wäre das interessanter. – greeness

+0

Hey, gute Idee mit dem Hinzufügen von Lärm. Ich denke auch an Transformationen und verschiedene Schriftarten. – ME914

Verwandte Themen