Временная сверточная нейросеть (TCN)

Автор:

Нейросеть для работы с последовательными данными, которая использует сверточные слои вместо рекуррентных, но при этом умеет учитывать долгосрочные зависимости во времени.

Временная сверточная нейросеть (Temporal Convolutional Network, TCN) — это нейросеть для работы с последовательными данными, которая использует сверточные слои вместо рекуррентных, но при этом умеет учитывать долгосрочные зависимости во времени. TCN — это «сверточная версия LSTM», которая часто быстрее и стабильнее.

Почему вообще понадобились TCN

Долгое время стандартом для последовательностей были:

  • RNN
  • LSTM
  • GRU

Но у них есть проблемы:

  • последовательная обработка (медленно на GPU),
  • сложное обучение,
  • нестабильные градиенты,
  • трудности с очень длинными последовательностями.

TCN предложили другой подход: вместо рекурсии — одномерныесвертки по времени.

Ключевые идеи TCN

Каузальные свёртки (Causal Convolutions): модель не «заглядывает в будущее». Значение в момент времени t зависит только от:

  • текущего шага,
  • предыдущих шагов.

Это важно для:

  • прогнозирования,
  • временных рядов,
  • онлайн-обработки.

Dilated Convolutions (расширенные свёртки): чтобы учитывать длинную историю, используются свёртки с пропусками.

Пример:

  • dilation=1 → обычная свёртка
  • dilation=2 → через один шаг
  • dilation=4 → через три шага

Это позволяет быстро увеличивать «поле зрения» без резкого роста параметров.

Residual connections: как и в ResNet, используются Skip Connections. Это стабилизирует обучение и позволяет строить глубокие TCN.

Почему TCN часто лучше LSTM

  • полностью параллельны (быстрее на GPU)
  • стабильнее в обучении
  • проще масштабируются
  • хорошо работают на длинных последовательностях

В ряде задач временных рядов TCN показывают результаты не хуже или лучше LSTM.

Минимальный пример TCN на PyTorch

Импортируем инструменты:

import torch
import torch.nn as nn
import torch.nn.functional as F

Temporal Block

class TemporalBlock(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, dilation):
        super().__init__()

        padding = (kernel_size - 1) * dilation

        self.conv1 = nn.Conv1d(
            in_channels,
            out_channels,
            kernel_size,
            padding=padding,
            dilation=dilation
        )

        self.relu = nn.ReLU()

        self.conv2 = nn.Conv1d(
            out_channels,
            out_channels,
            kernel_size,
            padding=padding,
            dilation=dilation
        )

        self.downsample = nn.Conv1d(in_channels, out_channels, 1) \
            if in_channels != out_channels else None

    def forward(self, x):
        out = self.conv1(x)
        out = out[:, :, :-self.conv1.padding[0]]  # обрезаем лишнее (causal)
        out = self.relu(out)

        out = self.conv2(out)
        out = out[:, :, :-self.conv2.padding[0]]

        res = x if self.downsample is None else self.downsample(x)
        return self.relu(out + res)

Полная модель TCN:

class TCN(nn.Module):
    def __init__(self, input_size, num_channels, kernel_size=3):
        super().__init__()

        layers = []
        for i in range(len(num_channels)):
            dilation = 2  i
            in_channels = input_size if i == 0 else num_channels[i-1]
            out_channels = num_channels[i]

            layers.append(
                TemporalBlock(
                    in_channels,
                    out_channels,
                    kernel_size,
                    dilation
                )
            )

        self.network = nn.Sequential(*layers)
        self.fc = nn.Linear(num_channels[-1], 1)

    def forward(self, x):
        # x: (batch, channels, time)
        y = self.network(x)
        y = y[:, :, -1]  # последний временной шаг
        return self.fc(y)

Проверим работу модели:

# 32 объекта, 5 признаков, 50 временных шагов
x = torch.randn(32, 5, 50)

model = TCN(
    input_size=5,
    num_channels=[16, 32, 64]
)

y = model(x)
print(y.shape)
# torch.Size([32, 1])

Где применяют TCN

  • прогнозирование временных рядов
  • обработка сигналов
  • финансовые данные
  • IoT и сенсоры
  • анализ логов
  • биомеханика движений

Для задач анализа динамики (например, спортивных движений) TCN может быть хорошей альтернативой LSTM.

Ограничения

  • сложнее интерпретировать, чем линейные модели
  • требует аккуратного выбора dilation
  • при очень длинных рядах глубина может расти