2015-11-15 7 views
28

おもちゃの例として、私は100の無ノイズデータポイントからの関数f(x) = 1/xを適合させようとしています。 matlabのデフォルトの実装は、平均平方差〜10^-10で劇的に成功し、完全に補間します。なぜこのTensorFlowの実装はMatlabのNNよりもあまり成功していませんか?

私は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で終わります。したがって、約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() 

で可視化我々はフィット感が体系的に不完全である見ることができます: enter image description here MATLAB 1は違い均一< 10^-5と肉眼では完璧に見えるながら:私は複製しようとしている enter image description here Matlabのネットワークの図はTensorFlow:

enter image description here

尚、図はシグモイドACTIVAではなく、双曲線正接を暗示するようです機能を備えています。私はドキュメントのどこにいてもそれを見つけることはできません。しかし、TensorFlowでtanhニューロンを使用しようとすると、フィッティングがすぐに変数のnanで失敗します。何故かはわからない。

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

TensorFlowの実装がそれほど悪くなっているのはなぜですか?さらに改善するためには何ができますか?

+0

私はまだテンソルの流れを調べていません。それは残念ですが、あなたはその 'toNd'関数を使っていくつかの奇妙なことをしています。 'np。リストをndarrayに変換したい場合は、 'np.array(my_list)'だけが必要です。余分な軸が必要な場合は、 'new_array = my_array [np.newaxis、:]'それはそれをすると思われるのでゼロ誤差が足りないのを止めることができます。ほとんどのデータにはノイズがあり、必ずしもトレーニングの誤差がゼロになる必要はありません。 'reduce_mean'で判断すると、相互検証を使用している可能性があります。 –

+0

@AdamAcosta 'toNd'は間違いなく私の経験不足のためのストップギャップです。私は以前に 'np.array'を試しました。問題は' np.array([5,7])。shape'は '(2,1)'ではなく '(2)'です。 'my_array [np.newaxis、:]'はこれを修正するようですが、ありがとう!私はPythonを使用せず、むしろ日常的にF#を使用します。 – Arbil

+0

@AdamAcostaI 'reduce_mean'はクロスバリデーションをしないと思います。ドキュメントから: 'テンソルの次元間の要素の平均を計算する '。 Matlabはクロス検証を行っていますが、これは私の心にはクロスサンプルなしと比較してトレーニングサンプルのフィット感を下げるべきでしょうか? – Arbil

答えて

23

私は50000回の練習を試みましたが、それは0.00012エラーに達しました。テスラK40で約180秒かかります。

enter image description here

この種の問題のために、一次勾配降下が良いフィット(しゃれ意図)ではないようだ、とあなたは、レーベンバーグ・マルカートまたはL-BFGSを必要としています。誰もまだTensorFlowで実装していないと思います。

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

+0

これをチェックしていただきありがとうございます。私のループの5000を意味するので、20Mの基本的なトレーニングが実行されますか?隠れたレイヤーをtanhニューロンに変更すると失敗することを確認できますか?もしそうなら、なぜそれが起こるか知っていますか? – Arbil

+1

xrange(4001)をxrange(5000)に変更しました。 tanhの場合、学習率が0.5になるほど訓練が異なるように見えます。一般に、グラディエント降下については、各問題の学習率を調整する必要があります。tf.train.GradientDescentOptimizer(0.1) –

+0

を実行すると動作するようです。非常に奇妙なxrange(0、5000)は、4kの範囲よりも精度が向上し、GPUでは180秒かかる。私は精度を変えずにCPU上で同じ範囲を実行し、10秒以下で済みます。 – Arbil

16

btwここでは、いくつかの形状問題とtfとnpの間の不必要なバウンスをクリーンアップする上記のややきれいなバージョンです。これは、40Kステップの後3E-08達成し、または約1.5E-5 4000の後:

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は、フィッティングのために、より一般的なDNNスタイルのオプティマイザより良いやっていることはおそらくあまりにも驚くべきことではないのです、と述べているすべての2Dカーブ。アダムと残りは非常に高次元の問題をターゲットにしており、LMA starts to get glacially slow for very large networks(12-15を参照)。

関連する問題