๐ค Transformers๋ฅผ ์ด์ฉํ ์๊ณ์ด Transformer ํ๋ฅ ์ ์์ธก
TL;DR
Hugging Face๋ Time Series Transformer๋ฅผ ์๊ฐํ์ต๋๋ค. ์ด๋ ๋จ์ผ ๋ณ์ ์๊ณ์ด์ ๋ํ ์ ์ญ ํ๋ฅ ์ ์์ธก์ ํ์ตํ๋ ๊ธฐ๋ณธ์ ์ธ ์ธ์ฝ๋โ๋์ฝ๋ Transformer์ด๋ฉฐ, Tourism Monthly ๋ฐ์ดํฐ์ ์์ ๊ธฐ์กด ๋ฒ ์ด์ค๋ผ์ธ๋ณด๋ค ์ฐ์ํ ์ฑ๋ฅ์ ๋ณด์ ๋๋ค.
์ ์ ์ญ ํ๋ฅ ๋ชจ๋ธ์ธ๊ฐ?
๋ง์ ๊ด๋ จ ์๊ณ์ด์ ๋ํด ํ๋์ ๋ชจ๋ธ์ ํ์ตํ๋ (global ๋ชจ๋ธ) ์ ๋คํธ์ํฌ๊ฐ ๊ณต์ ํจํด๊ณผ ์ ์ฌ ํํ์ ํฌ์ฐฉํ๋๋ก ํด์ค๋๋ค. ์ด๋ ๊ฐ ์๊ณ์ด์ ๋ ๋ฆฝ์ ์ผ๋ก ๋ง์ถ๋ ๊ณ ์ ์ ์ธ โlocalโ ๋ฐฉ๋ฒ๊ณผ ๋ค๋ฆ ๋๋ค. ํ๋ฅ ์ ์์ธกโ์ ์ถ์ ์ด ์๋๋ผ ์ ์ฒด ๋ถํฌ๋ฅผ ์์ธกํ๋ ๊ฒโ์ ํ์ ์์ฌ๊ฒฐ์ ์ ํ์์ ์ธ ๋ถํ์ค์ฑ ์ ๋ํ๋ฅผ ์ ๊ณตํฉ๋๋ค.
์ํคํ ์ฒ ๊ฐ์
Time Series Transformer๋ ํ์ค Transformer (Vaswani et al., 2017)๋ฅผ ์ธ์ฝ๋โ๋์ฝ๋ ๊ตฌ์ฑ์ผ๋ก ์ฌ์ฌ์ฉํฉ๋๋ค:
- Encoder ๊ณ ์ ํฌ๊ธฐ์ ๊ณผ๊ฑฐ ๊ด์ธก๊ฐ ์ปจํ ์คํธ ์๋์ฐ๋ฅผ ์๋นํฉ๋๋ค.
- Decoder ์ธ๊ณผ ๋ง์คํน์ ์ฌ์ฉํด ๋ฏธ๋ ๊ฐ์ ์๋ํ๊ท์ ์ผ๋ก ์์ฑํฉ๋๋ค. ์ด๋ ํ ์คํธ ์์ฑ๊ณผ ์ ์ฌํฉ๋๋ค.
- Distribution head (default: Studentโt) ๊ฐ ์์ธก ๋จ๊ณ์ ๋ํ ํ๋ฅ ๋ถํฌ์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ถ๋ ฅํฉ๋๋ค.
ํต์ฌ ์ฅ์ :
- ๋๋ฝ๋ ๊ฐ์
attention_mask์ ์ ์ฌํ ๋ฉ์ปค๋์ฆ์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค. - ์๋์ฐ ๊ธฐ๋ฐ ํ์ต์ ํตํด ์์์ ์ปจํ ์คํธ ๋ฐ ์์ธก ๊ธธ์ด๋ฅผ ์ง์ํฉ๋๋ค.
- NLP ๋ชจ๋ธ๊ณผ ๋์ผํ API๋ฅผ ํ์ฉํ์ฌ ์ถ๋ก ์
generate()๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋ชจ๋ธ ๊ตฌ์ฑ ์ธ๋ถ์ฌํญ
from transformers import TimeSeriesTransformerConfig, TimeSeriesTransformerForPrediction
config = TimeSeriesTransformerConfig(
prediction_length=24, # forecast horizon (months)
context_length=48, # encoder window (2ร horizon)
lags_sequence=[1,2,3,4,5,6,7,11,12,13,23,24,25,35,36,37],
num_time_features=2, # monthโofโyear + age feature
num_static_categorical_features=1, # series ID
cardinality=[366], # 366 regions in the dataset
embedding_dimension=[2],
encoder_layers=4,
decoder_layers=4,
d_model=32,
)
model = TimeSeriesTransformerForPrediction(config)
- ๋ชจ๋ธ์ Studentโt ๋ถํฌ๋ฅผ ํ์ตํฉ๋๋ค (
model.config.distribution_output == "student_t"). - ์ ์ ๋ฒ์ฃผํ ์๋ฒ ๋ฉ์ ๊ฐ ์๊ณ์ด์ ์ ์ฒด์ฑ์ ์ธ์ฝ๋ฉํ์ฌ ํ๋์ ๋ชจ๋ธ์ด 366๊ฐ์ ์๊ณ์ด์ ๋ชจ๋ ์ฒ๋ฆฌํ ์ ์๊ฒ ํฉ๋๋ค.
๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ (GluonTS + ๐ค Datasets)
- Monash
tourism_monthly๋ฐ์ดํฐ์ ์ ๋ก๋ํฉ๋๋ค (train/validation/test ๋ถํ , 366 ์๊ณ์ด). startํ์์คํฌํ๋ฅผpandas.Period๋ก ๋ณํํฉ๋๋ค ๋ก ์ฝ๊ฒ ์๊ฐ ํน์ฑ์ ์์ฑํ ์ ์์ต๋๋ค.- GluonTS ๋ณํ ์ฒด์ธ์ ์ ์ํฉ๋๋ค:
- ์ฌ์ฉ๋์ง ์๋ ์ ์ /๋์ ํ๋๋ฅผ ์ ๊ฑฐํฉ๋๋ค.
- ํ๋๋ฅผ NumPy ๋ฐฐ์ด๋ก ๋ณํํฉ๋๋ค.
- ๋๋ฝ๋ ๊ฐ์ ์ํ observedโmask ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
- ์๊ฐ ํน์ฑ(
month_of_year)๊ณผ age ํน์ฑ์ ์์ฑํฉ๋๋ค. - ์๊ฐ ํน์ฑ์ ์คํํ๊ณ ํ๋๋ช ์ Transformer API์ ๋ง๊ฒ ๋ณ๊ฒฝํฉ๋๋ค.
InstanceSplitter๋ฅผ ์์ฑํฉ๋๋ค ์ธ์ฝ๋์ฉcontext_length + max(lags)ํฌ๊ธฐ์ ์๋์ฐ์ ๋์ฝ๋์ฉprediction_lengthํฌ๊ธฐ์ ์๋์ฐ๋ฅผ ์ํ๋งํฉ๋๋ค. ์ธ ๊ฐ์ง ๋ชจ๋๋ฅผ ์ง์ํฉ๋๋ค:train(๋ฌด์์ ์๋์ฐ),validation(๋ง์ง๋ง ์๋์ฐ),test(๋ง์ง๋ง ์ปจํ ์คํธ๋ง).- DataLoaders๋ฅผ ๊ตฌ์ถํฉ๋๋ค ๋ณํ๋ ์ธ์คํด์ค๋ฅผ ํ
์(
past_values,past_time_features,future_time_features๋ฑ)๋ก ๋ฐฐ์นํฉ๋๋ค.
ํ์ต ๋ฃจํ (Accelerate)
from accelerate import Accelerator
from torch.optim import AdamW
accelerator = Accelerator()
model.to(accelerator.device)
optimizer = AdamW(model.parameters(), lr=6e-4, betas=(0.9, 0.95), weight_decay=1e-1)
model, optimizer, train_loader = accelerator.prepare(model, optimizer, train_loader)
model.train()
for epoch in range(40):
for batch in train_loader:
optimizer.zero_grad()
outputs = model(**batch)
accelerator.backward(outputs.loss)
optimizer.step()
- ๋์ฝ๋๋
future_values๋ฅผ ์๋์ผ๋ก ์ํํธํ์ฌ likelihood loss๋ฅผ ๊ณ์ฐํฉ๋๋ค. - ํ์ดํผํ๋ผ๋ฏธํฐ ํ์์ ์ํํ์ง ์์์ผ๋ฉฐ, 40 epoch๋ง์ผ๋ก๋ ๊ฐ๋ ฅํ ๊ฒฐ๊ณผ๋ฅผ ์ป์์ต๋๋ค.
์๋ํ๊ท ์์ฑ์ผ๋ก ์ถ๋ก
model.eval()
forecasts = []
for batch in test_loader:
out = model.generate(**batch)
forecasts.append(out.sequences.cpu().numpy())
forecasts = np.vstack(forecasts) # shape: (366, 100, 24)
generate()๋ ํ์ต๋ ๋ถํฌ์์ ์ํ๋งํ์ฌ ๊ฐ ์๊ณ์ด๋น 100๊ฐ์ MonteโCarlo ๊ถค์ ์ ์์ฑํฉ๋๋ค.- ์ํ๋ค์ ์ค์๊ฐ์ ์ ์์ธก ํ๊ฐ์ ์ฌ์ฉํฉ๋๋ค.
ํ๊ฐ ์งํ
Using the evaluate library:
- MASE (Mean Absolute Scaled Error) = 1.256 (366 ์๊ณ์ด ํ๊ท ).
- sMAPE (Symmetric Mean Absolute Percentage Error) = 0.161.
- ์ด ์์น๋ ๋์ผ ๋ฒค์น๋งํฌ์์ ๋ค์ํ ๊ณ ์ ๋ฐ ๋ฅ ๋ฒ ์ด์ค๋ผ์ธ์ ๋ฅ๊ฐํฉ๋๋ค.
๋ฒค์น๋งํฌ ๋น๊ต
| ๋ชจ๋ธ | MASE |
|---|---|
| SES | 3.306 |
| Theta | 1.649 |
| TBATS | 1.751 |
| ETS | 1.526 |
| (DHRโ)ARIMA | 1.589 |
| PR | 1.678 |
| CatBoost | 1.699 |
| FFNN | 1.582 |
| DeepAR | 1.409 |
| NโBEATS | 1.574 |
| WaveNet | 1.482 |
| Transformer (๋ณธ ์ฐ๊ตฌ) | 1.256 |
Transformer๋ ๋ฐ์ดํฐ์ โํน์ ํ๋ ์์ด ๊ฐ์ฅ ๋ฎ์ MASE๋ฅผ ๋ฌ์ฑํ์ผ๋ฉฐ, ์ ์ญ ์ดํ ์ ๋ฉ์ปค๋์ฆ์ด ๊ณ์ ์ฑ ๋ฐ ์ถ์ธ ํจํด์ ํจ๊ณผ์ ์ผ๋ก ํฌ์ฐฉํ ์ ์์์ ์์ฌํฉ๋๋ค.
์ค์ฉ์ ์ธ ์์ฌ์
- ์ ์ญ ํ๋ฅ ์์ธก์ ๐ค Transformers ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํด ๋ช ์ค์ ์ฝ๋๋ง์ผ๋ก ๊ตฌํํ ์ ์์ต๋๋ค.
- ์ธ์ด ๋ชจ๋ธ์ ์ฌ์ฉ๋๋ ๋์ผํ API(
generate,forward,loss)๊ฐ ์๊ณ์ด ๋ฐ์ดํฐ์๋ ์ ์ฉ๋์ด ์ค๋ฌด์์ ์ง์ ์ฅ๋ฒฝ์ ๋ฎ์ถฅ๋๋ค. - ๋๋ฝ ๋ฐ์ดํฐ ์ฒ๋ฆฌ๋ attention mask๋ฅผ ํตํด ๊ธฐ๋ณธ์ ์ผ๋ก ์ง์๋์ด ๋ณ๋์ ๋ณด๊ฐ์ด ํ์ํ์ง ์์ต๋๋ค.
- ์ด์ฐจ ์๊ฐ ๋ณต์ก๋์ attention์ ์ปจํ ์คํธ ๊ธธ์ด๋ฅผ ์ ํํ๋ฏ๋ก, ํฅํ ์ฐ๊ตฌ์์๋ ํจ์จ์ ์ธ attention ๋ณํ์ ๋์ ํ ์ ์์ต๋๋ค.
์ปค๋ฎค๋ํฐ๋ฅผ ์ํ ๋ค์ ๋จ๊ณ
- ๋ค๋ณ๋ ํ์ฅ โ ๋๊ฐ์ ๋ ๋ฆฝ ๋ฐ ์ ์ฒด ๊ณต๋ถ์ฐ ๋ถํฌ ํค๋๋ฅผ ์ง์ํฉ๋๋ค.
- ์๊ณ์ด ๋ถ๋ฅ โ ์ด์ ํ์ง ๋ฐ ๊ธฐํ ์์ ์ ์ํ ๋ถ๋ฅ ํค๋๋ฅผ ์ถ๊ฐํฉ๋๋ค.
- ์ฌ์ ํ์ต ์ฒดํฌํฌ์ธํธ โ NLP/๋น์ ๊ณผ ์ ์ฌํ๊ฒ ์ด์ง์ ์ธ ์๊ณ์ด ์ฝํผ์ค์ ๋ํ ๋๊ท๋ชจ ์ฌ์ ํ์ต์ ํ์ํฉ๋๋ค.
- ์ ํ์ ๋ ์งโ์๊ฐ ์ ๋ ฅ โ ๋ช ์์ ํ์์คํฌํ๊ฐ ์๋ ๋ฐ์ดํฐ์ (์: ์ ๊ฒฝ๊ณผํ ๊ธฐ๋ก)์ ๋ง๊ฒ ํ์ดํ๋ผ์ธ์ ์กฐ์ ํฉ๋๋ค.
- ํจ์จ์ ์ธ attention โ ํฌ์ ๋๋ ์ ํ ๋ณต์ก๋ attention์ ํตํฉํ์ฌ ์คํ ๊ฐ๋ฅํ ์ปจํ ์คํธ ์๋์ฐ๋ฅผ ํ๋ํฉ๋๋ค.
์ด๋ฒ ๋ฆด๋ฆฌ์ค๋ ์ ์ ํ ํ๋ฅ ํค๋์ ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ์ ๊ฒฐํฉํ ๊ธฐ๋ณธ์ ์ธ Transformer๊ฐ ๋จ๋ณ๋ ์์ธก์์๋ ๊ฒฝ์๋ ฅ์ ๊ฐ์ถ๋ค๋ ๊ฒ์ ๋ณด์ฌ์ค๋๋ค. ์ฐ๊ตฌ์์ ์์ง๋์ด๋ Hugging Face Hub์ ๋ค๋ฅธ ๋ฐ์ดํฐ์ ์ ์คํํ๊ณ , ์ฃผํ์๋ณ ํ๋ผ๋ฏธํฐ๋ฅผ ์กฐ์ ํ๋ฉฐ, ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ถ๊ฐ ๋ชจ๋ธ์ ๊ธฐ์ฌํ๋๋ก ๊ถ์ฅ๋ฉ๋๋ค.
SUMMARY: Hugging Face๋ ์ ์ญ ํ๋ฅ ์๊ณ์ด ์์ธก์ ์ํ ๊ธฐ๋ณธ Transformer ๋ชจ๋ธ์ ์ถ์ํ์ผ๋ฉฐ, Tourism Monthly ๋ฒค์น๋งํฌ์์ ์ต์ฒจ๋จ ์ฑ๋ฅ์ ์ ์ฆํ์ต๋๋ค.
TITLE: ๐ค Transformers๋ฅผ ์ด์ฉํ ์๊ณ์ด Transformer ํ๋ฅ ์ ์์ธก