Я прочитал книгу 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])
Было бы очень здорово, если бы вы могли сказать мне, что происходит не так :-)
Дело в том, что я хочу точно воспроизвести сеть Nielsen, чтобы проверить, что все работает нормально. Если я выберу GradientDescent с learnng_rate = 0.001, я получаю только точность 10%. Если я выберу AdamOptimizer с курсом обучения 0.001, я получаю точность 95%, но это не решает мою проблему с перекрестками –
Возможно, есть ошибка в версии Nielsen, которая заставляет ее работать с такой высокой частотой ошибок?Градиентный спуск TensorFlow прошел через множество тестов –
Nielsens net отлично работает для указанной установки, но тензорный поток плохой. Я думаю, что есть ошибка в тензорном потоке GradientDescentOptimizer –