Als ein Spielzeugbeispiel versuche ich eine Funktion f(x) = 1/x
von 100 No-Noise-Datenpunkten anzupassen. Die Matlab-Standardimplementierung ist phänomenal erfolgreich mit einer mittleren quadratischen Differenz von ~ 10^-10 und interpoliert perfekt.Warum ist diese TensorFlow-Implementierung wesentlich weniger erfolgreich als Matlabs NN?
Ich implementiere ein neuronales Netzwerk mit einer versteckten Schicht von 10 sigmoiden Neuronen. Ich bin ein Anfänger in neuronalen Netzen, also seien Sie auf der Hut vor dummem Code.
import tensorflow as tf
import numpy as np
def weight_variable(shape):
initial = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(initial)
def bias_variable(shape):
initial = tf.constant(0.1, shape=shape)
return tf.Variable(initial)
#Can't make tensorflow consume ordinary lists unless they're parsed to ndarray
def toNd(lst):
lgt = len(lst)
x = np.zeros((1, lgt), dtype='float32')
for i in range(0, lgt):
x[0,i] = lst[i]
return x
xBasic = np.linspace(0.2, 0.8, 101)
xTrain = toNd(xBasic)
yTrain = toNd(map(lambda x: 1/x, xBasic))
x = tf.placeholder("float", [1,None])
hiddenDim = 10
b = bias_variable([hiddenDim,1])
W = weight_variable([hiddenDim, 1])
b2 = bias_variable([1])
W2 = weight_variable([1, hiddenDim])
hidden = tf.nn.sigmoid(tf.matmul(W, x) + b)
y = tf.matmul(W2, hidden) + b2
# Minimize the squared errors.
loss = tf.reduce_mean(tf.square(y - yTrain))
optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(loss)
# For initializing the variables.
init = tf.initialize_all_variables()
# Launch the graph
sess = tf.Session()
sess.run(init)
for step in xrange(0, 4001):
train.run({x: xTrain}, sess)
if step % 500 == 0:
print loss.eval({x: xTrain}, sess)
Die mittlere quadratische Differenz endet bei ~ 2 * 10^-3, also etwa 7 Größenordnungen schlechter als Matlab. Visualisieren mit
xTest = np.linspace(0.2, 0.8, 1001)
yTest = y.eval({x:toNd(xTest)}, sess)
import matplotlib.pyplot as plt
plt.plot(xTest,yTest.transpose().tolist())
plt.plot(xTest,map(lambda x: 1/x, xTest))
plt.show()
wir das für richtig halten kann, ist systematisch unvollkommen: gleichmäßig < 10^-5 während die Matlab eine mit dem bloßen Auge mit den Unterschieden perfekt aussieht: Ich habe versucht, mit zu replizieren TensorFlow das Diagramm des Matlab-Netzwerk:
Übrigens scheint das Diagramm, das eine tanh zu implizieren, statt sigmoid activa Funktion. Ich kann es nirgends in der Dokumentation finden, um sicher zu sein. Wenn ich jedoch versuche, in TensorFlow ein tanh-Neuron zu verwenden, scheitert die Anpassung schnell an nan
für Variablen. Keine Ahnung warum.
Matlab verwendet den Levenberg-Marquardt-Trainingsalgorithmus. Bayessche Regularisierung ist mit mittleren Quadraten bei 10^-12 noch erfolgreicher (wir sind wahrscheinlich im Bereich der Dämpfe der Float-Arithmetik).
Warum ist die TensorFlow-Implementierung so viel schlimmer, und was kann ich tun, um es besser zu machen?
Ich habe noch nicht in Tensor Flow geschaut, tut mir leid, aber du machst einige bizarre Dinge mit numpy dort mit dieser 'toNd' Funktion. 'np.linspace gibt bereits ein ndarray zurück, nicht eine Liste, wenn Sie eine Liste in ein ndarray konvertieren wollen, müssen Sie nur 'np.array (my_list)' eingeben, und wenn Sie nur die zusätzliche Achse benötigen, können Sie das tun 'neuer_array = mein_array [np.newaxis,:]'. Es könnte nur kurz vor Null Fehler stehen, weil es das tun soll. Die meisten Daten haben Rauschen, und Sie möchten nicht notwendigerweise Null Trainingsfehler darauf. Gemessen an "reduce_mean" kann eine Kreuzvalidierung verwendet werden. –
@AdamAcosta 'toNd' ist definitiv eine Lücke für meinen Mangel an Erfahrung. Ich habe 'np.array' vorher probiert und das Problem scheint zu sein, dass' np.array ([5,7]) .form' '' (2,) 'und nicht' (2,1) 'ist. 'my_array [np.newaxis,:]' scheint das zu korrigieren, danke! Ich benutze nicht Python sondern F # Tag für Tag. – Arbil
@AdamAcostaI Ich glaube nicht, dass "reduce_mean" Kreuzvalidierung durchführt. Aus der Dokumentation: 'Berechnet den Mittelwert von Elementen über Dimensionen eines Tensors. Matlab führt eine Kreuzvalidierung durch, die meiner Meinung nach die Anpassung an die Trainingsstichprobe im Vergleich zu keiner Kreuzvalidierung reduzieren sollte, ist das richtig? – Arbil