2016-06-18 3 views
0

Я прочитал книгу Neuralnetworksanddeeplearning.com Майкла Нильсена о нейронных сетях. Он всегда делает пример с данными MNIST. Теперь я взял его код и сконструировал точно такую ​​же сеть в Tensorflow, но я понял, что результаты в Tensorflow не совпадают (они намного хуже).MNIST Tensorflow vs code от Michael Nielsen

Вот подробности:

1) Код от Michael Nielsen можно найти на https://github.com/kanban1992/MNIST_Comparison/tree/master/Michael_Nielsen. вы можете начать все с

python start_2.py 

Сеть имеет

  • 3 скрытых слоев в 30 нейронов.
  • все функции активации являются сигмоидами
  • Я использую стохастический градиентный спуск (скорость обучения 3.0) с обратным прополнением. Размер партии равен 10
  • Используется функция квадратичной стоимости без какой-либо регуляризации.
  • Матричная матрица, которая соединяет слои l и l + 1, инициализируется гауссовой плотностью вероятности с stddev = 1/sqrt (количество нейронов в слое l) и mu = 0.0. Уклонения инициализируются стандартным нормальным распределением.
  • после обучения в течение 5 эпох. Я получаю 95% изображений в наборе валидации, классифицированном правильно.

Этот подход должен быть правильным, потому что он работает хорошо, и я не изменял его!

2) Реализация тензорного потока была выполнена мной и имеет ту же структуру, что и сеть Nielsen, описанная выше в пункте 1). Полный код можно найти на https://github.com/kanban1992/MNIST_Comparison/tree/master/tensorflow и работать с

python start_train.py 

С приближением tensorflow я получаю точность 10% (что не будет такой же, как случайное угадывание!) Так что-то не работает, и у меня нет идея что !?

Вот отрывок из самой важной части кода:

x_training,y_training,x_validation,y_validation,x_test,y_test = mnist_loader.load_data_wrapper() 

N_training=len(x_training) 
N_validation=len(x_validation) 
N_test=len(x_test) 


N_epochs = 5 

learning_rate = 3.0 
batch_size = 10 


N1 = 784 #equals N_inputs 
N2 = 30 
N3 = 30 
N4 = 30 
N5 = 10 

N_in=N1 
N_out=N5 

x = tf.placeholder(tf.float32,[None,N1])#don't take the shape=(batch_size,N1) argument, because we need this for different batch sizes 

W2 = tf.Variable(tf.random_normal([N1, N2],mean=0.0,stddev=1.0/math.sqrt(N1*1.0)))# Initialize the weights for one neuron with 1/sqrt(Number of weights which enter the neuron/ Number of neurons in layer before) 
b2 = tf.Variable(tf.random_normal([N2])) 
a2 = tf.sigmoid(tf.matmul(x, W2) + b2) #x=a1 

W3 = tf.Variable(tf.random_normal([N2, N3],mean=0.0,stddev=1.0/math.sqrt(N2*1.0))) 
b3 = tf.Variable(tf.random_normal([N3])) 
a3 = tf.sigmoid(tf.matmul(a2, W3) + b3) 

W4 = tf.Variable(tf.random_normal([N3, N4],mean=0.0,stddev=1.0/math.sqrt(N3*1.0))) 
b4 = tf.Variable(tf.random_normal([N4])) 
a4 = tf.sigmoid(tf.matmul(a3, W4) + b4) 

W5 = tf.Variable(tf.random_normal([N4, N5],mean=0.0,stddev=1.0/math.sqrt(N4*1.0))) 
b5 = tf.Variable(tf.random_normal([N5])) 
y = tf.sigmoid(tf.matmul(a4, W5) + b5) 

y_ = tf.placeholder(tf.float32,[None,N_out]) # ,shape=(batch_size,N_out) 


quadratic_cost= tf.scalar_mul(1.0/(N_training*2.0),tf.reduce_sum(tf.squared_difference(y,y_))) 

train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(quadratic_cost) 
init = tf.initialize_all_variables() 

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


#batch size of training input 
N_training_batch=N_training/batch_size #rounds to samllest integer 

correct=[0]*N_epochs 
cost_training_data=[0.0]*N_epochs 

for i in range(0,N_epochs): 
    for j in range(0,N_training_batch): 
     start=j*batch_size 
     end=(j+1)*batch_size 
     batch_x=x_training[start:end] 
     batch_y=y_training[start:end] 

     sess.run(train_step, feed_dict={x: batch_x, 
     y_: batch_y}) 

    perm = np.arange(N_training) 
    np.random.shuffle(perm) 
    x_training = x_training[perm] 
    y_training = y_training[perm] 


    #cost after each epoch 
    cost_training_data[i]=sess.run(quadratic_cost, feed_dict={x: x_training, 
     y_: y_training}) 
    #correct predictions after each epoch 
    y_out_validation=sess.run(y,feed_dict={x: x_validation}) 
    for k in range(0,len(y_out_validation)): 
     arg=np.argmax(y_out_validation[k]) 
     if 1.0==y_validation[k][arg]: 
      correct[i]+=1 

    print "correct after "+str(i)+ " epochs: "+str(correct[i]) 

Было бы очень здорово, если бы вы могли сказать мне, что происходит не так :-)

ответ

1

Ваша скорость обучения, кажется высоким для градиента. Попробуйте номер больше .0001. Поднимитесь или опустите оттуда.

Мне нравится Адам оптимизатора, убедитесь, что вы начинаете с меньшей скоростью обучения (.001 Я думаю, это по умолчанию для Адама):

Оптимизатор = tf.train.AdamOptimizer (learning_rate)

+0

Дело в том, что я хочу точно воспроизвести сеть Nielsen, чтобы проверить, что все работает нормально. Если я выберу GradientDescent с learnng_rate = 0.001, я получаю только точность 10%. Если я выберу AdamOptimizer с курсом обучения 0.001, я получаю точность 95%, но это не решает мою проблему с перекрестками –

+0

Возможно, есть ошибка в версии Nielsen, которая заставляет ее работать с такой высокой частотой ошибок?Градиентный спуск TensorFlow прошел через множество тестов –

+0

Nielsens net отлично работает для указанной установки, но тензорный поток плохой. Я думаю, что есть ошибка в тензорном потоке GradientDescentOptimizer –

Смежные вопросы