为什么这个TensorFlow实现远没有Matlab的NN那么成功?

Arb*_*bil 32 python matlab neural-network tensorflow

作为玩具示例,我试图f(x) = 1/x从100个无噪声数据点拟合函数.matlab默认实现非常成功,均方差为~10 ^ -10,并且插值完美.

我实现了一个神经网络与一个隐藏的10个sigmoid神经​​元层.我是神经网络的初学者,所以请注意防范愚蠢的代码.

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)
Run Code Online (Sandbox Code Playgroud)

均方差在~2*10 ^ -3处结束,因此比matlab差大约7个数量级.可视化

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()
Run Code Online (Sandbox Code Playgroud)

我们可以看到拟合系统不完美: 在此输入图像描述 而matlab的一个看起来很完美的肉眼,差异均匀<10 ^ -5: 在此输入图像描述 我试图用TensorFlow复制Matlab网络图:

在此输入图像描述

顺便提一下,该图似乎暗示了tanh而不是sigmoid激活函数.我无法在文档中的任何地方找到它.然而,当我尝试在TensorFlow中使用tanh神经元时,拟合很快会nan因变量而失败.我不知道为什么.

Matlab使用Levenberg-Marquardt训练算法.贝叶斯正则化甚至更成功,均方值在10 ^ -12(我们可能在浮点运算的蒸汽区域).

为什么TensorFlow实施更糟糕,我该怎么做才能让它变得更好?

Yar*_*tov 25

我尝试了50000次迭代训练,得到0.00012错误.特斯拉K40需要大约180秒.

在此输入图像描述

似乎对于这种问题,一阶梯度下降不是一个很好的拟合(双关语),你需要Levenberg-Marquardt或l-BFGS.我认为还没有人在TensorFlow中实现它们.

编辑 使用tf.train.AdamOptimizer(0.1)了这个问题.它3.13729e-05经过4000次迭代后得到.此外,具有默认策略的GPU对于此问题似乎也是一个坏主意.有许多小型操作,并且开销导致GPU版本比我的机器上的CPU运行慢3倍.

  • 另外 - 将您的数据类型从float32更改为float64,调整adamoptimizer以使用指数衰减学习率从0.2下降到exp衰减0.9999在4000个训练步骤后得到1.44e-05.step = tf.Variable(0,trainable = False)rate = tf.train.exponential_decay(0.2,step,1,0.999)optimizer = tf.train.AdamOptimizer(rate)train = optimizer.minimize(loss,global_step = step) (2认同)

dga*_*dga 16

顺便说一句,这是上面的一个略微清理的版本,它清除了一些形状问题和tf和np之间不必要的弹跳.它在40k步后达到3e-08,在4000之后达到1.5e-5:

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)

xTrain = np.linspace(0.2, 0.8, 101).reshape([1, -1])
yTrain = (1/xTrain)

x = tf.placeholder(tf.float32, [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))
step = tf.Variable(0, trainable=False)
rate = tf.train.exponential_decay(0.15, step, 1, 0.9999)
optimizer = tf.train.AdamOptimizer(rate)
train = optimizer.minimize(loss, global_step=step)
init = tf.initialize_all_variables()

# Launch the graph                                                                            
sess = tf.Session()
sess.run(init)

for step in xrange(0, 40001):
    train.run({x: xTrain}, sess)
    if step % 500 == 0:
        print loss.eval({x: xTrain}, sess)
Run Code Online (Sandbox Code Playgroud)

总而言之,LMA比用于拟合2D曲线的更通用的DNN风格优化器做得更好也就不足为奇了.亚当和其他人正在针对非常高的维度问题,LMA开始变得非常大,因为非常大的网络(见12-15).