2015-11-24 5 views
6

私はTensorFlowで大きなことを目指していますが、私は小さく始めようとしています。TensorFlow - なぜこのsofmax回帰は何も学ばないのですか?

小さな灰色の四角形(ノイズが少ない)があり、その色(たとえば、3つのカテゴリ:黒、灰色、白)に従って分類したいと考えています。私は四角形と1ホットベクトルを生成するための小さなPythonクラスを作成し、基本的なMNISTの例を修正してフィードしました。

しかし、何も学習しません。 3つのカテゴリについては、常に≒33%が正しいと推測されます。

import tensorflow as tf 
import generate_data.generate_greyscale 

data_generator = generate_data.generate_greyscale.GenerateGreyScale(28, 28, 3, 0.05) 
ds = data_generator.generate_data(10000) 
ds_validation = data_generator.generate_data(500) 
xs = ds[0] 
ys = ds[1] 
num_categories = data_generator.num_categories 

x = tf.placeholder("float", [None, 28*28]) 
W = tf.Variable(tf.zeros([28*28, num_categories])) 
b = tf.Variable(tf.zeros([num_categories])) 
y = tf.nn.softmax(tf.matmul(x,W) + b) 
y_ = tf.placeholder("float", [None,num_categories]) 
cross_entropy = -tf.reduce_sum(y_*tf.log(y)) 
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy) 
init = tf.initialize_all_variables() 
sess = tf.Session() 
sess.run(init) 

# let batch_size = 100 --> therefore there are 100 batches of training data 
xs = xs.reshape(100, 100, 28*28) # reshape into 100 minibatches of size 100 
ys = ys.reshape((100, 100, num_categories)) # reshape into 100 minibatches of size 100 

for i in range(100): 
    batch_xs = xs[i] 
    batch_ys = ys[i] 
    sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys}) 

correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1)) 
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float")) 

xs_validation = ds_validation[0] 
ys_validation = ds_validation[1] 
print sess.run(accuracy, feed_dict={x: xs_validation, y_: ys_validation}) 

マイデータ・ジェネレータは、次のようになります。

import numpy as np 
import random 

class GenerateGreyScale(): 
    def __init__(self, num_rows, num_cols, num_categories, noise): 
     self.num_rows = num_rows 
     self.num_cols = num_cols 
     self.num_categories = num_categories 
     # set a level of noisiness for the data 
     self.noise = noise 

    def generate_label(self): 
     lab = np.zeros(self.num_categories) 
     lab[random.randint(0, self.num_categories-1)] = 1 
     return lab 

    def generate_datum(self, lab): 
     i = np.where(lab==1)[0][0] 
     frac = float(1)/(self.num_categories-1) * i 
     arr = np.random.uniform(max(0, frac-self.noise), min(1, frac+self.noise), self.num_rows*self.num_cols) 
     return arr 

    def generate_data(self, num): 
     data_arr = np.zeros((num, self.num_rows*self.num_cols)) 
     label_arr = np.zeros((num, self.num_categories)) 
     for i in range(0, num): 
      label = self.generate_label() 
      datum = self.generate_datum(label) 
      data_arr[i] = datum 
      label_arr[i] = label 
     #data_arr = data_arr.astype(np.float32) 
     #label_arr = label_arr.astype(np.float32) 
     return data_arr, label_arr 

答えて

2

dgaとsyncdの応答が役に立ちましたが、ゼロ以外の重みの初期化と大きなデータセットを使用しましたが、役に立たなかった。最終的には、別の最適化アルゴリズムを使用していました。

私が交換:

train_step = tf.train.AdamOptimizer(0.0005).minimize(cross_entropy)

train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

を私はまた、このような収束が得られ、いくつかのエポックのために訓練するループのための別のループのための研修を組み込み:

===# EPOCH 0 #=== 
Error: 0.370000004768 
===# EPOCH 1 #=== 
Error: 0.333999991417 
===# EPOCH 2 #=== 
Error: 0.282000005245 
===# EPOCH 3 #=== 
Error: 0.222000002861 
===# EPOCH 4 #=== 
Error: 0.152000010014 
===# EPOCH 5 #=== 
Error: 0.111999988556 
===# EPOCH 6 #=== 
Error: 0.0680000185966 
===# EPOCH 7 #=== 
Error: 0.0239999890327 
===# EPOCH 8 #=== 
Error: 0.00999999046326 
===# EPOCH 9 #=== 
Error: 0.00400000810623 

EDIT - その理由:私は手動で良い学習スケジュールを選択していないという問題があったと思うし、Adamは自動的に良いものを生成することができました。

3

は手始めに、ランダムな値ではなく、ゼロであなたのW行列を初期化してみてください - あなたはときに出力で動作するようにオプティマイザは何も与えていませんすべての入力に対してすべてゼロです。代わりの

W = tf.Variable(tf.zeros([28*28, num_categories])) 

試してみてください。

W = tf.Variable(tf.truncated_normal([28*28, num_categories], 
            stddev=0.1)) 
+0

)=私は私がやったように、チュートリアルの設定に従うようにしようとしているいくつかの初心者が立ち往生here..in場合、私の2セントを追加することを考え出しとあなたと彼らの[チュートリアル](http://tensorflow.org/tutorials/mnist/pros/index.html#weight-initialization)で提案されているように、私の重みと偏りについては 'tf.constant()'を参照してください。しかし、まだ変更はありません:yはランダムに推測されます。 :( –

+0

あなたのデータにはバグはありませんか?ds [0] 100アイテムですか? ds = data_generator.generate_data(10000) xs = ds [0] xs = xs.reshape(100,100,28) * 28) あなたが再構成する前にxsが適切な数値を持っていればもっと楽になります... – dga

+0

こんにちはnparray xsは形(10000,784)として始まり、次に(100,100,784)にサイズ変更されます。ありがとう! –

2

あなたの問題は、あなたのグラデーションがNaNになるために損失関数を引き起こし、際限なく増加/減少していることです。

はこの質問を見てみましょう: Why does TensorFlow example fail when increasing batch size?

さらに、あなたがステップの十分な数のためのモデルを実行していることを確認してください。列車のデータセット(100回* 100例)で一度だけ実行していますが、これでは収束するには不十分です。それを2000年のようなもの(データセットを通して20回実行)に増やしてください。

編集:(コメントはできませんので、私の考えをここに追加します): 0.001のような学習率にするのであれば、GradientDescentOptimizerを使用することができます。それは問題です、あなたの学習率はあなたが使っていた損失関数にとって高すぎます。

または、勾配をそれほど増減させない別の損失関数を使用します。 crossEntropyの定義でtf.reduce_sumの代わりにtf.reduce_meanを使用してください。

0

同様の問題が発生したときにこの質問が見つかりました。フィーチャを拡大縮小して固定しました。

少し背景:私はテンソルフローチュートリアルに従っていましたが、Kaggle(see data here)のデータを使ってモデリングを行ったかったのですが、最初は同じ問題を抱えていました。 ..トラブルシューティングのラウンドの後、私はKaggleのデータが全く異なるスケールであることに気付きました。したがって、テンソルフローのMNISTデータセットと同じスケール(0,1)を共有するようにデータをスケーリングしました。

ちょうど `)私は今(` tf.truncated_normalを使用しています

+0

はい - 転送学習では、新しいデータが次のように前処理されていることを確認することが不可欠です。転送しているモデルの元のトレーニングデータ。私が持っていたこの問題は、学習率と関係していたことに注意してください。私は[0、1]の区間で生成された人工データを使って最初からモデルを訓練していました。 –

関連する問題