Я изучаю тензорный поток и в качестве упражнения пытаюсь обучить классификатор для набора данных радужной оболочки. Я предварительно взял сетевую архитектуру из официального примера радужного тензорного потока , и я пытаюсь воссоздать его с помощью API слоев: это должна быть нейронная сеть с тремя скрытыми слоями размером 10, 20 и 10; после этого, так как радужная оболочка является трехсторонней классификационной проблемой, я помещаю окончательные плотные слои размером 3 с активацией softmax. Это код:
def parse_csv(line):
data = tf.decode_csv(line, record_defaults=[[]] * 5)
return tf.stack(data[:4]), data[4]
trn_data, trn_targ = tf.data.TextLineDataset("../data/train.csv").map(parse_csv).shuffle(200).repeat().batch(32).make_one_shot_iterator().get_next()
evl_data, evl_targ = tf.data.TextLineDataset("../data/test.csv").map(parse_csv).shuffle(200).repeat().batch(32).make_one_shot_iterator().get_next()
x = tf.placeholder(tf.float32, [None, 4], name="input")
y_ = tf.placeholder(tf.int64, [None, ], name="target")
# definition of the neural network
a1 = tf.layers.dense(x, 10, activation=tf.nn.relu)
a2 = tf.layers.dense(a1, 20, activation=tf.nn.relu)
a3 = tf.layers.dense(a2, 10, activation=tf.nn.relu)
y = tf.layers.dense(a3, 3, activation=tf.nn.softmax)
# training step
loss = tf.losses.softmax_cross_entropy(tf.one_hot(y_, 3), y)
train_op = tf.train.AdamOptimizer(0.001).minimize(loss, global_step=tf.train.get_or_create_global_step())
# evaluation of the results
predictions = tf.argmax(y, 1, name="predictions")
correct_prediction = tf.equal(y_, predictions) # boolean tensor that says if we did good
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
cm = tf.confusion_matrix(y_, predictions)
with tf.Session() as sess:
tf.global_variables_initializer().run()
for n in range(401):
if n % 50 == 0: # see what's going on every 50 steps
feed_train = {x: sess.run(evl_data), y_: sess.run(evl_targ)}
acc, c = sess.run([accuracy, cm], feed_dict=feed_train)
print(c, acc)
else: # train
feed_eval = {x: sess.run(trn_data), y_: sess.run(trn_targ)}
_ = sess.run(train_op, feed_dict=feed_eval)
Однако точность действительно плохая и примерно совместима с предположением, что сеть ничего не изучает (она колеблется около 0,33). Чтобы лучше понять, я напечатал матрицы путаницы на разных этапах и для разных прогонов: они часто показывают, что сеть предсказывает один и тот же результат для всех входных данных независимо от их функций или меток. Визуализация параметров сети с использованием тензорной доски показывает, что смещения меняются со временем, а весы (или ядра, как они определены в документации) не изменяются.
Должна быть ошибка в том, как я передаю данные, тренируюсь или что-то еще, но я не могу их найти. Не могли бы вы помочь?