Вопрос или проблема
У меня есть длинный список событий (400 уникальных событий, последовательность длиной ~10 млн). Я хочу обучить RNN предсказывать следующее событие.
Шаги предобработки следующие:
(1) преобразование в OneHotEncoding с использованием pandas:
vector = pd.get_dummies(sr)
Эта часть занимает около 15 секунд.
(2) Используя скользящее окно размером 10, я создаю образцы и метки следующим образом;
я перебираю вектор из (1), беру Xt как метку и Xt:t-10 как данные.
Код:
X = np.zeros((len(samples), window_size, voc_len), dtype=np.bool)
y = np.zeros((len(samples), voc_len), dtype=np.bool)
if IN_COLAB:
loading_bar = tqdm.tqdm_notebook(enumerate(samples),desc="Build dataset",total=len(samples))
else:
loading_bar = tqdm.tqdm(enumerate(samples),desc="Build dataset",total=len(samples))
for numpy_index, pandas_idx in loading_bar:
x_idx = (pandas_idx, pandas_idx + window_size)
y_idx = pandas_idx + window_size
Xt = vector.iloc[x_idx[0]:x_idx[1]]
yt = vector.iloc[y_idx]
X[numpy_index] = Xt
y[numpy_index] = yt
display(yt)
Проблема в том, что вторая часть ОЧЕНЬ медленная (25 минут).
Есть ли лучший способ сделать это?
встроенная функция какого-то рода?
Спасибо
Есть несколько шаблонов проектирования, которые способствуют медленному коду:
-
Pandas не предназначен для крупномасштабной, быстрой обработки данных.
-
Ваш код использует цикл for, который может быть медленным.
-
Вы проявляете скользящее окно до того, как программа в нём нуждается. Возможно, лучше создать представление данных и проявить данные в памяти только тогда, когда они нужны для обучения.
Лучше использовать NumPy с numpy.lib.stride_tricks.sliding_window_view
Ответ или решение
Предварительная обработка временных рядов для обучения рекуррентных нейронных сетей (RNN) может быть довольно сложной задачей, особенно когда речь идет о большом объеме данных. Давайте рассмотрим, как можно оптимизировать обработку временной последовательности из 400 уникальных событий и длиной порядка 10 миллионов, чтобы ускорить процесс и улучшить качество данных для обучения.
Проблемы с текущей реализацией
-
Использование Pandas для больших объемов данных: Pandas отлично подходит для работы с данными, но при больших масштабах, в миллионы записей, он может стать неэффективным. Это связано с тем, что Pandas не оптимизирован для высокопроизводительных вычислений с использованием векторизации.
-
Итерация с использованием цикла for: Циклы for в Python медленны в сравнении с векторизованными операциями NumPy. Это значительное узкое место в вашем коде, поскольку вы обрабатываете множество событий последовательно.
-
Предварительное создание всех оконных выборок: Создание всех оконных выборок перед фактическим использованием в процессе обучения может быть ресурсоемким как по времени, так и по памяти. Это приводит к избыточной загрузке.
Оптимизация процесса
Чтобы улучшить производительность предварительной обработки, можно применить следующие стратегии:
Использование NumPy и Скользящих Окон
NumPy предоставляет мощный инструмент numpy.lib.stride_tricks.sliding_window_view
, который можно использовать для создания представления данных, которое позволяет работать с событийными последовательностями более эффективно. Вместо создания копий данных, можно создать "вид" данных, который позволяет обращаться к ним по частям — так, как требуется для обучения.
import numpy as np
# Преобразование событий в вектор одномерного массива
vector = pd.get_dummies(sr).values
# Получение скользящих окон
window_data = np.lib.stride_tricks.sliding_window_view(vector, window_shape=(window_size + 1,), axis=0)
# Разделение на выборки и метки
X = window_data[:, :-1, :]
y = window_data[:, -1, :]
Этот подход значительно уменьшает затрату времени за счет избегания создания лишних копий данных и позволяет работать с большими объемами более эффективно.
Использование Библиотек для Высокопроизводительных Вычислений
Подумайте об использовании библиотек, таких как TensorFlow Dataset API, которые предлагают встроенные инструменты для загрузки и предварительной обработки данных. Эти инструменты разработаны для того, чтобы максимально использовать параллелизм и минимизировать загрузку памяти.
import tensorflow as tf
# Пример кодового фрагмента для создания TensorFlow Dataset
def generator():
for i in range(len(vector) - window_size):
X_sample = vector[i:i + window_size]
y_label = vector[i + window_size]
yield X_sample, y_label
dataset = tf.data.Dataset.from_generator(generator, output_types=(tf.float32, tf.float32))
Этот подход обеспечивает обработку данных на лету, что снижает время ожидания и улучшает общую производительность системы.
Заключение
Улучшение производительности предварительной обработки данных для RNN требует пересмотра используемых технологий и методологий обработки данных. Используйте мощные возможности векторизации NumPy и модульных данных TensorFlow, чтобы минимизировать временные и пространственные издержки. Эти изменения сделают вашу модель более эффективной и позволят сосредоточиться на задачах более высокого уровня при работе с временными рядами.
Работая над оптимизацией обработки данных, вы улучшаете не только эффективность обучения моделей, но и создаете более стабильную систему, способную справляться с большими объемами данных в будущем.