2017-09-18 2 views
0

私はTensorflowでMachine Learningにちょうど入りましたが、MNISTの初心者のチュートリアルを終えた後、隠されたレイヤーを挿入することによって、基本的には、マイケル・ニールセンの本の最初の章(ニューラルネットワークと深い学習)(hereを参照)からネットワークアーキテクチャを直接コピーすることに決めました。TensorflowのMNISTの1つの隠れ層を持つ完全に接続されたネットワークのトレーニング

Nielsenのコードはうまく動作しますが、次のTensorflowコードを使用しても同等の結果が得られませんでした。私は30のエポックのためのトレーニングの後に約17%の精度を得る

from tensorflow.examples.tutorials.mnist import input_data 
import tensorflow as tf 

mnist = input_data.read_data_sets("MNIST_data/", one_hot=True) 


def weight_variable(shape): 
    initial = tf.random_normal(shape) 
    return tf.Variable(initial) 

def bias_variable(shape): 
    initial = tf.random_normal(shape) 
    return tf.Variable(initial) 


x = tf.placeholder(tf.float32, [None, 784]) 

#hidden layer 
W_fc1 = weight_variable([784, 30]) 
b_fc1 = bias_variable([30]) 
h_fc1 = tf.sigmoid(tf.matmul(x, W_fc1) + b_fc1) 

#output layer 
W_fc2 = weight_variable([30, 10]) 
b_fc2 = bias_variable([10]) 
y = tf.sigmoid(tf.matmul(h_fc1, W_fc2) + b_fc2) 

y_ = tf.placeholder(tf.float32, [None, 10]) 
loss = tf.reduce_mean(tf.reduce_sum(tf.pow(y_ - y, 2), reduction_indices=[1])) #I also tried simply tf.nn.l2_loss(y_ - y) 
train_step = tf.train.GradientDescentOptimizer(3.0).minimize(loss) 

sess = tf.InteractiveSession() 
tf.global_variables_initializer().run() 

def get_accuracy(): 
    correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1)) 
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) 
    return sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}) 

for i in range(30): 
    batch_xs, batch_ys = mnist.train.next_batch(10) 
    sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys}) 
    print("Epoch {} accuracy: {:.2f}%".format(i+1, get_accuracy() * 100)) 

: - 私は間違っていないよ場合 - それはする必要があり、正確にニールセンが提案されたモデルを実装しています。 Nielsenのコードを使用すると、トレーニングの1エポック後に91%の精度が得られます。

明らかに私は何かが不足しています。私は精度を向上させようと努力してきましたが、トレーニングでは約60%まで改善できましたが、異なるバックエンドコードを使用しても同じネットワークで同様の結果が得られるはずです。私もハイパーパラメータで遊んでみましたが、同等の結果は得られませんでした。

私のコードに欠陥がありますか?

+1

30ステップはあまりありません。あなたは300の例を挙げるだけです。 forループを1000ステップ実行してみてください。私はそれが80〜90%になると思う。 – suharshs

答えて

2

suharshsに記載されているように、あなたの問題は、用語epochの誤解によるものです。厳密にはそうではありませんが、エポックは通常、トレーニングデータセット全体にわたる単一の反復です。ニールセンのコードをもう一度見てみると、これはSGDメソッドに反映されています。単一のエポックは、全体のtraining_dataを反復し、ミニバッチに分割されます。各エポックは、実際にはミニバッチのサイズで、わずか10サンプルです。

関連する問題