Классификация последовательности с последовательностью с переменной длиной последовательности в керасе - PullRequest
0 голосов
/ 14 ноября 2018

Я хотел бы обучить сеть LSTM или GRU в TensorFlow / Keras, чтобы непрерывно распознавать, идет ли пользователь или нет, на основе данных от датчиков движения (акселерометр и гироскоп).У меня есть 50 входных последовательностей с длинами от 581 до 5629 временных шагов и 6 функций и 50 соответствующих выходных последовательностей логических значений.Моя проблема в том, что я не знаю, как передать данные тренировки в метод fit ().

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

Вот проблема в коде:

import tensorflow as tf
import numpy as np

# Load data from file
x_list, y_list = loadSequences("train.csv")

# x_list is now a list of arrays (n,6) of float64, where n is the timesteps
# and 6 is the number of features, sorted by increasing sequence lengths.
# y_list is a list of arrays (n,1) of Boolean.

x_train = # WHAT DO I WRITE HERE?
y_train = # AND HERE?

model = tf.keras.models.Sequential([
            tf.keras.layers.Masking(),
            tf.keras.layers.LSTM(32, return_sequences=True),
            tf.keras.layers.Dense(2, activation=tf.nn.softmax)
        ])
model.compile(optimizer='adam',
            loss='sparse_categorical_crossentropy',
            metrics=['accuracy'])
model.fit(x_train, y_train, batch_size=10, epochs=100)

Ответы [ 2 ]

0 голосов
/ 23 ноября 2018

В случае, если это кому-то поможет, вот как я реализовал решение:

import tensorflow as tf
import numpy as np

# Load data from file
x_list, y_list = loadSequences("train.csv")

# x_list is now a list of arrays (m,n) of float64, where m is the timesteps
# and n is the number of features.
# y_list is a list of arrays (m,1) of Boolean.
assert len(x_list) == len(y_list)
num_sequences = len(x_list)
num_features = len(x_list[0][0])
batch_size = 10
batches_per_epoch = 5
assert batch_size * batches_per_epoch == num_sequences

def train_generator():
    # Sort by length so the number of timesteps in each batch is minimized
    x_list.sort(key=len)
    y_list.sort(key=len)
    # Generate batches
    while True:
        for b in range(batches_per_epoch):
            longest_index = (b + 1) * batch_size - 1
            timesteps = len(x_list[longest_index])
            x_train = np.zeros((batch_size, timesteps, num_features))
            y_train = np.zeros((batch_size, timesteps, 1))
            for i in range(batch_size):
                li = b * batch_size + i
                x_train[i, 0:len(x_list[li]), :] = x_list[li]
                y_train[i, 0:len(y_list[li]), 0] = y_list[li]
            yield x_train, y_train

model = tf.keras.models.Sequential([
            tf.keras.layers.Masking(mask_value=0., input_shape=(None,num_features)),
            tf.keras.layers.LSTM(32, return_sequences=True),
            tf.keras.layers.Dense(2, activation=tf.nn.softmax)
        ])
model.compile(optimizer='adam',
            loss='sparse_categorical_crossentropy',
            metrics=['accuracy'])
model.fit_generator(train_generator(), steps_per_epoch=batches_per_epoch, epochs=100)
0 голосов
/ 14 ноября 2018

Вы можете сделать что-то вроде этого

используйте функцию генератора, посмотрите по этой ссылке fit_generator ищите метод fit_generator.

def data_generater(batch_size):
print("reading data")
training_file = 'data_location', 'r')

# assuming data is in json format so feels free to change accordingly

training_set = json.loads(training_file.read())
training_file.close()

batch_i = 0  # Counter inside the current batch vector
batch_x = []  # The current batch's x data
batch_y = []  # The current batch's y data

while True:

    for obj in training_set:
        batch_x.append(your input sequences one by one)
        if obj['val'] == True:
            batch_y.append([1])
        elif obj['val'] == False:
            batch_y.append([0])
        batch_i += 1

        if batch_i == batch_size:
            # Ready to yield the batch
            # pad input to max length in the batch
            batch_x = pad_txt_data(batch_x)
            yield batch_x, np.array(batch_y)
            batch_x = []
            batch_y = []
            batch_i = 0

def pad_txt_data(arr):
# expecting arr to be in the shape of (10, m, 6)
paded_arr = []
prefered_len = len(max(arr, key=len))

# Now pad all your sequences to preferred length in the batch(arr)

return np.array(paded_arr)

и в модели

model = keras.Sequential()
model.add(keras.layers.Masking(mask_value=0., input_shape=(None,6)))
model.add(keras.layers.LSTM(32))
model.add(keras.layers.Dense(1, activation="softmax"))
model.compile(optimizer="Adam", loss='categorical_crossentropy', metrics=['categorical_accuracy'])
model.fit_generator(data_generater(10), steps_per_epoch=5, epochs=10)

Batch_size, steps_per_epoch, эпоха может быть разной. Вообще

steps_per_epoch = (number of sequences/batch_size)

Примечание. Форма, в которой читается ваше описание, является задачей двоичной классификации, а не проблемой последовательности или последовательности. Хорошим примером последовательности для последовательности является языковой перевод. Просто погуглите вокруг, и вы поймете, что я имею в виду.

И если вы действительно хотите увидеть разницу во времени обучения, я предлагаю использовать графический процессор, если он доступен, и CuDNNLSTM .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...