Tensorflow: мой классификатор радужной оболочки (без оценщиков) не работает - PullRequest
0 голосов
/ 03 мая 2018

Я изучаю тензорный поток и в качестве упражнения пытаюсь обучить классификатор для набора данных радужной оболочки. Я предварительно взял сетевую архитектуру из официального примера радужного тензорного потока , и я пытаюсь воссоздать его с помощью 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). Чтобы лучше понять, я напечатал матрицы путаницы на разных этапах и для разных прогонов: они часто показывают, что сеть предсказывает один и тот же результат для всех входных данных независимо от их функций или меток. Визуализация параметров сети с использованием тензорной доски показывает, что смещения меняются со временем, а весы (или ядра, как они определены в документации) не изменяются.

Должна быть ошибка в том, как я передаю данные, тренируюсь или что-то еще, но я не могу их найти. Не могли бы вы помочь?

1 Ответ

0 голосов
/ 03 мая 2018

Решение состояло в том, чтобы использовать питаемые итераторы, как объяснено в https://www.tensorflow.org/programmers_guide/datasets#creating_an_iterator. Код, размещенный в вопросе, должен быть исправлен следующим образом:

def parse_csv(line):
    data = tf.decode_csv(line, record_defaults=[[]] * 5)
    return tf.stack(data[:4]), data[4]    

# notice that there is no `get_next()` at the end
training_iterator = tf.data.TextLineDataset("../data/train.csv").map(parse_csv).shuffle(200).repeat().batch(
    32).make_one_shot_iterator()
validation_iterator = tf.data.TextLineDataset("../data/test.csv").map(parse_csv).shuffle(200).repeat().batch(
    32).make_one_shot_iterator()

handle = tf.placeholder(tf.string, shape=[])
x, y_ = tf.data.Iterator.from_string_handle(handle, training_iterator.output_types, training_iterator.output_shapes).get_next()

## [...more code...]

with tf.Session() as sess:
    tf.global_variables_initializer().run()

    training_handle = sess.run(training_iterator.string_handle())
    validation_handle = sess.run(validation_iterator.string_handle())

    for n in range(401):
        if n % 50 == 0:  # see what's going on every 50 steps
            acc, c = sess.run([accuracy, cm], feed_dict={handle: validation_handle})
            print(c, acc)
        else:  # train
            _ = sess.run(train_op, feed_dict={handle: training_handle})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...