web-dev-qa-db-ja.com

このTensorFlow実装は、MatlabのNNよりもそれほど成功しないのはなぜですか?

おもちゃの例として、ノイズのない100個のデータポイントから関数f(x) = 1/xを当てはめようとしています。 matlabの既定の実装は、平均二乗差が約10 ^ -10で驚異的に成功し、完全に補間されます。

10個のシグモイドニューロンの1つの隠れ層でニューラルネットワークを実装します。私はニューラルネットワークの初心者なので、愚かなコードには注意してください。

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で終わるため、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()

フィットが体系的に不完全であることがわかります。 enter image description here 一方、matlabは肉眼では完璧に見えますが、差は一様に<10 ^ -5です: enter image description here TensorFlowでMatlabネットワークの図を複製しようとしました:

enter image description here

ちなみに、この図はシグモイド活性化関数ではなくtanhを暗示しているようです。確かにドキュメント内で見つけることができません。ただし、TensorFlowでtanhニューロンを使用しようとすると、変数のnanでフィッティングがすぐに失敗します。何故かはわからない。

MatlabはLevenberg–Marquardtトレーニングアルゴリズムを使用します。ベイズ正則化は10 ^ -12の平均二乗でさらに成功します(おそらく浮動小数点演算の蒸気の領域にいます)。

TensorFlowの実装がなぜそれほど悪いのか、それを改善するために何ができるのか?

32
Arbil

50000回の繰り返しでトレーニングを試みましたが、0.00012エラーになりました。 Tesla K40では約180秒かかります。

enter image description here

この種の問題では、一次勾配降下法は適切ではないようで(しゃれを意図)、Levenberg–Marquardtまたはl-BFGSが必要です。 TensorFlowでそれらを実装した人はまだいないと思います。

Editこの問題にはtf.train.AdamOptimizer(0.1)を使用します。 3.13729e-05 4000回の反復後。また、デフォルトのストラテジーを備えたGPUも、この問題の悪い考えのようです。多くの小さな操作があり、オーバーヘッドにより、GPUバージョンは私のマシンのCPUの3倍遅くなります。

25

ちなみに、形状の問題と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)

とはいえ、LMAが2D曲線を近似するためのより一般的なDNNスタイルのオプティマイザーよりも優れていることは、おそらく驚くほどではありません。 Adamとその他の人々は、非常に高い次元の問題をターゲットにしています。 LMAは、非常に大規模なネットワークでは氷河的に遅くなり始めます (12-15を参照)。

16
dga