Я пытаюсь выяснить, как уменьшить ошибку в моем LSTM.Это странный вариант использования, потому что вместо классификации мы берем короткие списки (длиной до 32 элементов) и выводим серию действительных чисел в диапазоне от -1 до 1, представляющих углы.По сути, мы хотим восстановить короткие белковые петли из аминокислотных входов.
В прошлом у нас были избыточные данные в наших наборах данных, поэтому указанная точность была неверной.После удаления избыточных данных наша точность проверки стала намного хуже, что говорит о том, что наша сеть научилась запоминать наиболее частые примеры.
Наш набор данных состоит из 10 000 элементов, разделенных 70/20/10 между поездом, проверкой и тестированием,Мы используем двунаправленный LSTM следующим образом:
x = tf.cast(tf_train_dataset, dtype=tf.float32)
output_size = FLAGS.max_cdr_length * 4
dmask = tf.placeholder(tf.float32, [None, output_size], name="dmask")
keep_prob = tf.placeholder(tf.float32, name="keepprob")
sizes = [FLAGS.lstm_size,int(math.floor(FLAGS.lstm_size/2)),int(math.floor(FLAGS.lstm_size/ 4))]
single_rnn_cell_fw = tf.contrib.rnn.MultiRNNCell( [lstm_cell(sizes[i], keep_prob, "cell_fw" + str(i)) for i in range(len(sizes))])
single_rnn_cell_bw = tf.contrib.rnn.MultiRNNCell( [lstm_cell(sizes[i], keep_prob, "cell_bw" + str(i)) for i in range(len(sizes))])
length = create_length(x)
initial_state = single_rnn_cell_fw.zero_state(FLAGS.batch_size, dtype=tf.float32)
initial_state = single_rnn_cell_bw.zero_state(FLAGS.batch_size, dtype=tf.float32)
outputs, states = tf.nn.bidirectional_dynamic_rnn(cell_fw=single_rnn_cell_fw, cell_bw=single_rnn_cell_bw, inputs=x, dtype=tf.float32, sequence_length = length)
output_fw, output_bw = outputs
states_fw, states_bw = states
output_fw = last_relevant(FLAGS, output_fw, length, "last_fw")
output_bw = last_relevant(FLAGS, output_bw, length, "last_bw")
output = tf.concat((output_fw, output_bw), axis=1, name='bidirectional_concat_outputs')
test = tf.placeholder(tf.float32, [None, output_size], name="train_test")
W_o = weight_variable([sizes[-1]*2, output_size], "weight_output")
b_o = bias_variable([output_size],"bias_output")
y_conv = tf.tanh( ( tf.matmul(output, W_o)) * dmask, name="output")
По сути, мы используем 3 слоя LSTM с 256, 128 и 64 единицами каждый.Мы предпринимаем последний шаг как прямого, так и обратного проходов и объединяем их вместе.Они поступают в окончательный, полностью связанный слой, который представляет данные так, как нам нужно.Мы используем маску, чтобы установить эти шаги, нам не нужно обнулять.
Наша функция стоимости снова использует маску и принимает среднее значение квадрата разницы.Мы строим маску из тестовых данных.Значения, которые нужно игнорировать, установлены на -3.0.
def cost(goutput, gtest, gweights, FLAGS):
mask = tf.sign(tf.add(gtest,3.0))
basic_error = tf.square(gtest-goutput) * mask
basic_error = tf.reduce_sum(basic_error)
basic_error /= tf.reduce_sum(mask)
return basic_error
Для обучения сети я использовал различные оптимизаторы.Самые низкие оценки были получены с AdamOptimizer.Другие, такие как Adagrad, Adadelta, RMSProp, имеют тенденцию к плоской линии около 0,3 / 0,4 ошибки, что не особенно велико.
Наша скорость обучения составляет 0,004, размер партии 200. Мы используем слой с вероятностью 0,5 0,5.
Я пытался добавить больше слоев, изменить скорость обучения, размеры пакетов, даже представление данных.Я предпринял попытку регуляризации партии, регуляризации веса L1 и L2 (хотя, возможно, и некорректно), и вместо этого я даже подумал о переходе на подход с использованием конвеета.
Ничто, похоже, не имеет значения.То, что, кажется, работает, меняет оптимизатор.Адам кажется более шумным, поскольку он улучшается, но он становится ближе, чем другие оптимизаторы.
Нам нужно приблизиться к значению, намного ближе к 0,05или 0,01.Иногда ошибка обучения достигает 0,09, но проверка не выполняется.Я управлял этой сетью около 500 эпох (около 8 часов), и она имеет тенденцию улаживаться около 0,2 ошибки проверки.
Я не совсем уверен, что делать дальше.Сниженная скорость обучения может помочь, но я подозреваю, что есть кое-что более фундаментальное, что мне нужно сделать.Это может быть что-то простое, например, ошибка в коде - мне нужно дважды проверить маскировку,