在原論文《Lag-Llama: Towards Foundation Models for Probabilistic Time Series Forecasting》中,Lag-Llama作為單變量概率預測的通用大模型提出。

在本文中,我們將探討Lag-Llama的架構、功能以及訓練方式。還會通過代碼將lagllama應用于一個預測項目中,并將其與其他深度學習方法Temporal Fusion Transformer (TFT) 和DeepAR進行性能比較。

Lag-Llama

lagllama是為單變量概率預測而構建的,它使用不依賴于頻率的通用方法來標記時間序列數據。這樣模型可以很好地泛化到不可見的頻率。

1、時間序列數據處理

laglllama的標記策略是使用一組指定的滯后特征。

它將從這個列表中為給定的數據集選擇所有合適的頻率: 季度、月、周、天、小時、秒

也就是說,如果以每日頻率提供數據集,lag – llama將嘗試使用每日滯后(t-1),每周滯后(t-7),每月滯后(t-30)等構建特征。

策略如下圖所示。

從上圖中,我們還可以看到模型構建了其他靜態協變量,例如秒/分、小時/天等等,直到季度/年。雖然這可以很好地推廣到所有類型的時間序列,但它有一個致命的缺點:由于固定的滯后指數列表,輸入令牌可能會變得非常大。

例如,查看每小時數據的每月頻率需要730個時間步。這意味著除了所有靜態協變量之外,輸入令牌的長度至少為730。

2、Lag-Llama架構

Lag-Llama是一個基于transformer的純解碼器模型,其靈感來自大型語言模型LLaMA的體系結構。它利用Transformer體系結構來解析輸入token,并將它們映射到具有置信區間的未來預測。

從圖中可以看到輸入標記是滯后時間步長和靜態協變量的拼接。輸入序列通過線性投影層將特征映射到解碼器內部注意力模塊的隱藏維度。另外就是在最后的輸出,序列被發送到一個分布頭負責輸出一個概率分布。

在推理過程中,輸入序列生成下一個時間點的分布。然后通過自回歸,模型逐個生成剩余的預測序列,直到達到設置的長度。

生成預測的自回歸過程有效地允許模型為其預測生成不確定性區間。但是這里的問題就是如果序列很長,自回歸的方式會將錯誤擴大。

3、Lag-Llama的訓練

作為一個基礎模型,Lag-Llama顯然是在大量的時間序列數據語料庫上訓練的,因此該模型可以很好地泛化未見過的時間序列并進行零樣本預測。

論文中說:Lag-Llama在來自不同領域的27個時間序列數據集上進行了訓練,如能源、交通、經濟等。

數據包含7965個單變量時間序列,總計約3.52億個令牌。

所有數據集都是開源的,包括ethth, Exchange和Weather等。

Lag-Llama實踐及測試

因為代碼已經開源,所以我們可以直接測試,我們首先使用Lag-Llama的零樣本預測能力,并將其性能與特定數據模型(如TFT和DeepAR)進行比較。

Lag-Llama的實現是建立在GluonTS之上的,所以我們還需要安裝這個庫。實驗使用了澳大利亞電力需求數據集,該數據集包含五個單變量時間序列,以半小時的頻率跟蹤能源需求。

這里有個說明:Lag-Llama目前的實現是初期階段。并且存還在積極開發中,后面可能還會有很大的調整,因為目前還沒加入微調的功能。

1、環境設置

 !git clone https://github.com/time-series-foundation-models/lag-llama/
cd lag-llama
pip install -r requirements.txt --quiet

然后需要我們從HuggingFace下載模型的權重。

 !huggingface-cli download time-series-foundation-models/Lag-Llama lag-llama.ckpt --local-dir /content/lag-llama

2、加載數據集

 import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import torch

from itertools import islice

from gluonts.evaluation import make_evaluation_predictions, Evaluator
from gluonts.dataset.repository.datasets import get_dataset
from lag_llama.gluon.estimator import LagLlamaEstimator

可以直接從GluonTS加載數據集。

dataset = get_dataset("australian_electricity_demand")
backtest_dataset = dataset.test prediction_length = dataset.metadata.prediction_length
context_length = 3 * prediction_length

3、使用Lag-Llama預測

簡單地初始化模型并使用LagLlamaEstimator對象。

 ckpt = torch.load("lag-llama.ckpt", map_location=torch.device('cuda:0'))
estimator_args = ckpt["hyper_parameters"]["model_kwargs"]
estimator = LagLlamaEstimator( ckpt_path="lag-llama.ckpt",
prediction_length=prediction_length,
context_length=context_length,
input_size=estimator_args["input_size"],
n_layer=estimator_args["n_layer"],
n_embd_per_head=estimator_args["n_embd_per_head"],
n_head=estimator_args["n_head"],
scaling=estimator_args["scaling"],
time_feat=estimator_args["time_feat"])

lightning_module = estimator.create_lightning_module()
transformation = estimator.create_transformation()
predictor = estimator.create_predictor(transformation, lightning_module)

使用make_evaluation_predictions函數生成零樣本的預測。

 forecast_it, ts_it = make_evaluation_predictions(
dataset=backtest_dataset,
predictor=predictor)

這個函數返回生成器。我們需要把它們轉換成列表。

forecasts = list(forecast_it)
tss = list(ts_it)

4、評估

GluonTS可以使用Evaluator對象方便地計算不同的性能指標。

 evaluator = Evaluator()

agg_metrics, ts_metrics = evaluator(iter(tss), iter(forecasts))

RMSE為481.57。

我們還可以隨意地將預測可視化。

 plt.figure(figsize=(20, 15))
date_formater = mdates.DateFormatter('%b, %d')
plt.rcParams.update({'font.size': 15})

for idx, (forecast, ts) in islice(enumerate(zip(forecasts, tss)), 4):
ax = plt.subplot(2, 2, idx+1)
plt.plot(ts[-4 * dataset.metadata.prediction_length:].to_timestamp(), label="target")
forecast.plot( color='g')

plt.xticks(rotation=60)
ax.xaxis.set_major_formatter(date_formater)
ax.set_title(forecast.item_id)

plt.gcf().tight_layout()
plt.legend()
plt.show()

上圖可以看到模型對數據做出了合理的預測,盡管它在第四個序列(圖的右下角)上確實存在問題。

另外由于 Lag-Llama實現了概率預測,可以得到預測的不確定性區間。

5、與TFT和DeepAR相比

我們在數據集上訓練TFT和DeepAR模型,看看它們是否能表現得更好。

為了節省時間,我們將訓練設置為5個epoch。

 from gluonts.torch import TemporalFusionTransformerEstimator, DeepAREstimator

tft_estimator = TemporalFusionTransformerEstimator(
prediction_length=prediction_length,
context_length=context_length,
freq="30min",
trainer_kwargs={"max_epochs": 5})

deepar_estimator = DeepAREstimator(
prediction_length=prediction_length,
context_length=context_length,
freq="30min",
trainer_kwargs={"max_epochs": 5})

訓練過程。

tft_predictor = tft_estimator.train(dataset.train)
deepar_predictor = deepar_estimator.train(dataset.train)

訓練完成后,生成預測并計算RMSE。

 tft_forecast_it, tft_ts_it = make_evaluation_predictions(
dataset=backtest_dataset,
predictor=tft_predictor)

deepar_forecast_it, deepar_ts_it = make_evaluation_predictions(
dataset=backtest_dataset,
predictor=deepar_predictor)

tft_forecasts = list(tft_forecast_it)
tft_tss = list(tft_ts_it)

deepar_forecasts = list(deepar_forecast_it)
deepar_tss = list(deepar_ts_it)

# Get evaluation metrics
tft_agg_metrics, tft_ts_metrics = evaluator(iter(tft_tss), iter(tft_forecasts))
deepar_agg_metrics, deepar_ts_metrics = evaluator(iter(deepar_tss), iter(deepar_forecasts))

下表突出顯示了性能最好的模型。

可以看到只訓練了5個epoch這兩個模型都取得了比Lag-Llama更好的結果,TFT是目前表現最好的模型,DeepAR的表現也優于laglama。

雖然laglllama的表現似乎不盡如人意,但該模型沒有經過微調(零樣本學習本身就比較困難些)。

總結

在嘗試了TimeGPT和Lag-Llama之后,Lag-Llama算是構建開源預測模型的第一步,但與TimeGPT相比,它在功能方面存在不足。TimeGPT可以處理多變量時間序列、不規則時間戳,并實現共形預測,與使用laglama等固定分布相比,這是一種更穩健的量化不確定性的方式。

laglllama是一個開源的基礎模型,只用于單變量概率預測,性能表現也比較有限。相信在不久的將來會看到更多的開源預測模型出現,他們的表現可能會得到改善,這代表了該領域的一個重大轉變。

文章轉自微信公眾號@算法進階

上一篇:

時間序列+Transformer!

下一篇:

擴散模型的原理及實現(Pytorch)
#你可能也喜歡這些API文章!

我們有何不同?

API服務商零注冊

多API并行試用

數據驅動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內容創意新穎性、情感共鳴力、商業轉化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費