時系列の異常検知でよく使うのは「正常を再構成(または予測)して、うまく再現できないものを異常とする」やり方です。でも、これには弱点があります。再構成モデルは、訓練データに紛れた異常まで覚えてしまったり、ノイズに振り回されたりします。
DCdetector(Yang et al., KDD 2023)は、まったく違う発想をします。ひとことで言うと——
同じ時系列を「2つの見方」で見て、その食い違い(乖離)が大きいところを異常とする。
正常な点は、どちらの見方でも「いつもの正常パターン」として一貫して見えます。でも異常な点は、見方によって違って見える。この「食い違い」を異常の合図にするのです。再構成もしないし、ガウス核のような事前知識も、対照学習にありがちな「負例」も使いません。余計な部品を引き算した、シンプルな設計が魅力です。
本記事では、DCdetectorの骨子——2つの見方をどう作り、食い違いをどう測り、どう学習するか——を、論文の図とコードを使ってできるだけ分かりやすく追います。
本記事の内容
- 先行手法との設計上の違い(再構成 vs Anomaly Transformer vs DCdetector)
- 「2つの見方」とは何か(patch-wise と in-patch)
- なぜ食い違いで異常が分かるのか
- 全体アーキテクチャ(4つのモジュール)
- 純・対照損失と異常スコア(再構成なし)
- 8ベンチマークでの定量評価(affiliation / VUS / Range-AUC 含む)
- アブレーション:stop-gradient の役割、Forward Process の効果
- ハイパーパラメータ感度と計算コスト
前提・関連記事



設計思想:先行手法との違い
DCdetectorを正確に位置づけるために、まず時系列異常検知の主要設計を3つ並べて比較します。

出典: Y. Yang, C. Zhang, T. Zhou, Q. Wen, L. Sun “DCdetector: Dual Attention Contrastive Representation Learning for Time Series Anomaly Detection”, KDD 2023 (arXiv:2306.10347), Fig.1.
論文の Fig.1 は3種類の設計を1枚で対比しています。
- (a) 再構成ベース:表現ネットワークで正常パターンを学習し、再構成誤差を異常スコアにする。シンプルだが、異常まで再構成して覚えてしまう(over-fitting to anomaly)リスクがある。
- (b) Anomaly Transformer:2つの分布(学習した事前分布・ガウス核、それと自己注意の分布)を比較する。ミニマックス学習と再構成損失を組み合わせた設計で、ガウス核という事前知識が前提になる。
- (c) DCdetector:再構成なし、ガウス核なし、MinMax最適化なし。同じ入力を「2つの視点」で表現し、「表現の類似度(Representation Similarity)」だけを学習する。
この対比から分かるのは、DCdetectorが「引き算で作られた手法」だということです。余計な部品を一つずつ外して、「2つの見方の食い違いだけを見る」設計に絞り込んでいます。
では、この「2つの見方」がどう作られるか、内部の仕組みを追いましょう。
「2つの見方」という発想
DCdetectorの心臓部は「同じデータを2通りに見る」ことです。まず時系列の窓を、いくつかのパッチ(小区間)に区切ります。そのうえで、2つの注意(attention)をかけます。

- patch-wise(パッチ間)の見方:パッチ同士の関連を見ます。「窓全体がどんな形をしているか」という大局的・粗い視点です。
- in-patch(パッチ内)の見方:各パッチの中の点同士の関連を見ます。「細部がどう動いているか」という局所的・細かい視点です。
どちらも、同じ入力時系列に対する「関連の分布(どの点とどの点が関係しているか)」を表します。ポイントは、正常なデータなら、この2つの見方が同じ「正常パターン」に行き着いて一致すること。逆に異常なデータでは、大局の見方と局所の見方が食い違います。だから2つの見方の一致/不一致を測れば、異常が分かるのです。
ここで「2つの見方」は、普通の対照学習のように元データを水増し(augmentation)して作った2つのコピーではない点に注意してください。DCdetectorは、ひとつのデータを patch-wise と in-patch という構造の違う2経路に通して2つの見方を作ります。
なぜ食い違いで異常が分かるのか
直感はこうです。異常はまれで、正常な点は共通の潜在パターンを持っています。だから、同じ入力を2つの見方で表現したとき、正常点の2つの表現は似たものになるはずです。

正常点(左)では、patch-wise の見方と in-patch の見方の関連分布がほぼ重なります → 乖離(差)が小さい。異常点(右)では、2つの見方が別々の方向を指してしまう → 乖離が大きい。
この乖離をKLダイバージェンス(2つの分布の違いを測る量)で計算し、それをそのまま異常スコアにします。スコアが大きい点ほど異常、というわけです。再構成誤差を一切使わないのがミソで、訓練データに異常が混じっていても「再構成して覚えてしまう」悪影響を受けにくくなります。
では、この2つの見方を実際にどう作るのか。アーキテクチャ全体を見ましょう。
アーキテクチャ全体:4つのモジュール

出典: Y. Yang, C. Zhang, T. Zhou, Q. Wen, L. Sun “DCdetector”, KDD 2023 (arXiv:2306.10347), Fig.2.
DCdetectorは4つのモジュールでできています。
- Forward Process(前処理):入力を整える。インスタンス正規化 → チャネル独立化 → パッチ分割。
- Dual Attention Contrastive Structure(二重注意の対照構造):patch-wise と in-patch の2つの見方(表現)を作る心臓部。
- Representation Discrepancy(表現の乖離):2つの表現の差をKLで測る。
- Anomaly Criterion(異常基準):乖離を異常スコアにして、しきい値で判定。
最初の前処理で効いているのがチャネル独立化(channel independence)です。

出典: Y. Yang ら “DCdetector”, KDD 2023 (arXiv:2306.10347), Fig.3.
多変量時系列の各チャネル(センサー)をそれぞれ独立した1本の時系列として扱い、パッチに区切って、同じ自己注意ネットワークを共有して表現を作り、最後に結合します。こうすると、変量が増えてもネットワークが肥大せず、各チャネルの局所的な意味(パターン)をうまく捉えられます。
Forward Process の設計:インスタンス正規化とチャネル独立化が2つ揃う理由
Table 7(後述)のアブレーション結果が示すように、この前処理の2要素はどちらか1つでも外すと性能が落ちます。
インスタンス正規化は、窓ごとに平均・分散で正規化する操作です。バッチ正規化と違い、時系列の局所的なトレンド変動に頑健で、異なる時間帯でスケールが大きく変わるセンサーデータを揃えます。
チャネル独立化は、変量間の相関をネットワーク側で「モデル化しない」という判断です。多変量の相関を直接学習させると、訓練データのノイズや偶発的な相関をそのまま覚えてしまうリスクがあります。代わりに「各チャネルの時間パターン」を同じ重みで学習することで、汎化しやすい特徴を得ます。
二重注意:2つの見方を計算する
心臓部の Dual Attention を、もう少し具体的に見ます。窓をパッチに分けたあと、
- in-patch attention:各パッチの中で、点同士の自己注意を計算(局所の見方)。
- patch-wise attention:パッチを単位として、パッチ同士の自己注意を計算(大局の見方)。
記号と次元の定義
再実装に必要な記号を先に整理します。
| 記号 | 意味 | 形状 |
|---|---|---|
| $T$ | 窓(入力系列)の長さ | — |
| $d$ | 変量数(センサー数) | — |
| $P$ | パッチサイズ(各パッチの点数) | — |
| $N$ | パッチ数($N = T / P$) | — |
| $d_{model}$ | 埋め込み次元(デフォルト 256) | — |
| $H$ | 注意ヘッド数(デフォルト 1) | — |
| $L$ | エンコーダ層数(デフォルト 3) | — |
| $X$ | 入力多変量時系列 | $\mathbb{R}^{T \times d}$ |
| $X_i$ | チャネル独立化後の1チャネル | $\mathbb{R}^{T \times 1}$ |
| $X$ (パッチ後) | パッチ分割後 | $\mathbb{R}^{P \times N \times d}$ |
| $\mathcal{X}$ (バッチ融合後) | $d$ をバッチ次元に畳んだ行列 | $\mathbb{R}^{P \times N}$ |
| $\mathcal{X}_\mathcal{N}$ | patch-wise 埋め込み後 | $\mathbb{R}^{N \times d_{model}}$ |
| $\mathcal{X}_\mathcal{P}$ | in-patch 埋め込み後 | $\mathbb{R}^{P \times d_{model}}$ |
| $Q_{\mathcal{N}i}, K_{\mathcal{N}i}$ | patch-wise のクエリ・キー($i$ 番ヘッド) | $\mathbb{R}^{N \times (d_{model}/H)}$ |
| $Q_{\mathcal{P}i}, K_{\mathcal{P}i}$ | in-patch のクエリ・キー($i$ 番ヘッド) | $\mathbb{R}^{P \times (d_{model}/H)}$ |
| $W_{Qi}, W_{Ki}$ | Q・K の射影行列(共有) | $\mathbb{R}^{(d_{model}/H) \times (d_{model}/H)}$ |
| $W^\mathcal{O}_\mathcal{N}, W^\mathcal{O}_\mathcal{P}$ | マルチヘッド出力射影行列 | $\mathbb{R}^{d_{model} \times d_{model}}$ |
| $\mathit{Attn}_{\mathcal{N}i}$ | patch-wise 注意重み($i$ 番ヘッド) | $\mathbb{R}^{N \times N}$ |
| $\mathit{Attn}_\mathcal{N}$ | マルチヘッド結合後の patch-wise 表現 | $\mathbb{R}^{N \times d_{model}}$ |
| $\mathit{Attn}_{\mathcal{P}i}$ | in-patch 注意重み($i$ 番ヘッド) | $\mathbb{R}^{P \times P}$ |
| $\mathit{Attn}_\mathcal{P}$ | マルチヘッド結合後の in-patch 表現 | $\mathbb{R}^{P \times d_{model}}$ |
| $\mathcal{N}$ | アップサンプリング後の patch-wise 表現 | $\mathbb{R}^{T \times d_{model}}$ |
| $\mathcal{P}$ | アップサンプリング後の in-patch 表現 | $\mathbb{R}^{T \times d_{model}}$ |
| $X’_i$ | 1チャネルの最終表現 | $\mathbb{R}^{N \times 1}$ |
| $X’$ | 全チャネル結合後の最終表現 | $\mathbb{R}^{N \times d}$ |
| $\delta$ | 異常判定しきい値(デフォルト 1) | — |
チャネル独立化の詳細: 入力 $X \in \mathbb{R}^{T \times d}$ の各チャネル $X_i \in \mathbb{R}^{T \times 1}$($i=1,\ldots,d$)を1本の時系列として扱い、パッチ分割・自己注意・アップサンプリングを行う。各チャネルで同一のネットワーク重みを共有し、最終表現 $X’_i \in \mathbb{R}^{N \times 1}$ を全チャネルで結合して $X’ \in \mathbb{R}^{N \times d}$ を得る(Figure 3)。変量が増えてもネットワークが肥大しない利点がある。
2つの注意の「埋め込みの向き」が違う
パッチ分割後に変量次元 $d$ をバッチに融合すると、形状は $\mathbb{R}^{P \times N}$ になります。この行列に対して、2つの注意は埋め込みをかける軸を変えるだけで作られます(論文 Section 3.2.1)。
- patch-wise:パッチサイズ $P$ の軸を線形変換して $\mathcal{X}_\mathcal{N} \in \mathbb{R}^{N \times d_{model}}$ を作る。つまり「各パッチを1個のトークン」とみなし、$N$ 個のパッチ同士で自己注意を計算する。
- in-patch:パッチ数 $N$ の軸を線形変換して $\mathcal{X}_\mathcal{P} \in \mathbb{R}^{P \times d_{model}}$ を作る。つまり「パッチ内の $P$ 個の点」同士で自己注意を計算する。
どちらもマルチヘッドの自己注意で、クエリ・キーから注意重みを計算します(バリュー $V$ は使いません。欲しいのは値の変換結果ではなく関連の分布そのものだからです)。
patch-wise の計算(式 1–3):
まずクエリとキーを初期化します($i$ 番ヘッド, $1 \le i \le H$)。
$$ \begin{equation} Q_{\mathcal{N}i},\, K_{\mathcal{N}i} = W_{Qi}\mathcal{X}_{\mathcal{N}i},\; W_{Ki}\mathcal{X}_{\mathcal{N}i} \end{equation} $$
次に、スケール付き内積で注意重みを計算します(スケール因子は $\sqrt{d_{model}/H}$)。
$$ \begin{equation} \mathit{Attn}_{\mathcal{N}i} = \mathrm{Softmax}\!\left(\frac{Q_{\mathcal{N}i}\,K_{\mathcal{N}i}^{\top}}{\sqrt{d_{model}/H}}\right) \in \mathbb{R}^{N \times N} \end{equation} $$
全ヘッドを結合し、出力射影行列 $W^\mathcal{O}_\mathcal{N} \in \mathbb{R}^{d_{model} \times d_{model}}$ で変換します。
$$ \begin{equation} \mathit{Attn}_\mathcal{N} = \mathrm{Concat}\!\left(\mathit{Attn}_{\mathcal{N}1},\,\ldots,\,\mathit{Attn}_{\mathcal{N}H}\right) W^\mathcal{O}_\mathcal{N} \in \mathbb{R}^{N \times d_{model}} \end{equation} $$
in-patch の計算(式 4–6): 入力を $\mathcal{X}_\mathcal{P} \in \mathbb{R}^{P \times d_{model}}$ に変換し、全く同様の手順でクエリ・キーを作ります。
$$ \begin{equation} Q_{\mathcal{P}i},\, K_{\mathcal{P}i} = W_{Qi}\mathcal{X}_{\mathcal{P}i},\; W_{Ki}\mathcal{X}_{\mathcal{P}i} \end{equation} $$
$$ \begin{equation} \mathit{Attn}_{\mathcal{P}i} = \mathrm{Softmax}\!\left(\frac{Q_{\mathcal{P}i}\,K_{\mathcal{P}i}^{\top}}{\sqrt{d_{model}/H}}\right) \in \mathbb{R}^{P \times P} \end{equation} $$
$$ \begin{equation} \mathit{Attn}_\mathcal{P} = \mathrm{Concat}\!\left(\mathit{Attn}_{\mathcal{P}1},\,\ldots,\,\mathit{Attn}_{\mathcal{P}H}\right) W^\mathcal{O}_\mathcal{P} \in \mathbb{R}^{P \times d_{model}} \end{equation} $$
ここで重み共有が核心です。patch-wise と in-patch の注意ネットワークは、クエリ・キーの射影行列 $W_{Qi}, W_{Ki}$(および出力射影)を完全に共有します。同じ重みを「パッチ間で見るか/パッチ内で見るか」という入力の組み替えだけで2つの見方を作る——だから「2つの見方の食い違い」は、データの構造そのものから来る違いであって、別々のネットワークが勝手に作った差ではありません。これが後で効いてきます。
アップサンプリング:2つの見方を同じ土俵に乗せる(式 7)
難点が1つあります。patch-wise の注意行列は $N \times N$ のパッチ間関連しか持たず、in-patch の注意行列は $P \times P$ のパッチ内関連しか持ちません。サイズも意味も違うので、このままでは点ごとの KL が計算できません。そこで、両方を元の点の解像度($T$ 点)にアップサンプリングして揃えます(論文 Section 3.2.2, Fig.4)。

出典: Y. Yang ら “DCdetector”, KDD 2023 (arXiv:2306.10347), Fig.4.
- patch-wise 側(patch → points):$N \times N$ のパッチ間関連を、各パッチに属する $P$ 点へコピー展開する($P_1, P_2, P_3$ の関連を、それぞれのパッチ内の全点へ繰り返す)。結果は $T \times T$ の注意行列になる。
- in-patch 側(points → patches):1パッチ内の $P \times P$ 関連を、$N$ パッチぶん繰り返す($p_1,\ldots,p_5$ の関連パターンを全パッチに敷き詰める)。結果は同じく $T \times T$ になる。
式で書くと(式 7):
$$ \begin{equation} \mathcal{N} = \mathrm{Upsampling}(\mathit{Attn}_\mathcal{N}), \qquad \mathcal{P} = \mathrm{Upsampling}(\mathit{Attn}_\mathcal{P}) \end{equation} $$
こうして patch-wise 表現 $\mathcal{N}$ と in-patch 表現 $\mathcal{P}$ が、同じ点解像度 $T$ で得られ、点ごとの乖離を計算できます。本記事の最小実装コードで repeat_interleave を使ってブロック展開しているのは、まさにこのアップサンプリングに相当します。
情報損失への対処(マルチスケール):パッチに区切る以上、アップサンプリングは必ず情報の損失を伴います(細部をパッチ代表で丸めてしまう)。DCdetectorはこれを複数のパッチサイズで並列に計算して補います。あらかじめパッチサイズのリスト(例:$[3,5]$)を決め、各サイズで二重注意とアップサンプリングを行い、結果を加算して最終の $\mathcal{N}$ と $\mathcal{P}$ を得ます。後で見る感度分析(Fig.6(b))では、単一パッチサイズより複数サイズを組み合わせたほうが F1 が伸びることが実際に確認できます。
骨子をコードで見るとはっきりします。次は2つの見方(注意マップ)を作り、点ごとの乖離をKLで測る部分の最小実装です。
import torch, torch.nn as nn, torch.nn.functional as F
W, P, d = 60, 10, 32 # 窓長・パッチサイズ・埋め込み次元
N = W // P # パッチ数
x = torch.randn(4, W, d) # 埋め込み済みの窓 (バッチ4)
# in-patch attention:各パッチ「内」で自己注意
hp = x.view(4, N, P, d)
Ain = torch.softmax(hp @ hp.transpose(-1,-2) / d**0.5, -1) # (4,N,P,P)
# patch-wise attention:パッチ「同士」で自己注意(パッチを平均プールして1トークンに)
tok = hp.mean(2) # (4,N,d) パッチ代表
Apw = torch.softmax(tok @ tok.transpose(-1,-2) / d**0.5, -1) # (4,N,N)
# 2つの見方を点レベル(W×W)の関連分布に展開
inpatch = torch.zeros(4, W, W) + 1e-6
for n in range(N):
inpatch[:, n*P:(n+1)*P, n*P:(n+1)*P] = Ain[:, n] # パッチ内ブロック
inpatch = inpatch / inpatch.sum(-1, keepdim=True)
patchwise = Apw.repeat_interleave(P,1).repeat_interleave(P,2) / P # パッチ間→点へ展開
patchwise = patchwise / patchwise.sum(-1, keepdim=True)
# 点ごとの乖離(対称KL) = 異常スコアの素
def sym_kl(A, B):
A = A.clamp_min(1e-8); B = B.clamp_min(1e-8)
return (A*(A.log()-B.log())).sum(-1) + (B*(B.log()-A.log())).sum(-1)
discrepancy = sym_kl(inpatch, patchwise) # (4, W) 各点の乖離
print(discrepancy.shape) # torch.Size([4, 60])
上記コードの discrepancy(形状 [4, 60])が、各時刻点における patch-wise と in-patch の「見方の食い違い」を数値化したものです。正常な点ではこの値が小さく、異常な点では大きくなる、それが DCdetector の異常スコアの素になります。
純・対照損失(再構成なし)
学習は2つの見方の表現を似せるだけ。再構成も負例も使いません。in-patch 表現 $\mathcal{P}$ と patch-wise 表現 $\mathcal{N}$ の間の対称KLを損失にします(論文 Section 3.3, 式 8–10)。
$\mathrm{Stopgrad}(\cdot)$ は引数を定数として扱う操作で、片方の経路に勾配を流さず、2経路を非同期に学習させます。
まず $\mathcal{P}$ 側の損失(in-patch 経路を主役に、patch-wise を固定)を定義します(式 8):
$$ \begin{equation} \mathcal{L}_{\mathcal{P}}\{\mathcal{P}, \mathcal{N}; X\} = \sum \big[\mathrm{KL}(\mathcal{P},\, \mathrm{Stopgrad}(\mathcal{N})) + \mathrm{KL}(\mathrm{Stopgrad}(\mathcal{N}),\, \mathcal{P})\big] \end{equation} $$
次に $\mathcal{N}$ 側の損失(patch-wise 経路を主役に、in-patch を固定)を定義します(式 9):
$$ \begin{equation} \mathcal{L}_{\mathcal{N}}\{\mathcal{P}, \mathcal{N}; X\} = \sum \big[\mathrm{KL}(\mathcal{N},\, \mathrm{Stopgrad}(\mathcal{P})) + \mathrm{KL}(\mathrm{Stopgrad}(\mathcal{P}),\, \mathcal{N})\big] \end{equation} $$
全体の損失は両者の差を $\mathrm{len}(\mathcal{N})$(バッチあたりのトークン数)で正規化します(式 10):
$$ \begin{equation} \mathcal{L} = \frac{\mathcal{L}_{\mathcal{N}} – \mathcal{L}_{\mathcal{P}}}{\mathrm{len}(\mathcal{N})} \end{equation} $$
なぜ差($\mathcal{L}_\mathcal{N} – \mathcal{L}_\mathcal{P}$)なのか:$\mathcal{L}_\mathcal{N}$ は patch-wise 経路($\mathcal{N}$)を in-patch($\mathcal{P}$)に近づける損失、$\mathcal{L}_\mathcal{P}$ は in-patch 経路($\mathcal{P}$)を patch-wise($\mathcal{N}$)に近づける損失です。差を取ることで、2経路が互いを「引き寄せる」勾配だけが有効になり、一方が他方を一方的に引きずる形の不安定な更新が抑制されます。正常データに対して2つの見方が一致するように最適化される点は両損失項で共通です。
なぜ崩壊しないのか(非対称性の効き目)
ここで普通は心配になります——「負例なしで2つの見方を似せるだけだと、両方が同じ定数ベクトルに潰れる(モデル崩壊)のでは?」。SimSiam では、この崩壊を防ぐ主役が stop-gradient だとされていました。
ところがDCdetectorは、stop-gradient を外しても崩壊しないことが報告されています(後述のアブレーションで実測)。理由は2つの経路が完全に非対称だからです。論文の議論をなぞると、ある経路の出力 $Z$ を、表現空間全体での平均(中心ベクトル)$o = \mathbb{E}[Z]$ と残差 $r$ に分けて $Z = o + r$ と書きます。崩壊とは、すべての $Z$ が中心 $o$ に潰れて $o$ が支配的になる状態です。
2つの経路を $Z_p = o_p + r_p$、$Z_n = o_n + r_n$ とすると、もし経路が対称($o_p = o_n$)なら、両者の差は $Z_p – Z_n = r_p – r_n$ になります。$r_p$ と $r_n$ は同じ入力から来るので似てしまい、差が消える=崩壊に向かいます。SimSiam が stop-gradient を要したのはこのためです。
DCdetectorの2経路は、入力の組み替え(パッチ間 vs パッチ内)からして別物で $o_p \neq o_n$ なので、$r_p$ と $r_n$ が似ても差がゼロにならない。非対称性そのものが崩壊を防ぐ安全装置になっているわけです。stop-gradient は「無いと崩壊する必須部品」ではなく「あると性能がもう一段上がる補助」という位置づけになります。これも「引き算の設計」が効いている点です。
異常スコアと判定
異常スコア(式 11)
学習後、点ごとの異常スコアは、2つの見方の乖離そのものです(論文 Section 3.4, 式 11)。
$$ \begin{equation} \mathrm{AnomalyScore}(X) = \sum \big[\mathrm{KL}(\mathcal{P},\, \mathrm{Stopgrad}(\mathcal{N})) + \mathrm{KL}(\mathcal{N},\, \mathrm{Stopgrad}(\mathcal{P}))\big] \end{equation} $$
論文の式 11 には Stopgrad が明記されていますが、推論時は勾配が流れない(パラメータ更新がない)ため、実質的に $\mathcal{N}$ と $\mathcal{P}$ の対称KLと等価です。$\sum$ はマルチスケールの各パッチサイズ・各エンコーダ層にわたる和を表します。
正常点は2つの見方が一致するのでスコアが小さく、異常点は食い違うのでスコアが大きくなります。これは点ごとのスコア(point-wise)であり、各時刻 $t$ に1つのスコア値が付きます。
判定ルール(式 12)
しきい値 $\delta$(デフォルト 1)と比較してラベルを決めます(式 12):
$$ \begin{equation} Y_i = \begin{cases} 1 & \text{(anomaly)} \quad \mathrm{AnomalyScore}(X_i) \ge \delta \\ 0 & \text{(normal)} \quad \mathrm{AnomalyScore}(X_i) < \delta \end{cases} \end{equation} $$
しきい値 $\delta$ は検証セットで F1 が最大になるよう選ぶか、固定値を使います。再構成誤差と違い、スコアの絶対スケールは損失関数の構成(KL の総和)に依存するため、データセットごとにチューニングする場合があります。
Anomaly Transformer との違い
「2つの分布の差で異常を見る」という発想は、Anomaly Transformer と共通です。違いは、DCdetectorが余計な部品を引き算したことにあります。

Anomaly Transformerは「ガウス核の事前(prior)」と「再構成損失+minimax」を組み合わせる、やや複雑な設計でした。DCdetectorは、2つの見方をどちらも学習で作り、純粋な対照損失だけで学習し、事前知識も再構成も負例も使いません。シンプルなぶん、未知の異常にも対応しやすく、設計の見通しが良いのが利点です。
比較軸をまとめると以下の通りです。
| 項目 | Anomaly Transformer | DCdetector |
|---|---|---|
| 2つの分布 | 事前(ガウス核) vs 自己注意 | patch-wise vs in-patch |
| 事前知識 | ガウス核(locality仮定) | なし |
| 損失 | 再構成 + minimax | 純・対照損失のみ |
| 崩壊防止 | stop-gradient(必須) | 非対称2経路(構造的に防ぐ) |
| バリュー $V$ | 使用 | 不使用(関連分布のみ) |
Anomaly Transformer は「ガウス核で正常点の局所性を仮定し、それとの乖離を異常の合図にする」設計です。DCdetectorはそのガウス核すら学習に委ねた、より純粋な対照学習アプローチといえます。
評価
デフォルトハイパーパラメータ
論文が報告した実装詳細(Section 4.3)をまとめます。再実装の基準点として参考にしてください。
| ハイパーパラメータ | デフォルト値 | 備考 |
|---|---|---|
| エンコーダ層数 $L$ | 3 | — |
| 埋め込み次元 $d_{model}$ | 256 | 性能・計算量のトレードオフで選択 |
| 注意ヘッド数 $H$ | 1 | シンプルさを重視 |
| マルチスケールパッチ | データセット依存(例: $[3,5]$) | Table 8(付録)参照 |
| 窓サイズ | データセット依存(60 または 100) | — |
| 異常しきい値 $\delta$ | 1 | — |
| 学習率 | $10^{-4}$(Adam, デフォルト設定) | — |
| バッチサイズ | 128 | — |
| エポック数 | 3 | — |
| GPU | NVIDIA Tesla-V100 32GB | — |
8ベンチマークの概要
DCdetectorは、5つの実応用にまたがる8つのベンチマークで評価されています。
| データセット | 由来 | 変量数 | 異常率 | 特徴 |
|---|---|---|---|---|
| SMD | サーバ監視 | 38 | 4.2% | 多変量、産業データ |
| MSL | NASA 火星探査機 | 55 | 10.7% | センサー異常 |
| SMAP | NASA 土壌水分 | 25 | 13.1% | テレメトリ |
| SWaT | 水処理制御 | 51 | 12.0% | サイバー攻撃ラベル |
| PSM | eBay サーバ | 25 | 27.7% | 多様な異常タイプ |
| NIPS-TS-SWAN | 宇宙天気 | 1 | 多種 | 多タイプ異常 |
| NIPS-TS-GECCO | 水質モニタ | 1 | 多種 | 複雑なラベル |
| UCR | UCR アーカイブ | 1 | – | 単変量250種 |
これだけ多様な応用と変量規模を8セットでまとめてカバーしていることが、評価の信頼性を高めています。
主要結果:Table 1 (point-adjust F1)

出典: Y. Yang ら “DCdetector”, KDD 2023 (arXiv:2306.10347), Table 1.
Table 1 は5つの多変量データセット(SMD/MSL/SMAP/SWaT/PSM)でのスコアです。比較対象は LOF・OCSVM・U-Time・IForest・ITAD・NPSR・CL-MPPCA・TS-CP2・Deep-SVDD・BOCPD・LSTM-VAE・BeatGAN・LSTM・OmniAnomaly・InterFusion・THOC・Anomaly Transformer という19手法。DCdetectorは PSM で F1 97.14%(先端水準)、SMD・SWaT でも Anomaly Transformer を上回っています。
ただし、この F1 は point-adjust 評価であることに注意が必要です。point-adjust は「異常区間の中に1点でもスコアが閾値を超えれば、区間全体を正解とみなす」緩い評価法で、ランダム検出器でも高スコアになりやすいという問題があります(詳しくは時系列異常検知サーベイ、VUS 記事を参照)。
多指標評価:Table 2(affiliation / VUS / Range-AUC)

出典: Y. Yang ら “DCdetector”, KDD 2023 (arXiv:2306.10347), Table 2.
Table 2 は affiliation(Aff-P / Aff-R)、Range-AUC-ROC(R_A_R)、Range-AUC-PR(R_A_P)、VUS-ROC(V_ROC)、VUS-PR(V_PR)という点調整に依存しない指標での比較です。
Anomaly Transformer との比較で注目すべき点として、MSL では:
- Acc: Anomaly Transformer 98.69 vs DCdetector 99.06
- F1 (point-adjust): Anomaly Transformer 93.93 vs DCdetector 96.60
- Aff-P / Aff-R: Anomaly Transformer 51.76 / 95.98 vs DCdetector 51.84 / 97.39
- V_ROC: Anomaly Transformer 88.20 vs DCdetector 93.15
- V_PR: Anomaly Transformer 86.26 vs DCdetector 91.66
また SMAP での V_ROC / V_PR では、Anomaly Transformer が 95.52 / 93.37、DCdetector が 95.19 / 93.46 とほぼ拮抗しています。PSM では Aff-P / R で Anomaly Transformer が 55.35 / 80.28、DCdetector が 54.71 / 82.93 と逆転する指標もあります。
VUS 指標では両者が拮抗または逆転する場面もあり、point-adjust F1 だけで単純に優劣をつけられない複雑さがあります。DCdetectorが複数の指標で報告した点——これ自体が、評価の透明性に対する著者の配慮として評価できます。
スコアを「目で見る」:5種類の異常での挙動
数字の表だけでは、何が起きているか掴みにくいものです。論文は合成データで、5種類の代表的な異常に対する異常スコアを可視化しています。

出典: Y. Yang ら “DCdetector”, KDD 2023 (arXiv:2306.10347), Fig.5.
上段が入力時系列(赤帯が真の異常区間)、中段が Anomaly Transformer の異常スコア、下段が DCdetector の異常スコアです。Global Point(大局的な外れ点)・Contextual Point(文脈的な外れ点)・Seasonal(季節性の乱れ)・Group Point(群異常)・Trend(トレンドの変化)という質の違う5種類すべてで、DCdetectorのスコア(下段)が異常区間でくっきり跳ね上がり、正常区間では平坦に保たれているのが読み取れます。
特に Contextual Point と Seasonal の列では、Anomaly Transformer のスコア(中段)が正常区間でも高めに揺れているのに対し、DCdetectorのスコアは正常区間でより低く安定しています。再構成も事前知識も使わず「2つの見方の乖離」だけで、これだけ多様な異常に反応できるのが要点です。
アブレーション:stop-gradient と Forward Process
stop-gradient は「必須」ではなく「効く」
先ほどの「非対称性が崩壊を防ぐ」という主張は、アブレーション(Table 6)で実測できます。patch-wise / in-patch それぞれの経路で stop-gradient を入れる・入れないを切り替えた MSL/SMAP/PSM の F1 は次の通りです。
| Patch-wise の stop-grad | In-patch の stop-grad | MSL F1 (%) | SMAP F1 (%) | PSM F1 (%) |
|---|---|---|---|---|
| なし | なし | 90.97 | 95.51 | 97.18 |
| あり | なし | 80.88 | 93.81 | 97.83 |
| なし | あり | 94.18 | 96.24 | 97.51 |
| あり | あり | 96.60 | 97.02 | 97.94 |
両方とも stop-gradient なし(最上段)でも MSL F1 = 90.97% と崩壊せず実用的——これが「非対称性そのものが崩壊を防ぐ」ことの裏付けです。一方で、両方に stop-gradient を入れると MSL で 96.60% まで伸びる。つまり stop-gradient は崩壊回避のための必須部品ではなく、2経路を非同期に学習させて性能を底上げする補助だと分かります。
「in-patch のみ stop-grad あり(MSL: 94.18%)」が「patch-wise のみ(MSL: 80.88%)」より大幅に高い点も興味深く、in-patch 経路(局所視点)のほうがより安定的な基準として機能していることが示唆されます。
Forward Process の効果(Table 7)
インスタンス正規化(Bilateral Filter / Instance Norm)を外した場合の影響も表に示されています(Table 7)。
| Bilateral Filter | Instance Norm | MSL F1 (%) | SMAP F1 (%) | PSM F1 (%) |
|---|---|---|---|---|
| なし | なし | 94.59 | 96.00 | 97.40 |
| あり | なし | 95.59 | 96.44 | 97.77 |
| なし | あり | 96.60 | 97.02 | 97.94 |
| あり | あり | 95.44 | 96.08 | 97.35 |
結果としてインスタンス正規化あり・バイラテラルフィルタなしが最良(MSL: 96.60%)です。インスタンス正規化は明確な改善をもたらす一方、バイラテラルフィルタ(時間方向のスムージング)とインスタンス正規化を両方使うと(最終行)、どちらか単独より性能が落ちます。過剰な平滑化が「2つの見方の食い違い」で検出したかった異常を均してしまうリスクがあるためと考えられます。最終的な DCdetector はインスタンス正規化のみを前処理に採用しています。
ハイパーパラメータ感度と計算コスト
感度分析(Fig.6)

出典: Y. Yang ら “DCdetector”, KDD 2023 (arXiv:2306.10347), Fig.6.
5つのハイパーパラメータに対する F1 の感度を見ます。
- (a) 窓サイズ:30〜210 の広い範囲で F1 がほぼ平坦(MSL/PSM)。範囲 [45, 195] での変動は 2.3% 未満。窓サイズ選びにシビアでないことが分かります。
- (b) マルチスケールパッチ:単一パッチサイズ($[1]$ や $[3]$)より $[1,3]$ や $[3,5]$ のように複数を組み合わせたほうが F1 が上がります。マルチスケールがアップサンプリングの情報損失を補う設計の効果が明確に出ています。
- (c) エンコーダ層数:1〜5 の範囲で性能変化は比較的緩やか。
- (d) 注意ヘッド数:2〜8 の範囲で安定。
- (e) $d_{model}$:128〜1024 でも大きな変動なし。
全体として、DCdetectorはハイパーパラメータ調整に過度に依存しないことが読み取れます。マルチスケール設計((b))だけは組み合わせの効果が明確なため、実装時には $[3,5]$ 程度の複数パッチサイズを初期値として選ぶことが推奨されます。
計算コスト(Fig.7)

出典: Y. Yang ら “DCdetector”, KDD 2023 (arXiv:2306.10347), Fig.7.
$d_{model}$ を 128〜1024 と変えたときの GPU メモリ(左)と100イテレーション平均実行時間(右)を示します。$d_{model} = 128$ の軽量設定では GPU メモリ約 0.2 GB・時間約 0.1 秒と非常に低コスト。$d_{model} = 512$ 相当でもメモリ 0.5〜0.6 GB 程度に収まり、大規模データセットへの適用が現実的です。
再構成ネットワークと比べてデコーダが不要な分、計算コストが小さい。これも「引き算の設計」がもたらす副産物です。
まとめ
DCdetectorの骨子を、できるだけ平易に追いました。
- 発想:同じ時系列を patch-wise(大局)と in-patch(局所)の2つの見方で見る
- 設計の差別化:再構成なし・ガウス核なし・MinMax不要(Fig.1で先行手法と対比)
- 異常の合図:正常点は2つの見方が一致(乖離小)、異常点は食い違う(乖離大)
- アーキ:前処理(チャネル独立+パッチ)→ 二重注意(重み共有)→ マルチスケール → 表現乖離(KL)→ 異常基準
- 学習:純・対照損失のみ。非対称な2経路が構造的に崩壊を防ぐ。stop-gradient は補助(必須ではない)
- スコア:2つの見方の対称KLが大きい点を異常とする
- 評価:point-adjust F1 に加え、affiliation・VUS・Range-AUC という指標非依存の評価でも報告
- 頑健性:ハイパーパラメータ感度が低く、計算コストも小さい
「複雑な部品を足す」のではなく「2つの見方の食い違いだけを見る」という引き算の設計が、DCdetectorの分かりやすさと強さの源です。コードは github.com/DAMO-DI-ML/KDD2023-DCdetector で公開されています。






参考文献
- Y. Yang, C. Zhang, T. Zhou, Q. Wen, L. Sun. “DCdetector: Dual Attention Contrastive Representation Learning for Time Series Anomaly Detection.” KDD 2023 (arXiv:2306.10347). コード: github.com/DAMO-DI-ML/KDD2023-DCdetector
- X. Chen, K. He. “Exploring Simple Siamese Representation Learning (SimSiam).” CVPR 2021(負例なし対照学習の崩壊と stop-gradient)
- J. Xu, H. Wu, J. Wang, M. Long. “Anomaly Transformer: Time Series Anomaly Detection with Association Discrepancy.” ICLR 2022(DCdetectorと対比される先行手法)
- J. Paparrizos, P. Boniol, T. Palpanas, R. Tsay, A. Elmore, M. Franklin. “Volume Under the Surface: A New Accuracy Evaluation Measure for Time-Series Anomaly Detection.” VLDB 2022(VUS指標)
- J. Huet, N. Navarro, D. Rossi. “Local Evaluation of Time Series Anomaly Detection Algorithms.” KDD 2022(affiliation指標)