Frage

Es gibt online viele Ressourcen zur Implementierung von MLP in Tensorflow, und die meisten Beispiele funktionieren :) Aber ich interessiere mich für ein bestimmtes Beispiel, von dem ich gelernt habe https://www.coursera.org/learn/machine-learning.Dabei wird a verwendet kosten Funktion wie folgt definiert:

$ J ( theta) = frac {1} {m} sum_ {i = 1}^{m} sum_ {k = 1}^{k} links [-y_k^{(i)} log ((h_ theta (x^{(i)}) _ k - (1 - y_k^{(i)}) log (1 - (h_ theta (x^{(i)}) _ k rechts ] $

$h_ heta$ ist das Sigmoid Funktion.

Und da ist meine Implementierung:

# one hidden layer MLP

x = tf.placeholder(tf.float32, shape=[None, 784])
y = tf.placeholder(tf.float32, shape=[None, 10])

W_h1 = tf.Variable(tf.random_normal([784, 512]))
h1 = tf.nn.sigmoid(tf.matmul(x, W_h1))

W_out = tf.Variable(tf.random_normal([512, 10]))
y_ = tf.matmul(h1, W_out)

# cross_entropy = tf.nn.sigmoid_cross_entropy_with_logits(y_, y)
cross_entropy = tf.reduce_sum(- y * tf.log(y_) - (1 - y) * tf.log(1 - y_), 1)
loss = tf.reduce_mean(cross_entropy)
train_step = tf.train.GradientDescentOptimizer(0.05).minimize(loss)

correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

# train
with tf.Session() as s:
    s.run(tf.initialize_all_variables())

    for i in range(10000):
        batch_x, batch_y = mnist.train.next_batch(100)
        s.run(train_step, feed_dict={x: batch_x, y: batch_y})

        if i % 100 == 0:
            train_accuracy = accuracy.eval(feed_dict={x: batch_x, y: batch_y})
            print('step {0}, training accuracy {1}'.format(i, train_accuracy))

Ich denke, die Definition für die Ebenen ist korrekt, aber das Problem liegt in der cross_entropy.Wenn ich das erste verwende, der wurde auskommentiert, das Modell konvergiert schnell; Aber wenn ich die zweite Gleichung verwende, von der ich denke/hoffe, dass sie die Übersetzung der vorherigen Gleichung ist, konvergiert das Modell nicht.

War es hilfreich?

Lösung

Sie haben drei Fehler gemacht:

  1. Sie haben die Offset-Terme vor den nichtlinearen Transformationen (Variablen b_1 und b_out) weggelassen.Dies erhöht die repräsentative Leistung des neuronalen Netzwerks.
  2. Sie haben die Softmax-Transformation auf der obersten Ebene weggelassen.Dadurch wird die Ausgabe zu einer Wahrscheinlichkeitsverteilung, sodass Sie die Kreuzentropie berechnen können, die die übliche Kostenfunktion für die Klassifizierung ist.
  3. Sie haben die binäre Form der Kreuzentropie verwendet, obwohl Sie die Mehrklassenform hätten verwenden sollen.

Wenn ich das ausführe, erhalte ich Genauigkeiten von über 90 %:

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets('/tmp/MNIST_data', one_hot=True)

x = tf.placeholder(tf.float32, shape=[None, 784])
y = tf.placeholder(tf.float32, shape=[None, 10])

W_h1 = tf.Variable(tf.random_normal([784, 512]))
b_1 = tf.Variable(tf.random_normal([512]))
h1 = tf.nn.sigmoid(tf.matmul(x, W_h1) + b_1)

W_out = tf.Variable(tf.random_normal([512, 10]))
b_out = tf.Variable(tf.random_normal([10]))
y_ = tf.nn.softmax(tf.matmul(h1, W_out) + b_out)

# cross_entropy = tf.nn.sigmoid_cross_entropy_with_logits(y_, y)
cross_entropy = tf.reduce_sum(- y * tf.log(y_), 1)
loss = tf.reduce_mean(cross_entropy)
train_step = tf.train.GradientDescentOptimizer(0.05).minimize(loss)

correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

# train
with tf.Session() as s:
    s.run(tf.initialize_all_variables())

    for i in range(10000):
        batch_x, batch_y = mnist.train.next_batch(100)
        s.run(train_step, feed_dict={x: batch_x, y: batch_y})

        if i % 1000 == 0:
            train_accuracy = accuracy.eval(feed_dict={x: batch_x, y: batch_y})
            print('step {0}, training accuracy {1}'.format(i, train_accuracy))
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit datascience.stackexchange
scroll top