Jako przykład zabawki próbuję dopasować funkcję f(x) = 1/x
ze 100 punktów danych bez szumów. Domyślna implementacja programu Matlab jest fenomenalnie skuteczna ze średnią różnicą kwadratów ~ 10^-10 i idealnie interpoluje.Dlaczego ta implementacja TensorFlow jest mniej skuteczna niż NN Matlaba?
Implementuję sieć neuronową z jedną ukrytą warstwą 10 sigmoidalnych neuronów. Jestem początkującym w sieciach neuronowych, więc miej się na baczności przed głupim kodem.
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)
Średnia różnica kwadratów kończy się na ~ 2 * 10^-3, czyli około 7 rzędów wielkości gorszych niż matlab. Wizualizacja z
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()
widzimy dopasowanie jest systematycznie niedoskonały: natomiast Matlab wygląda idealny gołym okiem z różnicami równomiernie < 10^-5: starałem się replikować z TensorFlow schemat sieci Matlab:
Nawiasem mówiąc, schemat wydaje się sugerować tanh zamiast esicy activa funkcja. Nie mogę znaleźć nigdzie w dokumentacji, aby być pewnym. Jednak gdy próbuję użyć neuronu tanha w TensorFlow, dopasowanie szybko zawiedzie z nan
dla zmiennych. Nie wiem dlaczego.
Matlab używa algorytmu szkolenia Levenberga-Marquardta. Bayesowska regularyzacja jest jeszcze bardziej skuteczna ze średnimi kwadratami przy 10^-12 (prawdopodobnie znajdujemy się w obszarze oparów arytmetyki pływaków).
Dlaczego wdrożenie TensorFlow jest znacznie gorsze i co mogę zrobić, aby było lepiej?
Nie zajrzałem jeszcze do przepływu tensora, więc przepraszam za to, ale robisz dziwne rzeczy z numpy tam z funkcją 'toNd'. 'np.linspace' już zwraca ndarray, a nie listę, jeśli chcesz przekonwertować listę do ndarray, wszystko co musisz zrobić to 'np.array (my_list)', a jeśli potrzebujesz tylko dodatkowej osi, możesz zrobić 'new_array = my_array [np.newaxis,:]'. Może to być zatrzymanie się na zero błędu zerowego, ponieważ ma to zrobić. Większość danych zawiera szumy i nie koniecznie chcesz zerwać błąd szkolenia. Sądząc po "reduce_mean", może używać sprawdzania krzyżowego. –
@AdamAcosta 'toNd' to zdecydowanie przerwa dla mojego braku doświadczenia. Próbowałem wcześniej 'np.array' i problem wydaje się, że' np.array ([5,7]). Shape' to '(2,)' a nie '(2,1)'. 'my_array [np.newaxis,:]' wydaje się to poprawiać, dziękuję! Nie używam Pythona, ale raczej F # z dnia na dzień. – Arbil
@AdamAcostaI Nie uważam, że 'reduce_mean' ma sprawdzanie krzyżowe. Z dokumentów: "Oblicza średnią elementów w wymiarach tensora". Matlab sprawdza krzyżowo, co moim zdaniem powinno zmniejszyć dopasowanie do próbki treningowej w porównaniu do braku sprawdzania krzyżowego, czy to prawda? – Arbil