Autoformer: Decomposition Transformers with Auto-Correlation for Long-Term Series Forecasting
Autoformer: Decomposition Transformers with Auto-Correlation for Long-Term Series Forecasting [paper] は、Transformer に似た (マルチヘッドアテンション層を "Auto-Correlation" 層に、層正規化層を "Series Decomposition" 層に置き換えた) エンコーダ + デコーダ構造をもつ時系列予測モデル Autoformer を提案する論文である。Tsinghua University (清華大学) の Haixu Wu らによって著され (著者全員が同所属)、2021 年の NeurIPS に採択された。
具体的に、"Auto-Correlation" 層は入力系列の各ステップを Q, K, V に線形変換し、FFT を用いて Q-K の全ラグの相互相関を O(L log L) で一括計算し、モデル次元方向の平均値がトップ k = floor(c log L) 個のステップに絞った上で softmax し、各ラグ分だけ V をロールシフトして重み付き和を取る。続く "Series Decomposition" 層は入力系列の移動平均 (ウィンドウサイズ 25) をとってトレンド成分とし、これを分離する (分離したトレンド成分は、エンコーダでは破棄し、デコーダでは蓄積する)。
参考文献
- paper
- Haixu Wu, Jiehui Xu, Jianmin Wang, Mingsheng Long. Autoformer: Decomposition Transformers with Auto-Correlation for Long-Term Series Forecasting. Advances in Neural Information Processing Systems (NeurIPS 2021), vol. 34, 2021.
Autoformer の構造
- models/Autoformer.py::Model
- layers/Embed.py::DataEmbedding_wo_pos
- layers/Autoformer_EncDec.py::Encoder (これの上に EncoderLayer も)
- layers/Autoformer_EncDec.py::Decoder (これの上に DecoderLayer も)
Autoformer は参照期間のタイムスタンプ (L_in,)、参照期間の観測値 (L_in, C)、予測期間のタイムスタンプ (L_out,) を受け取り、予測結果 (L_out, C) を出力する。
Autoformer ではデコーダ初期化に用いる過去系列の長さをラベル長 L_label = L_in/2 と定めている。直近の過去情報をデコーダに与えつつ、ゼロパディング部分を予測させる設計になっている (つまり、エンコーダに入力する系列の後半は常にデコーダの初期入力にもなる)。ラベル長は実装上はハイパーパラメータとなっているが、論文では L_in/2 をデフォルトとしている。
また、エンコーダ出力と、デコーダ出力の季節成分に対して、独自の正規化を適用する。具体的に、通常の層正規化 (各トークンの標準化) に加えて、各時系列の平均を差し引く。季節成分がゼロ周りの振動になるよう保証する措置と考えられる。この記事では以降、"TokenNormSeriesDemean" とよぶ。
Autoformer のモデル次元数 512、中間層次元数 2048、ヘッド数 8 はオリジナル Transformer の値がそのまま採用されている。ただし、エンコーダ層数 2、デコーダ層数 1 はオリジナル Transformer での層数 (エンコーダ層数、デコーダ層数共に 6) とは異なる。また、活性化に GELU を採用している点もオリジナル Transformer とは異なる [脚注GELU]。
Autoformer 全体
- x_enc (L_in, C)、x_mark_enc (L_in, n_feat)、x_mark_dec (L_label+L_out, n_feat) を受け取る。ただし、x_mark_enc, x_mark_dec はタイムスタンプから以下の 5 (4) 列の特徴を抽出し各列を -0.5~0.5 の値に正規化したものである。
- その時刻が何時か (0〜23 時)
- その日が週の何日目か (1〜7 日)
- その日が月の何日目か (1〜31 日)
- その日が年の何日目か (1〜365 日)
- その分が時間の何分目か (0〜59 分) ※ 時間ステップが 1 時間未満の場合のみ。
- (L_in, C) 次元の入力系列の各ステップのチャネル次元を線形変換で 512 次元に埋め込み、時間特徴エンコーディングの最初の L_in ステップを加算し、エンコーダ入力とする。
- エンコーダ入力に "Series Decomposition" 層を適用する:移動平均 (ウィンドウサイズ 25) でトレンド成分を抽出し、残りを季節成分とする (ア)。
- (ア) の季節成分の後半 L_in/2 ステップに、時間特徴エンコーディングの最後の L_out ステップを concat し、デコーダ入力の季節成分とする。
- (ア) のトレンド成分の後半 L_in/2 ステップに、エンコーダ入力全体の平均を L_out ステップ分繰り返して concat し、デコーダ入力のトレンド成分とする。
- エンコーダ入力にエンコーダを適用してエンコーダ出力を得る。
- エンコーダ出力の下に、デコーダ入力にデコーダを適用してデコーダ出力を得る。
- 最後に、以下の後半 L_out ステップ同士を加算して予測結果とする。
- デコーダ出力の季節成分に、線形変換 (512 → C 次元) を適用する。
- デコーダ出力のトレンド成分に、カーネルサイズ 3 の Conv1d (3×512 → C 次元) を適用する。
データ埋込層
- (L, d_inp) 次元の時間特徴と (L, C) 次元の入力データをそれぞれ以下で (L, d_model) 次元に変換して足し合わせ、ドロップアウトする。
- (L, d_inp) 次元の時間特徴を時刻ごとに d_model 次元に線形変換する。
- (L, C) 次元の入力データを各時刻を中心に Conv1d(kernel_size=3, keep_len=True, padding_mode='circular') で畳込んで (L, d_model) 次元に変換する。
エンコーダ
- エンコーダ層 (以下) を 2 層積み重ねる。
- (L_in, d_model) 次元の入力系列を受け取る (ア)。
- "AutoCorrelation" 層 (以下) を適用する。
- 入力系列をステップごとに Q, K, V 用に 3×8×64 次元に線形変換して、8 ヘッドに分割する。
- 各ヘッドで FFT を用いて Q-K の全ラグの相互相関を計算し、モデル次元方向の平均値の大きいトップ k = floor(c log L) 個のラグに絞った上で softmax し (c の規定値は 1) [脚注top]、絞った各ラグ分だけ V をロールシフトして重み付き和を取る。
- 各ヘッドからの出力を 8×64=512 次元に連結する。
- 512 次元に線形変換する。
- ドロップアウトする。
- (ア) から残差接続する。
- "Series Decomposition" 層を適用して季節成分を得る (イ)。トレンド成分は破棄する。
- 2048 次元に線形変換、GELU 活性化、ドロップアウトする。
- 再び 512 次元に線形変換、ドロップアウトする。
- (イ) から残差接続する。
- "Series Decomposition" 層を適用して季節成分を得る。トレンド成分は破棄する。
- "TokenNormSeriesDemean" を適用する。
デコーダ
- デコーダ層 (以下) を 1 層適用する。
- デコーダ層 (以下) を 1 層適用する。
- 各ステップが 512 次元の季節成分 (ア) とトレンド成分 (イ) を入力として受け取る。
- "Auto-Correlation" 層を適用する。
- ドロップアウトする。
- (ア) から残差接続する。
- "Series Decomposition" 層を適用して季節成分を得る (ウ)。トレンド成分は (イ) に累積。
- クロス "Auto-Correlation" 層 (以下) を適用する。
- (ウ) から Q 用に 8×64 次元に線形変換して 8 ヘッドに分割する。
- エンコーダ出力から K, V 用にそれぞれ 8×64 次元に線形変換して 8 ヘッドに分割する。
- 8 ヘッド並列に FFT 相互相関・トップ k ラグ選択・ロールシフト和を適用する。
- 各ヘッドからの出力を 8×64=512 次元に連結する。
- 512 次元に線形変換する。
- ドロップアウトする。
- (ウ) から残差接続する。
- "Series Decomposition" 層を適用して季節成分を得る (エ)。トレンド成分は (イ) に累積。
- 2048 次元に線形変換、GELU 活性化、ドロップアウトする。
- 再び 512 次元に線形変換、ドロップアウトする。
- (エ) から残差接続する。
- "Series Decomposition" 層を適用して季節成分を得る (オ)。トレンド成分は (イ) に累積。
- (オ) に "TokenNormSeriesDemean" を適用し、デコーダ出力の季節成分とする。
- 累積されたトレンド成分を、そのままデコーダ出力のトレンド成分とする。
トイモデル
論文リポジトリの 2026/04/09 現在の最新リビジョン (51c7d41) を取得して以下を実行すれば、小さなインスタンスができる。
from models.Autoformer import Model
import types
import torch
def main():
configs = {
'seq_len': 8, 'label_len': 4, 'pred_len': 3,
'embed': 'timeF', 'freq': 'h',
'moving_avg': 25, 'd_model': 6, 'n_heads': 2,
'factor': 1, 'd_ff': 12,
'e_layers': 2, 'enc_in': 5,
'd_layers': 1, 'dec_in': 5, 'c_out': 5,
'activation': 'gelu', 'dropout': 0.05,
'output_attention': False,
}
model = Model(types.SimpleNamespace(configs))
print(model)
x_enc = torch.randn(1, 8, 5)
x_dec = torch.zeros(1, 7, 5)
x_mark_enc = torch.rand(1, 8, 4) - 0.5
x_mark_dec = torch.rand(1, 7, 4) - 0.5
with torch.no_grad():
output = model(
x_enc,
x_mark_enc,
x_dec,
x_mark_dec,
)
assert output.shape == (1, 3, 5)
if __name__ == '__main__':
main()
脚注
- GELU
- GELU とは Gaussian Error Linear Unit の略で、f(x) = x · Φ(x) と定義される (Φ は標準正規分布の累積分布関数)。ReLU が x < 0 で出力を 0 にカットするのに対し、GELU は x < 0 でも確率的に小さい値を通すなめらかな形になる。Dan Hendrycks と Kevin Gimpel が 2016 年に提案し ()、BERT (2018) で採用されてから Transformer 系モデルでの標準的な活性化関数として普及した。Autoformer が GELU を選んだ理由は論文中に明記はなく、当時の標準に倣ったものと考えられる。
- top
- 絶対値を取るのではなく、符号付きで値の大きいラグを選択する (後段で softmax 重み付き和を取る都合上、相関が負のラグを取ると予測が劣化すると考えられ、ここで相関が負のラグを取るべきではないのはさもありなんと思われる)。