Vision Transformers(ViT)についてのアニメーションを作成した経験をシェアします。映像処理に使われるモデルの一つで、従来のニューラルネットワークとは異なり、自然言語処理で使われるアーキテクチャを用いています。モデルのパフォーマンスを最適化するためのファインチューニングは複雑です。

前の記事で、PCA(主成分分析)を用いて、ファインチューニング中の埋め込みの変化をアニメーションで示しました。これらの埋め込みは、ファインチューニングの様々な段階とそれに対応するチェックポイントから生成されました。

このアニメーションは20万以上のインプレッションを獲得し、多くの読者がその作成方法に興味を持ちました。この記事は、興味のある読者や同様の可視化を作成したい人々の支援を目的としています。

この記事では、そのようなアニメーションを作成するための包括的なガイドを提供し、ファインチューニング、埋め込みの生成、アウトライヤーの検出、PCA、Procrustes分析、レビュー、アニメーションの作成に関連するステップを詳述します。

アニメーションの完全なコードも、GitHub上の同梱されているノートブックにもあります。

準備:ファインチューニング

最初のステップは、事前にトレーニングされたgoogle/vit-base-patch16–224-in21k Vision Transformer(ViT)モデルをファインチューニングすることです。CIFAR-10データセットを使用します。これには、10種類のクラスに分類された60,000の画像が含まれています。

Hugging Faceのチュートリアルに従い、CIFAR-10用のファインチューニングプロセスを実行することもできます。加えて、TrainerCallbackを使って、トレーニング中の損失値をCSVファイルに保存し、後でアニメーションで使用します。

from transformers import TrainerCallback

class PrinterCallback(TrainerCallback):
    def on_log(self, args, state, control, logs=None, **kwargs):
        _ = logs.pop("total_flos", None)
        if state.is_local_process_zero:
            if len(logs) == 3:  # skip last row
                with open("log.csv", "a") as f:
                    f.write(",".join(map(str, logs.values())) + "\n")

アニメーション用のチェックポイントを十分に確保するために、TrainingArgumentsでsave_strategy="step"と低い値のsave_stepを設定して、チェックポイントの保存間隔を増やすことが重要です。アニメーションの各フレームは、1つのチェックポイントに対応しています。トレーニング中に、各チェックポイントのフォルダとCSVファイルが作成され、次の手順に備えて準備されます。

埋め込みの生成

TransformersライブラリのAutoFeatureExtractorとAutoModelを使用して、CIFAR-10データセットのテスト分割から、異なるモデルチェックポイントを使用して埋め込みを生成します。

それぞれの埋め込みは、1つのチェックポイントに対して10,000のテスト画像のうちの1つを表す768次元のベクトルです。これらの埋め込みは、チェックポイントと同じフォルダに保存され、良い概要を維持します。

アウトライヤーの抽出

Cleanlabライブラリに提供されているOutOfDistributionクラスを使用して、各チェックポイントに基づいて埋め込みからアウトライヤーを特定することができます。結果として得られるスコアを使って、アニメーションのための上位10のアウトライヤーを特定できます。

from cleanlab.outlier import OutOfDistribution


def get_ood(sorted_checkpoint_folder, df):

  ...

  ood = OutOfDistribution()

  ood_train_feature_scores = ood.fit_score(features=embedding_np)

  df["scores"] = ood_train_feature_scores

PCAとProcrustes分析の適用

scikit-learnパッケージの主成分分析(PCA)を使用して、768次元ベクトルを2次元に削減し、2D空間で埋め込みを視覚化します。各タイムステップでPCAを再計算すると、軸の反転や回転によるアニメーション内の大きなジャンプが発生することがあります。この問題に対処するために、Procrustes分析を追加適用し、各フレームを最後のフレームに幾何学的に変換します。これには、移動、回転、そして均一なスケーリングのみが含まれます。これにより、アニメーションの滑らかな遷移が可能になります。

from sklearn.decomposition import PCA
from scipy.spatial import procrustes

def make_pca(sorted_checkpoint_folder, pca_np):

  ...

  embedding_np_flat = embedding_np.reshape(-1, 768)
  pca = PCA(n_components=2)
  pca_np_new = pca.fit_transform(embedding_np_flat)
  _, pca_np_new, disparity = procrustes(pca_np, pca_np_new)

Spotlightでのレビュー

アニメーション全体を最終化する前に、Spotlightでレビューを行います。この過程では、最初と最後のチェックポイントを使用して、埋め込みの生成、PCA、およびアウトライヤーの検出を実施します。そして、結果のDataFrameをSpotlightに読み込みます。

Spotlightは、データセットに存在するすべてのフィールドを示す包括的な表を左上に提供します。右上には2つのPCA表現が表示され、1つは最初のチェックポイントを使用して生成された埋め込み用、もう1つは最後のチェックポイント用です。最後に、下部には選択された画像が表示されます。

免責事項:この記事の著者は、Spotlinlightの開発者の一人です。

アニメーションの作成

各チェックポイントについて、対応するチェックポイントと一緒に保存される画像を作成します。これは、make_pca(...)関数とget_ood(...)関数を使用して得られた2Dポイントをプロットし、それぞれのクラスに対応する色で表現します。アウトライヤーはそのスコアに基づいてソートされ、対応する画像はハイスコアリーダーボードに表示されます。トレーニングの損失はCSVファイルから読み込まれ、折れ線グラフとしてプロットされます。最終的に、すべての画像をimageioなどのライブラリを使用してGIFにまとめることができます。

結論

この記事では、Vision Transformer(ViT)モデルのファインチューニングプロセスを視覚化するアニメーションを作成する方法についての詳細なガイドを提供しました。埋め込みの生成と分析、結果の視覚化、これらの要素をまとめたアニメーションの作成の手順を歩みました。

このようなアニメーションを作成することは、ViTモデルのファインチューニングの複雑なプロセスを理解する助けになるだけでなく、他の人にこれらのコンセプトを伝えるための強力なツールとしても機能します。

アニメーションの完全なコードは、GitHubにある同梱されているノートブックで利用可能です。

筆者は、非構造化データのインタラクティブな探索のための高度なソフトウェアソリューションを作成する専門家です。非構造化データに関して執筆し、強力な視覚化ツールを使用して分析と意思決定を行っています。

参考文献

[1] Alexey Dosovitskiy, Lucas Beyer, Alexander Kolesnikov, Dirk Weissenborn, Xiaohua Zhai, Thomas Unterthiner, Mostafa Dehghani, Matthias Minderer, Georg Heigold, Sylvain Gelly, Jakob Uszkoreit, Neil Houlsby, An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale (2020), arXiv

[2] Alex Krizhevsky, Learning Multiple Layers of Features from Tiny Images (2009), University Toronto

[3] Gower, John C. Generalized procrustes analysis (1975), Psychometrika

こちらの記事はdev.toの良い記事を日本人向けに翻訳しています。
https://dev.to/markusstoll/how-i-created-an-animation-of-the-embeddings-during-fine-tuning-17ln