Теперь Кью работает в режиме чтения

Мы сохранили весь контент, но добавить что-то новое уже нельзя

Какую архитектуру выбрать, если входные данные — последовательность последовательностей?

То, что мне приходит в голову:
  1. сделать padding до определенной длины на каждую строчку (заполнить скажем -1, потому что все значения >0);
  2. склеить все последовательности через -1, и уже на результат сделать padding;
  3. обучать с величиной батча = 1, последовательность из каждой строки пропускать через ту же рекуррентную сеть, результаты выхода склеить и подавать в другую рекуррентную сеть.
Может, есть идеи получше?
Входные данные похожи на это - 5 строчек, каждая может состоять из практически любого числа чисел (от 0 до 100000)
1.050
0.275
3.295 0.080
1.910
0.001
~~~~SEQ OF LEN 5 DELIM~~~~
0.034
0.001 0.005 0.167 3.940
0.002 0.014
0.490 3.385 0.000 7.196 0.007
<ПУСТАЯ ПОСЛЕДОВАТЕЛЬНОСТЬ> (Я.Кью удаляет пустые строки)
~~~~SEQ OF LEN 5 DELIM~~~~
0.506 0.323 0.062 0.034 0.429
0.050 0.176
1.376 0.220 0.007 0.369 0.076
1.551 0.000 0.453 0.032 1.156
3.607 0.153 1.607 0.002 0.005
~~~~SEQ OF LEN 5 DELIM~~~~
Целевая переменная - одно число (физическая величина, не номер класса)
10.0
4.0
11.0
ПрограммированиеData science+3
Эмиль Пилецкий
  ·   · 1,4 K
Лучший
Экс-преподаватель msu.ai, специалист образовательн...  · 12 дек 2021
Здравствуйте, Эмиль.
К сожалению, предобработка данных и создание модели в большей части случаев требуют применения domain knowledge, однако Вы привели не достаточно информации, чтобы давать некие осмысленные советы, подходящие конкретно для Вашей задачи. В связи с этим, поделюсь своими рассуждениями - может, они будут полезны Вам.
Первый Ваш вариант может работать плохо по той причине, что указанный Вами разброс длин строк слишком велик - от 0 до 100000. Далее возникает проблема выбора оптимального размера итоговой последовательности. Если наивно дополнять до максимальной длины, то есть шанс, что большая часть полученных строк будет состоять из placeholder'ов, что не есть хорошо. Если ставить меньший размер, то вероятно придётся обрезать некоторые строки - возникает вопрос, как это оптимально сделать, не потеряв ключевую информацию из данных.
Второй вариант кажется куда более интересным, однако я бы предложил Вам использовать различные значения для разделителей последовательностей и для padding значений.
Третий вариант может привести к крайней нестабильности обучения, если Вы будете делать шаг градиентного бустинга после каждого сэмпла. В связи с этим, рекомендую Вам использовать оптимизатор по градиенту, накопленному за несколько сэмплов. В целом, этот вариант кажется мне наиболее хорошим.
Теперь давайте попробую в целом поанализировать задачу. Если что - направьте мои мысли комментарием к данному ответу.
Существуют последовательность, состоящая из пяти последовательностей, имеющих не фиксированную длину (от 0 до 100000). Если логика данных в каждой из пяти подпоследовательностей одинакова, то стоит создать один общий модуль для получения информации из подпоследовательностей, в ином случае - пять модулей, по одному для последовательности (если поведение данных от подпоследовательности к подпоследовательности меняется аналогичным образом во всех последовательностях).
Теперь давайте попробуем рассмотреть данный модуль. В целом, для обработки последовательностей есть смысл использовать либо рекуррентные нейронные сети, либо трансформероподобные (построенные на внимании) модели. Свёрточные не рассматриваю, поскольку они так же работают с фиксированным "окном", как и модели с вниманием, но значительно уступают последним в качестве работы:
  • рекуррентные модели - в принципе, неплохой вариант, однако они как правило не способны улавливать закономерности в совсем уж длинных зависимостях (поскольку кодирование происходит в вектор фиксированной длины); в принципе, можно попробовать использовать огромный размер скрытого состояния, но едва ли это сильно поможет.
  • модели, использующие внимание - вариант получше, однако они как правило требуют большое количество сэмплов для обучения + очень требовательны к памяти, да и работают "в окне", потому их стоит использовать только если у Вас большое количество сэмплов (иначе модуль просто не обучится и выгоднее использовать рекуррентную модель).
Оба типа моделей в целом довольно плохо работают с крайне длинными последовательностями (до 100'000 записей), потому возникает идея о создании подмодулей, которые будут вытягивать информацию из подпоследовательностей подпоследовательностей (то есть, подпоследовательностей каждой из пяти последовательностей, составляющих сэмпл). Если в Ваших данных можно допустить некое рациональное разделение подпоследовательностей на последовательности меньшего размера (к примеру, день/час сбора данных), то стоит углубить иерархию и создать подмодули (опять же, рекуррентные либо основанные на внимании) для извлечения информации из подподпоследовательностей.
В любом случае, как бы ни была глубока иерархия модулей, модуль должен обрабатывать последовательную информацию, полученную с предыдущего уровня. В вопросе о том, какую модель использовать для обобщения информации, рекомендую ориентироваться на количество получаемых единиц данных - если полученные последовательности длинны (1000 элементов, допустим), то лучше использовать рекуррентные модели (иначе высока вероятность, что Вы не сможете обучить модель из-за большого количества используемой памяти). Если же окажется, что модели основанные на внимании не переполняют доступную Вам видеопамять, то стоит посмотреть на качество обучения - есть шанс, что модель недообучится из-за малого количества доступных сэмплов - в этом случае, опять же, придётся перейти на рекуррентные модели.
В целом, предлагаю Вам использовать иерархию модулей, по описанным выше шаблонам выбирая разделение данных на меньшие фрагменты и тип используемых модулей на каждом уровне иерархии.
Даже не рассчитывал на столь подробный ответ. О некоторых вещах не подумал. Спасибо. Так понял, что вы за вариант... Читать дальше