[2203.10807] ViM: Out-Of-Distribution with Virtual-logit Matching (arxiv.org)
DNNの重みとバイアスを利用して固有値分解時の平均を除去する効果を狙った(と思われる)所がこの手法の勘所でしょうか。イマイチすっきりしません。
分散共分散行列を作成するのに GPU から CPUに戻しています。sklearn を使用しているので時間がかかるのが難点です。
以下、主要部分です。
特徴量の固有ベクトルを求める。
-> バイアスを取り除いた特徴量を作成する。
-> 特徴量の原点を計算。
固有値分解は分散共分散行列を利用。
from sklearn.covariance import EmpiricalCovariance
print('computing principal space...')
ec = EmpiricalCovariance(assume_centered=True)
ec.fit(feature_id_train - u)
eig_vals, eigen_vectors = np.linalg.eig(ec.covariance_)
NS = np.ascontiguousarray(
(eigen_vectors.T[np.argsort(eig_vals * -1)[DIM:]]).T)
残差||xPT||を固有ベクトルへの射影時の離れ具合とみなし、OOD検出に利用している。残差が最大のロジットと比較して非常に小さい場合、SoftMaxでロジットのノイズに埋もれてしまう。スケールを補正するために、α=最大ロジットの平均/残差の平均を求める。
print('computing alpha...')
vlogit_id_train = norm(np.matmul(feature_id_train - u, NS), axis=-1)
alpha = logit_id_train.max(axis=-1).mean() / vlogit_id_train.mean()
vlogit_ood = norm(np.matmul(feature_ood - u, NS), axis=-1) * alpha
0 件のコメント:
コメントを投稿