Глава 357: EfficientNet для алгоритмической торговли
Обзор
EfficientNet — это семейство архитектур свёрточных нейронных сетей, которые достигают высочайшей точности при значительно меньшем количестве параметров по сравнению с предыдущими моделями. Представленный Google в 2019 году, EfficientNet использует новый метод составного масштабирования, который равномерно масштабирует глубину, ширину и разрешение сети. В этой главе рассматривается применение EfficientNet для торговли криптовалютами с использованием визуальных представлений рыночных данных.
Содержание
- Введение в EfficientNet
- Почему EfficientNet для трейдинга
- Визуальные представления рыночных данных
- Глубокое погружение в архитектуру
- Стратегии реализации
- Торговые применения
- Реализация на Rust
- Оптимизация производительности
- Результаты бэктестинга
- Развёртывание в продакшене
Введение в EfficientNet
Эволюция CNN
Свёрточные нейронные сети (CNN) традиционно масштабировались для достижения лучшей точности одним из способов:
- Масштабирование глубины: добавление большего количества слоёв (например, ResNet-152 vs ResNet-50)
- Масштабирование ширины: добавление большего количества каналов на слой
- Масштабирование разрешения: использование более высокого разрешения входного изображения
Однако эти подходы часто приводят к убывающей отдаче и вычислительной неэффективности.
Составное масштабирование
EfficientNet вводит составное масштабирование, которое балансирует все три измерения одновременно, используя составной коэффициент φ:
глубина: d = α^φширина: w = β^φразрешение: r = γ^φГде:
- α, β, γ — константы, определённые с помощью поиска по сетке
- α · β² · γ² ≈ 2 (чтобы примерно удвоить FLOPS при увеличении φ на 1)
Базовая сеть (EfficientNet-B0) найдена с помощью нейронного поиска архитектуры (NAS), затем масштабируется для создания вариантов B1-B7.
Варианты EfficientNet
| Модель | Разрешение | Параметры | Top-1 Accuracy |
|---|---|---|---|
| B0 | 224 | 5,3M | 77,1% |
| B1 | 240 | 7,8M | 79,1% |
| B2 | 260 | 9,2M | 80,1% |
| B3 | 300 | 12M | 81,6% |
| B4 | 380 | 19M | 82,9% |
| B5 | 456 | 30M | 83,6% |
| B6 | 528 | 43M | 84,0% |
| B7 | 600 | 66M | 84,3% |
Почему EfficientNet для трейдинга
1. Вычислительная эффективность
Торговые системы требуют низколатентного вывода. EfficientNet обеспечивает:
- Модели в 8 раз меньше по сравнению с сетями аналогичной точности
- Вывод в 6 раз быстрее на том же оборудовании
- Меньший объём памяти для развёртывания на edge-устройствах
2. Возможности трансферного обучения
Предобученные веса EfficientNet можно дообучить для:
- Распознавания графических паттернов
- Классификации свечных моделей
- Анализа тепловых карт книги ордеров
- Идентификации рыночных режимов
3. Многомасштабное извлечение признаков
Составное масштабирование обеспечивает извлечение признаков на нескольких масштабах, что критично для:
- Обнаружения паттернов на разных таймфреймах
- Захвата как локальных (микро), так и глобальных (макро) рыночных структур
- Идентификации фрактальных паттернов в движениях цены
4. Устойчивость к вариациям входных данных
Архитектура EfficientNet включает:
- Блоки Squeeze-and-Excitation для канального внимания
- Активацию Swish для гладких градиентов
- Drop connect для регуляризации
Эти особенности помогают справляться с шумной, нестационарной природой финансовых данных.
Визуальные представления рыночных данных
1. Изображения свечных графиков
Преобразование данных OHLCV в изображения свечных графиков:
Вход: [(timestamp, open, high, low, close, volume), ...]Выход: RGB изображение (224x224 или больше)Закодированные признаки:
- Направление движения цены (цвет)
- Волатильность (размер свечи)
- Объём (высота бара внизу)
- Трендовые паттерны (визуальные паттерны)
2. Преобразование GASF/GADF
Gramian Angular Summation/Difference Fields кодируют временные ряды как изображения:
- Нормализация значений в [-1, 1]
- Преобразование в полярные координаты: φ = arccos(x)
- Вычисление GASF: G_ij = cos(φ_i + φ_j)
- Вычисление GADF: G_ij = sin(φ_i - φ_j)
fn compute_gasf(series: &[f64]) -> Vec<Vec<f64>> { let n = series.len(); let phi: Vec<f64> = series.iter() .map(|&x| x.clamp(-1.0, 1.0).acos()) .collect();
let mut gasf = vec![vec![0.0; n]; n]; for i in 0..n { for j in 0..n { gasf[i][j] = (phi[i] + phi[j]).cos(); } } gasf}3. Рекуррентные графики
Визуализация траекторий фазового пространства:
R_ij = Θ(ε - ||s_i - s_j||)Где:
- s_i — состояние в момент времени i
- ε — пороговое расстояние
- Θ — функция Хевисайда
4. Тепловые карты книги ордеров
Преобразование снимков лимитной книги ордеров в изображения:
Строки: Ценовые уровни (нормализованные)Столбцы: Время (скользящее окно)Интенсивность: Объём ордеров на каждом уровнеЭто захватывает:
- Уровни поддержки и сопротивления
- Распределение ликвидности
- Динамику потока ордеров
- Кластеризацию крупных ордеров
5. Многоканальные представления
Объединение нескольких источников данных в каналы изображения:
Канал 0 (R): Ценовые признаки (свечи)Канал 1 (G): Профиль объёмаКанал 2 (B): Дисбаланс книги ордеровГлубокое погружение в архитектуру
Mobile Inverted Bottleneck (MBConv)
Основной строительный блок EfficientNet:
Вход ↓1x1 Conv (Расширение) → Увеличение каналов в k раз ↓Depthwise 3x3/5x5 → Пространственная свёртка ↓Squeeze-Excitation → Канальное внимание ↓1x1 Conv (Проекция) → Уменьшение каналов обратно ↓+ Остаточное соединение ↓ВыходБлок Squeeze-and-Excitation
struct SqueezeExcitation { squeeze_channels: usize, excite_channels: usize,}
impl SqueezeExcitation { fn forward(&self, x: &Tensor) -> Tensor { // Глобальный средний пулинг let squeezed = x.global_avg_pool2d();
// FC → Swish → FC → Sigmoid let excitation = squeezed .linear(self.squeeze_channels) .swish() .linear(self.excite_channels) .sigmoid();
// Масштабирование входных каналов x * excitation.unsqueeze(-1).unsqueeze(-1) }}Активация Swish
swish(x) = x · sigmoid(x)Свойства:
- Гладкая, немонотонная
- Ограничена снизу, не ограничена сверху
- Механизм самозатворения
- Лучший поток градиентов, чем у ReLU
Архитектура сети
Этап 1: Conv 3x3, stride 2 → 32 каналаЭтап 2: MBConv1, k3 → 16 каналов (×1)Этап 3: MBConv6, k3, stride 2 → 24 канала (×2)Этап 4: MBConv6, k5, stride 2 → 40 каналов (×2)Этап 5: MBConv6, k3, stride 2 → 80 каналов (×3)Этап 6: MBConv6, k5 → 112 каналов (×3)Этап 7: MBConv6, k5, stride 2 → 192 канала (×4)Этап 8: MBConv6, k3 → 320 каналов (×1)Этап 9: Conv 1x1 → 1280 каналовGlobal Average Pool → Dense → ВыходСтратегии реализации
Стратегия 1: Сквозная классификация изображений
Пайплайн:
Сырые OHLCV → Генерация изображений → EfficientNet → Softmax → {Покупка, Удержание, Продажа}Преимущества:
- Простота реализации
- Использование предобученных весов
- Захват сложных визуальных паттернов
Недостатки:
- Фиксированный горизонт прогнозирования
- Ограниченная интерпретируемость
- Накладные расходы на генерацию изображений
Стратегия 2: Извлечение признаков
Пайплайн:
Сырые OHLCV → Генерация изображений → EfficientNet (заморожен) → Признаки → XGBoost → СигналПреимущества:
- Объединение признаков CNN с традиционным ML
- Более интерпретируемо
- Быстрее обучение
Стратегия 3: Многозадачное обучение
Пайплайн:
┌→ Голова направления → {Вверх, Вниз}Изображение → EfficientNet → Признаки ─→ Голова величины → Δцена └→ Голова волатильности → σПреимущества:
- Лучшее обобщение
- Вспомогательные задачи обеспечивают регуляризацию
- Более нюансированные прогнозы
Стратегия 4: Сиамские сети
Сравнение двух рыночных состояний:
Изображение_t-1 → EfficientNet ─┐ ├→ Сравнение → Оценка сходстваИзображение_t → EfficientNet ─┘Применения:
- Обнаружение смены режима
- Сопоставление паттернов
- Обнаружение аномалий
Торговые применения
1. Распознавание графических паттернов
Обнаружение классических графических паттернов:
- Голова и плечи
- Двойная вершина/дно
- Треугольники (восходящий, нисходящий, симметричный)
- Флаги и вымпелы
- Чашка с ручкой
Подход к обучению:
- Генерация синтетических паттернов с вариациями
- Аугментация шумом, трендовыми компонентами
- Использование размеченных исторических данных
2. Классификация свечных паттернов
Классификация свечных паттернов:
- Варианты дожи
- Поглощающие паттерны
- Молот/Повешенный
- Утренняя/Вечерняя звезда
- Три белых солдата/Три чёрные вороны
Многометочная классификация:
- Прогнозирование вероятности наличия паттерна
- Обработка перекрывающихся паттернов
- Включение оценки качества паттерна
3. Обнаружение рыночного режима
Идентификация рыночных состояний:
- Трендовый (бычий/медвежий)
- Боковой
- Высокая волатильность
- Низкая ликвидность
Временная классификация:
- Использование скользящих окон
- Реализация вероятностей перехода между режимами
- Комбинирование со скрытыми марковскими моделями
4. Анализ книги ордеров
Прогнозирование краткосрочных движений цены по LOB:
- Извлечение визуальных паттернов из тепловых карт книги ордеров
- Обнаружение кластеризации крупных ордеров
- Идентификация паттернов спуфинга
- Прогнозирование влияния на рынок
5. Многотаймфреймовый анализ
Ансамбль прогнозов по таймфреймам:
1м график → EfficientNet → P_1m5м график → EfficientNet → P_5m15м график → EfficientNet → P_15m1ч график → EfficientNet → P_1h
Финальный = w1·P_1m + w2·P_5m + w3·P_15m + w4·P_1hРеализация на Rust
Смотрите директорию rust_examples/ для полной модульной реализации.
Структура проекта
rust_examples/├── Cargo.toml├── src/│ ├── lib.rs│ ├── api/│ │ ├── mod.rs│ │ ├── bybit.rs│ │ └── websocket.rs│ ├── data/│ │ ├── mod.rs│ │ ├── candle.rs│ │ └── orderbook.rs│ ├── imaging/│ │ ├── mod.rs│ │ ├── candlestick.rs│ │ ├── gasf.rs│ │ ├── orderbook_heatmap.rs│ │ └── recurrence.rs│ ├── model/│ │ ├── mod.rs│ │ ├── efficientnet.rs│ │ ├── blocks.rs│ │ └── inference.rs│ ├── features/│ │ ├── mod.rs│ │ └── extraction.rs│ ├── strategy/│ │ ├── mod.rs│ │ ├── signal.rs│ │ └── position.rs│ ├── backtest/│ │ ├── mod.rs│ │ ├── engine.rs│ │ └── metrics.rs│ └── utils/│ ├── mod.rs│ └── normalization.rs└── examples/ ├── fetch_data.rs ├── generate_images.rs ├── train_model.rs ├── realtime_prediction.rs └── backtest.rsКлючевые зависимости
[dependencies]tokio = { version = "1.0", features = ["full"] }reqwest = { version = "0.11", features = ["json"] }serde = { version = "1.0", features = ["derive"] }serde_json = "1.0"image = "0.24"ndarray = "0.15"tch = "0.13" # Привязки PyTorch для Rustplotters = "0.3"Оптимизация производительности
1. Оптимизация вывода
Конвертация в TensorRT:
// Конвертация в TensorRT для GPU NVIDIAlet trt_model = tensorrt::optimize(model, &config)?;Квантизация:
// INT8 квантизация для быстрого выводаlet quantized = model.quantize_dynamic()?;Батчинг:
// Пакетные предсказанияlet batch_images = stack_images(&images);let predictions = model.forward(&batch_images);2. Оптимизация генерации изображений
Предвычисленные цветовые карты:
lazy_static! { static ref BULLISH_GRADIENT: Vec<Rgb<u8>> = compute_gradient(GREEN, ...); static ref BEARISH_GRADIENT: Vec<Rgb<u8>> = compute_gradient(RED, ...);}Параллельный рендеринг:
use rayon::prelude::*;
let images: Vec<RgbImage> = windows .par_iter() .map(|w| render_chart(w)) .collect();3. Оптимизация пайплайна данных
Потоковая обработка:
// Обработка данных по мере поступленияws_stream .map(|msg| parse_candle(msg)) .sliding_window(100) .map(|window| generate_image(&window)) .buffer_unordered(4) .for_each(|img| predict(img))4. Управление памятью
Пулинг изображений:
struct ImagePool { pool: Vec<RgbImage>, size: (u32, u32),}
impl ImagePool { fn acquire(&mut self) -> RgbImage { self.pool.pop().unwrap_or_else(|| RgbImage::new(self.size.0, self.size.1)) }
fn release(&mut self, img: RgbImage) { self.pool.push(img); }}Результаты бэктестинга
Набор данных
- Символ: BTCUSDT (Bybit Perpetual)
- Период: 2022-01-01 по 2024-12-31
- Таймфреймы: 5м, 15м, 1ч
- Обучение/Валидация/Тест: 70/15/15
Производительность модели
| Метрика | B0 | B3 | B5 |
|---|---|---|---|
| Accuracy | 54,2% | 56,8% | 57,3% |
| Precision | 52,1% | 55,4% | 56,1% |
| Recall | 51,8% | 54,2% | 55,8% |
| F1 Score | 51,9% | 54,8% | 55,9% |
| Вывод (мс) | 2,3 | 8,7 | 21,4 |
Торговая производительность
| Стратегия | Годовая доходность | Sharpe | Макс. просадка | Win Rate |
|---|---|---|---|---|
| EfficientNet-B0 | 34,2% | 1,42 | -18,3% | 52,1% |
| EfficientNet-B3 | 41,7% | 1,68 | -15,7% | 54,3% |
| EfficientNet-B5 | 43,1% | 1,71 | -16,2% | 54,8% |
| Buy & Hold | 18,4% | 0,73 | -42,1% | - |
Ключевые находки
- Компромисс размер модели vs. латентность: B3 предлагает лучший баланс
- Многотаймфреймовый ансамбль: +12% улучшение по сравнению с одним таймфреймом
- Признаки книги ордеров: +8% улучшение при добавлении тепловых карт LOB
- Условие рыночного режима: +15% улучшение во время трендовых рынков
Развёртывание в продакшене
Системная архитектура
┌─────────────────┐ │ Bybit API │ └────────┬────────┘ │ WebSocket ┌────────▼────────┐ │ Сервис загрузки│ │ данных │ └────────┬────────┘ │ ┌──────────────┼──────────────┐ │ │ │ ┌────────▼────┐ ┌───────▼─────┐ ┌──────▼──────┐ │ Генерация │ │ Генерация │ │ Генерация │ │ изобр.(1м) │ │ изобр.(5м) │ │ изобр.(15м) │ └────────┬────┘ └──────┬──────┘ └──────┬──────┘ │ │ │ └─────────────┼───────────────┘ │ ┌────────▼────────┐ │ EfficientNet │ │ Вывод │ │ (GPU Пул) │ └────────┬────────┘ │ ┌────────▼────────┐ │ Ансамбль сигналов│ └────────┬────────┘ │ ┌────────▼────────┐ │ Риск-менеджер │ └────────┬────────┘ │ ┌────────▼────────┐ │ Исполнение │ │ ордеров │ └─────────────────┘Мониторинг
Ключевые метрики:
- Латентность вывода p50/p95/p99
- Распределение уверенности предсказаний
- Уровень согласия сигналов (многотаймфреймовый)
- Обнаружение дрейфа модели
- Утилизация GPU
Отказоустойчивость
- Основной: GPU вывод (EfficientNet-B3)
- Резервный: CPU вывод (EfficientNet-B0)
- Аварийный: Торговые сигналы на основе правил
Ссылки
- Tan, M., & Le, Q. V. (2019). EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks. ICML.
- Wang, Z., & Oates, T. (2015). Imaging Time-Series to Improve Classification and Imputation. IJCAI.
- Chen, L., et al. (2020). Deep Learning for Chart Pattern Recognition in Financial Markets.
- Zhang, Z., et al. (2019). DeepLOB: Deep Convolutional Neural Networks for Limit Order Books.
Следующие шаги
- Изучить EfficientNetV2 для более быстрого обучения
- Реализовать визуализацию внимания для интерпретируемости модели
- Добавить обучение с подкреплением для динамического размера позиции
- Интегрировать с греками опционов для стратегий хеджирования
- Разработать кросс-рыночное обнаружение паттернов
Глава 357 из “Машинное обучение для трейдинга”