3darray обучение / тестирование TensorFlow RNN LSTM

(Я проверяю свои способности писать короткие, но эффективные вопросы, поэтому дайте мне знать, как я здесь)

Я пытаюсь обучить / протестировать рекуррентную нейронную сеть тензорного потока, в частности LSTM, с некоторыми испытаниями данных временных рядов в следующем формате ndarray:

[[[time_step_trial_0, feature, feature, ...]
  [time_step_trial_0, feature, feature, ...]]                  
 [[time_step_trial_1, feature, feature, ...]
  [time_step_trial_1, feature, feature, ...]]
 [[time_step_trial_2, feature, feature, ...]
  [time_step_trial_2, feature, feature, ...]]]

the 1d часть этого 3darray содержит шаг времени a и все значения объектов, которые наблюдались на этом шаге времени. The блок содержит все массивы 1d (временные шаги), которые были отмечены в одном испытании. The блок содержит все 2d-блоки (испытания), записанные для набора данных временных рядов. Для каждого испытания частота шага времени постоянна, а интервал окна одинаков во всех испытаниях (от 0 до 50 секунд, от 0 до 50 секунд и т. д.).

например, мне даны данные для гоночных автомобилей Формулы 1, таких как крутящий момент, скорость, ускорение, скорость вращения и т. д. В течение определенного интервала времени запись шагов времени каждые 0,5 секунды, I сформируйте массивы 1d с каждым шагом времени по сравнению с записанными функциями, записанными на этом шаге времени. Затем я формирую 2D-массив вокруг всех временных шагов, соответствующих одному запуску гоночного автомобиля Формулы 1 на трассе. Я создаю окончательный 3D-массив, содержащий все автомобили F1 и их данные временных рядов. Я хочу обучить и протестировать модель для обнаружения аномалий в общих траекториях F1 на курсе для новых автомобилей.

в настоящее время я знаю, что модели TensorFlow поддерживают 2d-массивы для обучения и тестирования. Я был интересно, какие процедуры мне придется пройти, чтобы иметь возможность обучать и тестировать модель на всех независимых испытаниях (2d), содержащихся в этом 3darray. Кроме того, в будущем я буду проводить дополнительные испытания. Итак, какие правильные процедуры нужно пройти, чтобы постоянно обновлять мою модель новыми данными/испытаниями для укрепления моей LSTM.

вот модель, которую я пытался первоначально воспроизвести для другой цели, отличной от человеческой деятельности: https://github.com/guillaume-chevalier/LSTM-Human-Activity-Recognition. Еще более возможной моделью будет так что я бы предпочел посмотреть для обнаружения аномалий в данных временных рядов: https://arxiv.org/abs/1607.00148. Я хочу построить модель обнаружения аномалий, что, учитывая набор аномальных временных рядов данных, можно обнаружить аномалии в тестовых данных, где часть данных за определенный период времени определяется как "из семьи."

2 ответов


ваша входная форма и соответствующая модель зависят от того, почему вы хотите обнаружить аномалию. Вы можете рассмотреть:

1. Особенность только аномалия: Здесь вы рассматриваете индивидуальные особенности и решаете, является ли любой из них аномальным, не учитывая, когда его измеряют. В вашем примере,функция [крутящий момент, скорость, ускорение,...] является аномалией, если один или несколько является выбросом по отношению к другим функциям . В этом случае ваши входные данные должны иметь форму [batch, features].

2. Время-особенность аномалии: Здесь ваши входные данные зависят от того, когда вы измеряете функцию. Ваша текущая функция может зависеть от предыдущих функций, измеренных с течением времени. Например, может существовать объект, значение которого является выбросом, если он появляется в момент времени 0, но не выброс, если он появляется во времени furture. В этом случае вы разделяете каждый из ваших трасс с перекрывающимися временными окнами и формируете набор функций form [batch, time_window, features].

Это должно быть очень просто начать с (1) используя autoencoder где вы тренируете автоматическ-шифратор и на ошибке между входным сигналом и выходом, вы можете выбрать порог как 2 стандартных деватионс от середины для того чтобы определить ли свой выброс или не.

на (2), вы можете следовать второй статье, которую вы упомянули, используя модель seq2seq, где ваша ошибка декодера определит, какие функции являются выбросами. Вы можете проверить на этой для реализации таких модель.


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

У вас будет 3 измерения размеров:

feature_size = количество различной характеристики (крутящий момент, скорость и т. д.)

number_of_time_steps = количество временных шагов, собранных для одного автомобиля

number_of_cars = количество автомобилей

это, скорее всего, будет проще всего прочитать ваш данные в виде набора матриц, где каждая матрица соответствует одному полному образцу (все временные шаги для одного автомобиля).

вы можете расположить эти матрицы так, чтобы каждая строка была наблюдением, а каждый столбец-другим параметром (или наоборот, вам может потребоваться транспонировать матрицы, посмотрите, как форматируется ваш сетевой вход).

таким образом, каждая матрица имеет размер: number_of_time_steps x feature_size (#строки X #столбцы). У вас будут разные матрицы number_of_cars. Каждая матрица является образцом.

преобразовать массив в формат, вы можете использовать этот блок кода (обратите внимание, вы уже можете открыть единого образца в массиве с[н], но это делает его так что форма доступна элементы, что вы ожидаете):

import numpy as np

A = [[['car1', 'timefeatures1'],['car1', 'timefeatures2']],
     [['car2', 'timefeatures1'],['car2', 'timefeatures2']], 
     [['car3', 'timefeatures1'],['car3', 'timefeatures2']]
    ]

easy_format = np.array(A)

Теперь вы можете получить индивидуальный образец с easy_format[n], где n-образец, который вы хотите.

easy_format[1] prints

array([['car2', 'timefeatures1'],
       ['car2', 'timefeatures2']],
      dtype='|S12')

easy_format[1].shape = (2,2)

Теперь, когда вы можете это сделать, вы можете отформатировать их, как вам нужно для сети, которую вы используете (транспонирование строк и столбцов при необходимости, представление одного образца за раз или всех сразу и т. д.)

то, что вы хотите сделать (если я правильно читаю эту вторую статью), скорее всего, требует последовательности последовательности lstm или rnn. Ваша исходная последовательность-это ваш временной ряд для данной пробной версии, и вы генерируете промежуточный набор весов (вложение), который может воссоздать эту исходную последовательность с небольшим количеством ошибок. Ты делаешь это для всех испытаний. Вы будет тренировать этот lstm на серии разумно нормальных испытаний и заставить его хорошо работать (точно реконструировать последовательность). Затем вы можете использовать тот же набор вложений, чтобы попытаться восстановить новую последовательность, и если она имеет высокую ошибку восстановления, вы можете предположить, что она аномальна.

проверьте это РЕПО для образца того, что вы хотите вместе с объяснениями того, как его использовать и что делает код (он отображает только последовательность целых чисел в другую последовательность целых чисел, но может легко быть расширен на карте последовательность векторов в последовательности векторов): https://github.com/ichuang/tflearn_seq2seq шаблон ты определить только ваш оригинальный последовательности. Вы также можете взглянуть на autoencoders для этой проблемы.

Final Edit: проверьте этот репозиторий: https://github.com/beld/Tensorflow-seq2seq-autoencoder/blob/master/simple_seq2seq_autoencoder.py

Я изменил код в нем очень немного, чтобы работать на новейшая версия tensorflow и сделать некоторые имена переменных более ясными. Вы должны иметь возможность изменить его для запуска в своем наборе данных. Прямо сейчас у меня просто есть Автокод случайно сгенерированного массива 1 и 0. Вы сделаете это для большого подмножества ваших данных, а затем посмотрите, были ли другие данные восстановлены точно или нет (гораздо более высокая ошибка, чем средняя, может означать аномалию).

import numpy as np
import tensorflow as tf


learning_rate = 0.001
training_epochs = 30000
display_step = 100

hidden_state_size = 100
samples = 10
time_steps = 20
step_dims = 5
test_data = np.random.choice([ 0, 1], size=(time_steps, samples, step_dims))

initializer = tf.random_uniform_initializer(-1, 1)

seq_input = tf.placeholder(tf.float32, [time_steps, samples, step_dims])

encoder_inputs = [tf.reshape(seq_input, [-1, step_dims])]


decoder_inputs = ([tf.zeros_like(encoder_inputs[0], name="GO")]
                  + encoder_inputs[:-1])
targets = encoder_inputs
weights = [tf.ones_like(targets_t, dtype=tf.float32) for targets_t in targets]

cell = tf.contrib.rnn.BasicLSTMCell(hidden_state_size)
_, enc_state = tf.contrib.rnn.static_rnn(cell, encoder_inputs, dtype=tf.float32)
cell = tf.contrib.rnn.OutputProjectionWrapper(cell, step_dims)
dec_outputs, dec_state = tf.contrib.legacy_seq2seq.rnn_decoder(decoder_inputs, enc_state, cell)

y_true = [tf.reshape(encoder_input, [-1]) for encoder_input in encoder_inputs]
y_pred = [tf.reshape(dec_output, [-1]) for dec_output in dec_outputs]

loss = 0
for i in range(len(y_true)):
    loss += tf.reduce_sum(tf.square(tf.subtract(y_pred[i], y_true[i])))
optimizer = tf.train.AdamOptimizer(learning_rate).minimize(loss)

init = tf.initialize_all_variables()

with tf.Session() as sess:
    sess.run(init)
    x = test_data
    for epoch in range(training_epochs):
        #x = np.arange(time_steps * samples * step_dims)
        #x = x.reshape((time_steps, samples, step_dims))
        feed = {seq_input: x}
        _, cost_value = sess.run([optimizer, loss], feed_dict=feed)
        if epoch % display_step == 0:
            print "logits"
            a = sess.run(y_pred, feed_dict=feed)
            print a
            print "labels"
            b = sess.run(y_true, feed_dict=feed)
            print b

            print("Epoch:", '%04d' % (epoch+1), "cost=", "{:.9f}".format(cost_value))

print("Optimization Finished!")