Как пример игрушки, я пытаюсь установить функцию f(x) = 1/x
из 100 точек без шума. Реализация Matlab по умолчанию феноменально успешна со средней квадратичной разницей ~ 10^-10 и отлично интерполирует.Почему эта реализация TensorFlow намного менее успешна, чем NN Matlab?
Я реализую нейронную сеть с одним скрытым слоем из 10 сигмовидных нейронов. Я новичок в нейронных сетях, поэтому будьте настороже от немого кода.
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)
Средняя квадратная разница заканчивается на уровне ~ 2 * 10^-3, что примерно на 7 порядков хуже, чем у Matlab. Визуальное с
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()
мы можем видеть подгонку систематически несовершенны: в то время как один MATLAB выглядит идеально невооруженным глазом с различиями равномерно < 10^-5: я пытался повторить с TensorFlow диаграмма сети Matlab:
Кстати, схема, как представляется, подразумевает TANH, а не сигмовидной ACTIVA . Я не могу найти его где-нибудь в документации, чтобы быть уверенным. Тем не менее, когда я пытаюсь использовать tanh neuron в TensorFlow, фитинг быстро терпит неудачу с nan
для переменных. Я не знаю почему.
Matlab использует алгоритм обучения Levenberg-Marquardt. Байесовская регуляризация еще более успешна со средними квадратами при 10^-12 (мы, вероятно, находимся в области паров арифметики с плавающей точкой).
Почему реализация TensorFlow намного хуже, и что я могу сделать, чтобы сделать ее лучше?
Я еще не смотрел в поток тензоров, поэтому сожалею об этом, но вы делаете некоторые причудливые вещи с numpy там с этой функцией toNd. 'Нп.linspace' уже возвращает ndarray, а не список, если вы хотите преобразовать список в ndarray, все, что вам нужно сделать, это 'np.array (my_list)', и если вам просто нужна дополнительная ось, вы можете сделать 'new_array = my_array [np.newaxis,:]'. Это может быть просто прекращение нулевой ошибки, потому что это должно сделать это. У большинства данных есть шум, и вам не обязательно нужна нулевая ошибка обучения. Судя по «reduce_mean», он может использовать кросс-валидацию. –
@AdamAcosta 'toNd' - определенно стоп-лосс для моего отсутствия опыта. Я пробовал 'np.array' раньше, и проблема заключается в том, что' np.array ([5,7]). Shape' is '(2,)', а не '(2,1)'. 'my_array [np.newaxis,:]' похоже, исправляет это, спасибо! Я не использую python, а скорее F # изо дня в день. – Arbil
@AdamAcostaI Я не думаю, что 'reduce_mean' делает перекрестную проверку. Из документов: «Вычисляет среднее значение элементов в измерениях тензора». Matlab делает кросс-валидацию, которая, на мой взгляд, должна уменьшать соответствие учебного образца по сравнению с отсутствием перекрестной проверки, верно ли? – Arbil