«Эпохи» Трансформеров
Обработка всей эпохи Numerai с помощью Transformers.
Просто дайте мне код ️:
GPU -> Запустить все блокноты, которые генерируют файл отправки. Выполняется в течение 15 мин.
Если вы новичок в турнирах Numer.ai, следующие сообщения могут быть полезны для понимания контекста этого сообщения.
- https://docs.numer.ai/tournament/learn
- Простой путеводитель по «Самому сложному турниру на планете»
- Поговорим о сигналах
Данные (Эры) ⌗
Предоставленный набор данных ( v4.1: Sunshine ) содержит запутанные данные фондового рынка за прошлые десятилетия, разделенные на группы под названием «Эра» (целое число). Эры представляют собой относительное чувство времени, то есть эра 1 произошла до эры 2 и так далее до примерно 1050 эр. Они разделены на обучающие и проверочные наборы.
Эпоха как последовательность ⠿
Большинство моделей рассматривают каждую строку как образец без какого-либо контекста эпохи. Такие подходы, как Era Boosting, тренируют дополнительные деревья на эпохах, с которыми борется текущий ансамбль. Тем не менее, это все еще не рассматривает всю эпоху для предсказания. Поскольку основная цель специалистов по обработке и анализу данных — ранжировать выборки в данную эпоху, имеет смысл иметь возможность просматривать не только признаки, но и все выборки за эту эпоху. Это заставляет нас задаться вопросом, что мы можем сделать, если мы можем посмотреть на все образцы в эпоху и сделать вывод из этого! Возможности: кластеризация эр, создание синтетической эры за один проход и т. д. Вопрос в том, может ли он дать некоторое представление о движении группы акций, поскольку он может видеть все (все) сразу?
Я уже некоторое время пытаюсь работать над этими идеями. Первоначальные эксперименты с LSTM не увенчались успехом (возможно, тогда я не смог правильно его реализовать). Мои первоначальные испытания с Transformers обрабатывали каждую строку как последовательность, используя встраивание 5 уникальных входных значений {0, 1, 2, 3, 4}. Тем не менее, он должен иметь возможность обрабатывать всю эпоху сразу, просто транспонируя.
(Эра)Трансформер спешит на помощь
Вместо того, чтобы рассматривать каждую строку как образец, эра дополняется до фиксированного значения MAX_LENGTH и, таким образом, обрабатывается как последовательность. Выбранные функции встраиваются в модель вместе с маской в дополненных местах, как показано на рисунке ниже.
def pad_sequence(inputs, padding_value=-1, max_len=None):
if max_len is None:
max_len = max([input.shape[0] for input in inputs])
padded_inputs = []
masks = []
for input in inputs:
pad_len = max_len - input.shape[0]
padded_input = F.pad(input, (0, 0, 0, pad_len), value=padding_value)
mask = torch.ones((input.shape[0], 1), dtype=torch.float)
masks.append(
torch.cat((mask, torch.zeros((pad_len, 1), dtype=torch.float)), dim=0)
)
padded_inputs.append(padded_input)
return torch.stack(padded_inputs), torch.stack(masks)
def convert_to_torch(era, data):
inputs = torch.from_numpy(
data[feature_names].values.astype(np.int8))
labels = torch.from_numpy(
data[target_names].values.astype(np.float32))
padded_inputs, masks_inputs = pad_sequence(
[inputs], padding_value=PADDING_VALUE, max_len=MAX_LEN)
padded_labels, masks_labels = pad_sequence(
[labels], padding_value=PADDING_VALUE, max_len=MAX_LEN)
return {
era: (
padded_inputs,
padded_labels,
masks_inputs
)
}
def get_era2data(df):
res = Parallel(n_jobs=-1, prefer="threads")(
delayed(convert_to_torch)(era, data)
for era, data in tqdm(df.groupby("era_int")))
era2data = {}
for r in tqdm(res):
era2data.update(r)
return era2data
era2data_train = get_era2data(train)
era2data_validation = get_era2data(validation)
class TransformerEncoder(nn.Module):
def __init__(
self,
input_dim,
d_model,
output_dim,
num_heads,
num_layers,
dropout_prob=0.15,
max_len=5000,
):
super(TransformerEncoder, self).__init__()
self.input_dim = input_dim
self.output_dim = output_dim
self.num_heads = num_heads
self.num_layers = num_layers
self.dropout_prob = dropout_prob
self.d_model = d_model
self.positional_encoding = PositionalEncoding(d_model, max_len)
self.attention = MultiHeadLinearAttention(d_model, num_heads)
self.fc = nn.Sequential(
nn.Linear(d_model, d_model),
)
self.layers = nn.ModuleList(
[
nn.Sequential(FeedForwardLayer(d_model=d_model))
for _ in range(num_layers)
]
)
self.mapper = nn.Sequential(
nn.Linear(input_dim, d_model), nn.Linear(d_model, d_model)
)
def forward(self, inputs, mask=None):
x = self.mapper(inputs)
pe = self.positional_encoding(x)
x = x + pe # works without PE as well
for layer in range(self.num_layers):
attention_weights = self.attention(x, mask)
x = x + attention_weights
x = F.layer_norm(x, x.shape[1:])
x = F.dropout(x, p=self.dropout_prob)
op = self.layers[layer](x)
x = x + op
x = F.layer_norm(x, x.shape[1:])
x = F.dropout(x, p=self.dropout_prob)
outputs = self.fc(x)
return outputs
Ванильное внимание было слишком тяжелым для графического процессора моего ноутбука, поэтому я попытался использовать что-то вроде Linear Attention , так как это уменьшит нагрузку умножения матриц сначала до D_MODEL , а затем до MAX_LEN . Стандартная среда выполнения Colab в предоставленном ноутбуке использует ванильный механизм внимания к предоставленному небольшому подмножеству функций, поскольку у него больше памяти графического процессора. Ноутбук доступен в качестве замены для многоголового блока внимания. Используйте то, что работает для вас.
Полученные результаты
Эксперименты в предоставленном Colab используют «небольшой» подмножество функций из-за ограничений памяти. Однако он использует ванильный механизм внимания. Ниже представлена небольшая модель, обученная на небольшом наборе функций для 10 итераций с низкой скоростью обучения для оптимизации MSE и корреляции Пирсона.
Функция потерь, обеспечивающая ортогональные вложения в выходные данные кодировщика, имела бы гораздо больше смысла для кластеризации. Текущая реализация является скорее ранним экспериментом и будет более точной для идеальной реализации. Хотя вроде работает.
Тренировочная производительность
Проверка производительности
Относительно метамодели
Кластеризация
Что дальше?
- Запустите блокнот Colab (GPU->Выполнить все). Создает файл отправки
- Расширьте набор функций (маленький -> средний -> полный набор)
- Играйте с механизмами внимания.
- Функции потерь для улучшения встраивания
- У нас есть полное представление о данных в Сигналах; Там он будет более применим.
- Создавайте синтетические эры, используя процесс диффузии.
- Самостоятельное обучение
- https://github.com/lucidrains/linear-attention-transformer
- https://numer.ai/data/v4.1
- Снова блокнот Colab
- ChatGPT + Github Copilot

![В любом случае, что такое связанный список? [Часть 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































