Multi-Task Learning for Simultaneous Price, Volume, and Volatility Prediction
MTL(다중 작업 학습)은 일반적으로 어설션과 함께 판매됩니다. 즉, 상관된 대상 간에 인코더를 공유하면 기본 작업이 더 좋아집니다. 거래에서 상관관계가 있는 목표는 명백합니다. 수익률, 거래량, 실현 변동성은 모두 동일한 주문 흐름에서 발생하며 이러한 주장은 거의 테스트되지 않습니다. 흥미로운 질문은 작업이 관련되어 있는지 여부가 아닙니다. 공유된 그라디언트가 동의하는지 여부와 그렇지 않은 경우 접힌 부분에서 어떤 일이 발생하는지가 중요합니다.
이 기사에서는 대부분의 MTL 글이 각주로 취급되는 두 가지 사항을 중심으로 설명합니다.
- 손실 균형은 세부 사항이 아닌 실험입니다. 고정 가중치, Kendall 불확실성 가중치 및 GradNorm은 세 가지 다른 모델입니다. 동일한 접기에서 세 가지를 모두 실행하고 각각에 대한 기본 작업 측정항목과 함께 학습된 가중치를 보고합니다.
- 음수 전송은 메트릭을 보기 전에 측정할 수 있습니다. 공유 인코더의 작업 그라데이션 간의 코사인 유사성은 훈련 중에 보조 작업이 기본 작업이 원하는 위치로 표현을 가져오고 있는지 여부를 알려줍니다. 코사인에 서명한 다음, 그 기호가 해당 접기의 결과를 예측했는지 확인하세요.
변동성 프로세스, 훈련 루프, 누출 제어, 검증 프로토콜 등 파이프라인의 다른 모든 내용은 이미 이 블로그의 다른 곳에서 다루고 있으며 다시 파생되지 않고 링크되어 있습니다.
설정

입력 기능 (OHLCV, 기술 지표, 주문 흐름)가 주어지면 세 가지 목표:
- 작업 1(1차): 다음 기간 반환
- 작업 2(보조): 다음 기간 로그 볼륨
- 과제 3(보조): 차기 실현변동성
다중 작업 모델은 세 가지 를 동시에 생성하며 다중 작업 위험은 작업별 위험의 가중 합계입니다.
전체 기사는 와 작업별 그라데이션이 서로에게 미치는 영향에 관한 것입니다.
공동 훈련이 도움이 될 수 있는 이유를 한 단락으로 설명합니다. 보조 작업은 공유 표현이 용량 제어와 귀납적 편견인 둘 이상의 시장 현상을 동시에 설명하도록 제한합니다. 거래량과 변동성은 직접적으로 관찰되지만 "기대 수익률"은 관찰되지 않기 때문에 보조 헤드는 기본 헤드보다 더 깨끗한 기울기 신호를 제공합니다. 많은 출력을 방출하는 하나의 모델에 대한 사례는 해석 가능성 기계가 첨부된 다수평선 예측을 위한 임시 융합 변환기]에서 길게 논의되며, 이는 다중수평 분위수에 대해 동일한 공유 인코더 다중 헤드 주장을 만듭니다.
아키텍처 개요
하드 매개변수 공유: 공유 인코더 는 작업별 헤드 를 공급하므로 입니다. 여기서 측정한 버전은 의 그래디언트 충돌이 잘 정의된 버전이기 때문입니다.
소프트 매개변수 공유는 각 작업에 커플링 페널티 가 있는 자체 인코더를 제공합니다. 즉, 더 많은 매개변수, 더 많은 유연성, 충돌을 측정할 단일 공유 매개변수 벡터가 없습니다. 크로스 스티치 네트워크는 각 레벨에서 학습된 매트릭스 를 통해 작업별 기능을 혼합하면서 그 사이에 위치합니다. 하드 공유가 충돌을 나타내는 경우 둘 다 시도해 볼 가치가 있으며 둘 다 아래 측정 범위를 벗어납니다.
중요한 실험: 세 가지 손실 균형 방식

순진한 손실 는 규모에 민감합니다. 반사 손실이 주변에 있고 볼륨 손실이 주변에 있는 경우 볼륨이 기울기를 소유하고 리턴 헤드가 부족해집니다. 세 가지 응답:
고정 가중치. 모든 타겟을 표준화한 후 를 설정합니다. 정직한 기준 - 승리할 경우 적응 계획은 의식입니다.
불확도 가중치(Kendall et al., 2018). 작업별로 등분산적 잡음 척도 를 알아봅니다.
불확실성이 높은 작업은 자동으로 가중치가 낮아집니다. 용어는 사소한 솔루션을 차단합니다. 이 는 예측 간격이 아닌 훈련 시간 손실 가중치 장치입니다. 실제로 위치 크기를 조정할 수 있는 불확실성에 대해서는 등각 예측를 참조하세요.
GradNorm(Chen et al., 2018). 손실 규모가 아닌 균형 기울기 크기. 각 단계: 및 평균 를 계산하고, 상대 훈련 속도 를 계산하고, 를 업데이트합니다. 그런 다음 모든 작업은 손실 규모에 관계없이 비슷한 속도로 훈련됩니다.
MTL 특정 코드는 헤드, 앞으로 반환되는 목록 및 손실 집계입니다. Linear/BatchNorm/ReLU/Dropout 스택, Adam/cosine/clip 상용구 및 epoch 루프는 DeepLOB에 표시된 표준 패턴이며 여기에서는 생략되었습니다.
import torch
import torch.nn as nn
class MultiTaskTradingModel(nn.Module):
"""Hard parameter sharing: one encoder, K heads."""
def __init__(self, encoder: nn.Module, repr_dim: int, n_tasks: int = 3):
super().__init__()
self.shared_encoder = encoder # any MLP/CNN/GRU trunk
self.task_heads = nn.ModuleList(
nn.Linear(repr_dim, 1) for _ in range(n_tasks)
)
def forward(self, x):
h = self.shared_encoder(x)
return [head(h).squeeze(-1) for head in self.task_heads]
def shared_repr(self, x):
return self.shared_encoder(x)
class UncertaintyWeightedLoss(nn.Module):
"""Kendall et al. (2018) homoscedastic weighting."""
def __init__(self, n_tasks: int = 3):
super().__init__()
self.log_vars = nn.Parameter(torch.zeros(n_tasks)) # log(sigma^2)
def forward(self, losses: list) -> torch.Tensor:
return sum(
torch.exp(-self.log_vars[i]) * loss + self.log_vars[i]
for i, loss in enumerate(losses)
)
def get_weights(self) -> list:
with torch.no_grad():
return [torch.exp(-lv).item() for lv in self.log_vars]
UncertaintyWeightedLoss에는 매개변수가 있으므로 모델 optim.Adam(list(model.parameters()) + list(uw.parameters()), ...)와 함께 최적화 프로그램으로 들어가야 합니다. 이것을 잊어버리는 것이 "불확실성 가중치를 실행"하고 대신 고정 가중치를 자동으로 실행하는 가장 일반적인 방법입니다.
보고할 내용
각 체계에 대해, 각 접기에서 학습된 최종 작업 가중치, 기본 작업 측정항목 및 가중치 부여 체계는 모델 선택이기 때문에 하나를 선택하기 전에 비교된 체계 수입니다.
| 계획 | 기본 작업 측정항목과 단일 작업 비교 | |||
|---|---|---|---|---|
| 고정() | 1.00 | 1.00 | 1.00 | — |
| 불확실성 가중치 | — | — | — | — |
| GradNorm | — | — | — | — |
세 가지 방식에 여러 배를 곱하면 이미 작은 모델 검색입니다. 여기에 보고된 개선 사항은 수축된 Sharpe 및 여러 테스트에 설명된 여러 테스트 수정을 거쳐야 의미가 있습니다.
부정적 전이: 그래디언트가 보여주는 것

보관할 가치가 있는 부분입니다. 부정적인 전달은 보조 작업이 기본 작업을 악화시키는 경우이며 직접적인 진단이 있습니다. 즉, 공유 매개변수 공간에서 작업 그라데이션 사이의 각도입니다.
공유 인코더에서만 측정됩니다. 헤드는 구성에 따라 작업별로 다르며 항상 사소하게 "동의"됩니다.
import torch.nn.functional as F
def shared_grad(model, x, y, task_idx, criterion=nn.MSELoss()):
"""Gradient of task `task_idx` w.r.t. the shared encoder, flattened."""
model.zero_grad(set_to_none=True)
loss = criterion(model(x)[task_idx], y)
loss.backward()
return torch.cat([
p.grad.detach().flatten()
for p in model.shared_encoder.parameters()
if p.grad is not None
])
def task_conflict(model, x, y_by_task, task_names):
"""Pairwise cosine similarity between per-task shared-encoder gradients."""
grads = {
name: shared_grad(model, x, y_by_task[name], i)
for i, name in enumerate(task_names)
}
return {
(a, b): F.cosine_similarity(
grads[a].unsqueeze(0), grads[b].unsqueeze(0)
).item()
for i, a in enumerate(task_names)
for b in task_names[i + 1:]
}
훈련이 끝날 때 한 번이 아니라 훈련 중에 고정된 주기로 보류 배치에서 이를 호출하십시오. 인코더가 전문화함에 따라 쌍은 정렬을 시작하고 분기될 수 있습니다. 하나의 훈련 종료 번호로 이를 숨길 수 있습니다.
찾아서 게시할 결과는 다음과 같습니다.
| 쌍 | cos sim, 조기 교육 | cos sim, 늦은 훈련 | MTL이 기본 작업에 도움이 되었나요? |
|---|---|---|---|
| 수익률 ⇔ 거래량 | — | — | — |
| 수익률 ⇔ 변동성 | — | — | — |
| 거래량 ⇔ 변동성 | — | — | — |
거래량과 변동성 기울기가 서로 일치하고 둘 다 반환 기울기와 충돌하는 경우 올바른 결론은 두 개의 보조 작업이 반환 작업이 속하지 않는 일관된 블록을 형성한다는 것입니다. 수정은 더 많은 용량이 아니라 작업 그룹화입니다. 충돌이 실제로 발생하는 경우 표준 해결 방법은 PCGrad(Yu et al., 2020)입니다. 이는 충돌하는 각 경사도를 다른 경사도의 일반 평면에 투영합니다. CAGrad(Liu et al., 2021), 어떤 작업에도 해를 끼치지 않는 하강 방향을 검색합니다. 또는 보조 작업을 완전히 삭제합니다.
의도적으로 누락된 점에 주목하세요: 목표 값으로 색상이 지정된 공유 표현의 t-SNE 플롯입니다. 장식적입니다. 위의 코사인 숫자는 임베딩이 나타내는 모든 것을 말하며 숫자로 나타냅니다.
검증 프로토콜

위의 측정은 엉성한 프로토콜에서는 쓸모가 없으며 MTL은 누출할 대상이 하나가 아닌 세 개이기 때문에 일반적인 트랩을 더욱 악화시킵니다.
시뮬레이터가 아닌 실제 데이터. 목표는 실제 OHLCV/무역 데이터에서 나와야 합니다. 하드코딩된 GARCH 장난감은 구성별 수익과 상관관계가 있는 변동성을 생성합니다. 이는 정확하게 테스트 중인 것입니다. 실험에서는 자체 생성기를 측정하게 됩니다. 적합한 변동성 프로세스를 원하는 경우, crypto에 대한 GARCH 변동성 예측은 실제 BTC/ETH의 최대 가능성으로 GARCH(1,1)에 적합하고 표준화된 잔차를 검증하며, 비대칭 GARCH 및 레버리지 효과는 애초에 가우스 대칭 응답 시뮬레이터가 암호화 변동성을 잘못 표시하는 이유를 다룹니다. 합성 데이터는 통제된 지상 진실(복원하려는 알려진 작성자 설정 작업 상관 관계)을 제공하는 경우에만 방어할 수 있습니다. 이는 여기서의 실험과는 다릅니다.
스케일러는 열차에만 적합합니다. 각 훈련 접기 내부에 기능 스케일러와 세 가지 대상 스케일러를 모두 맞추고 검증에 적용합니다. 누출 테스트 세트 순간을 훈련으로 분할하기 전에 글로벌 fit_transform입니다. 이 정확한 실패는 예측 편향 분류 .
제거되고 금지된 워크 포워드 폴드. 하나의 80/20 연대순 분할은 MTL 개선과 폴드 효과를 구별할 수 없습니다. 이는 세 개의 결론을 생성하는 세 개의 분할을 보여주는 워크 포워드 최적화의 전체 인수입니다. 기계 학습을 통한 확산 모델링의 확장 창 purged_walk_forward 생성기를 재사용합니다. 각 경계의 양쪽에서 horizon 행의 간격을 삭제합니다. 이는 반환 대상이 그렇지 않은 경우에도 겹치는 실현 변동성 창이 경계를 넘어 누출되기 때문에 여기서 중요합니다.
고전적인 기준선. 3개의 단일 작업 넷을 능가하는 MTL 넷은 대상별 그래디언트 부스팅 또는 능선 모델이 4개 모두를 능가하는 경우 아무 것도 입증되지 않았습니다. LightGBM 또는 능선이 있는 대상당 하나의 모델을 동일한 접힘 및 동일한 기능에 맞추고 동일한 테이블에 보고합니다.
| 모델 | 기본 작업 측정항목 | 메모 |
|---|---|---|
| 능선, 대상별 | — | 고전적 기준선 |
| LightGBM, 대상별 | — | 고전적 기준선 |
| 대상별 단일 작업 MLP | — | 세 개의 별도 그물 |
| MTL, 최고의 손실 방식 | — | 하나의 그물, 세 개의 머리 |
MTL이 가치 있는 경우

MTL이 승리해야 하는 조건은 체크리스트가 아닌 위의 폴드를 확인하기 위한 가설로 명시됩니다.
- 보조 라벨은 기본 라벨보다 깨끗합니다. 볼륨을 직접 관찰합니다. "기대 수익"은 그렇지 않습니다. 리턴 헤드가 대부분 노이즈에 맞는 경우 보조 헤드의 경사 신호는 대물렌즈의 위치가 올바른 유일한 부분입니다.
- 훈련 데이터는 인코더 용량에 비해 제한되어 있으므로 보조 제약 조건은 단순히 매개변수에 대해 경쟁하는 것이 아니라 실제 정규화 작업을 수행합니다.
- 추론 지연 시간이 중요하며 하나의 정방향 패스가 3개보다 뛰어납니다.
반대 사례도 동일하게 테스트 가능합니다. 측정된 cos_sim(return, ·) 값이 지속적으로 음수인 경우 공유 인코더는 기본 작업에서 멀어지고 보조 헤드는 정규화가 아닌 세금입니다.
결론

수익률, 거래량, 변동성은 동일한 미세 구조에서 나오므로 공유 표현은 합리적인 사전 계산이지만 사전 계산은 결과가 아닙니다. 이 설정이 실제로 설정할 수 있는 두 가지 사항은 데이터가 선호하는 손실 균형 방식(승자 이름이 아닌 학습된 가중치가 보고됨)과 공유 인코더의 작업 경사도가 일치하는지 여부(목표가 상관되어 있다는 사실에서 가정하는 것이 아니라 훈련을 통해 측정)입니다.
제거된 Walk-forward 폴드에서 MTL 네트가 대상별 그래디언트 부스팅 모델을 이기지 못하는 것으로 나타나면 이것이 발견이며 그렇게 게시됩니다. 템플릿은 정직한 negative입니다. 부정적인 전달에 대한 부정적인 결과는 여전히 부정적인 전달에 대한 결과입니다.
Authors
Trading-systems engineer
Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.