2

Ich arbeite gerade daran, Professor Andrew Ngs "Machine Learning" -Kurse von Coursera zu überarbeiten, und ich bin in der Logistischen Regression geblieben.Warum produziert mein GradientDescentOptimizer NaN?

filename = 'data/ex2data1.txt' 
data = np.loadtxt(filename, delimiter = ",", unpack = True) 

# Data matrices 
xtr = np.transpose(np.array(data[:-1])) 
ytr = np.transpose(np.array(data[-1:])) 

# Initial weights 
W = tf.Variable(tf.zeros([2,1], dtype = tf.float64)) 

# Bias 
b = tf.Variable(tf.zeros([1], dtype = tf.float64)) 

# Cost function 
y_ = tf.nn.sigmoid(tf.matmul(xtr,W) + b) 

cost = -tf.reduce_mean(ytr*tf.log(y_) + (1-ytr)*tf.log(1-y_)) 
optimize = tf.train.GradientDescentOptimizer(0.01).minimize(cost) 

corr = tf.equal(tf.argmax(ytr,1), tf.argmax(y_,1)) 
acc = tf.reduce_mean(tf.cast(corr, tf.float64)) 

init = tf.initialize_all_variables() 

with tf.Session() as sess: 
    sess.run(init) 
    print(sess.run(cost)) 
    for _ in range(3): 
     sess.run(optimize) 
     print(sess.run(cost)) 

Daraus ergibt sich die Antwort:

0.69314718056 
nan 
nan 
nan 

Das erste Ergebnis an die Kostenfunktion ist richtig, aber die sind Nächsten sein soll:

3.0133 
1.5207 
0.7336 

und stattdessen bekomme ich ein Bündel von NaNs. Ich habe niedrigere Lernraten versucht, alles ohne Erfolg. Was mache ich falsch? Und ist es möglich, diese Aufgabe in TensorFlow zu reproduzieren?

PS: Andere Python-Lösungen scheinen scipy.optimize zu verwenden, aber ich habe keine Ahnung, wie ich das mit TensorFlow-Werten verwenden würde, und ich würde nur TensorFlow verwenden, wenn überhaupt möglich.

EDIT: Ich habe auch versucht, Bias als tf.ones anstelle von tf.zeros, aber es hat auch nicht funktioniert.

Antwort

0

Ihr Logarithmus bereinigt den Eingang nicht. Es kann sehr gut passieren, dass Sie negative Eingabewerte haben, die NaN schnell irgendeine arithmetische Zahl schwebender Zahlen.

What I did in Java code that makes heavy use of logs in similar domain:

  • prüfen NaN oder Unendlichkeit und annehmen Ausgabe als Null
  • Wenn negativen Eingang, den Ausgang zu einem gewissen statischen Zahl zB Clip. log (1e-5) ~ = -11,51
  • sonst nehmen Sie nur das Protokoll

In Java, dass Code wie folgt aussieht, sollte tf zu übersetzen nicht schwierig sein:

public static double guardedLogarithm(double input) { 
    if (Double.isNaN(input) || Double.isInfinite(input)) { 
     return 0d; 
    } else if (input <= 0d || input <= -0d) { 
     // assume a quite low value of log(1e-5) ~= -11.51 
     return -10d; 
    } else { 
     return FastMath.log(input); 
    } 
    }