トランスフォーマーによるグラフ分類

Graph classification with Transformers.

前回のブログでは、グラフ上での機械学習の理論的な側面について調査しました。このブログでは、Transformersライブラリを使用してグラフ分類を行う方法について調査します(デモノートブックをここからダウンロードして一緒に進めることもできます!)

現時点では、Transformersで利用できる唯一のグラフトランスフォーマーモデルはMicrosoftのGraphormerですので、こちらを使用します。他のモデルも使用して統合する人々がどのような結果を出すか楽しみにしています 🤗

必要条件

このチュートリアルに従うためには、datasetstransformers(バージョン>= 4.27.2)がインストールされている必要があります。これはpip install -U datasets transformersで行うことができます。

データ

グラフデータを使用するためには、独自のデータセットから始めるか、Hubで利用可能なデータセットを使用することができます。既に利用可能なデータセットを使用することに焦点を当てますが、自分のデータセットを追加することも自由です!

読み込み

Hubからのグラフデータセットの読み込みは非常に簡単です。まず、ogbg-mohivデータセット(StanfordのOpen Graph Benchmarkのベースライン)をロードしましょう。これはOGBリポジトリに保存されています:

from datasets import load_dataset

# Hubには1つのスプリットしかありません
dataset = load_dataset("OGB/ogbg-molhiv")

dataset = dataset.shuffle(seed=0)

このデータセットにはすでにtrainvalidationtestの3つのスプリットがあり、これらのスプリットはすべて興味のある5つの列(edge_indexedge_attrynum_nodesnode_feat)を含んでいます。これはprint(dataset)を実行することで確認できます。

他のグラフライブラリがある場合は、それらを使用してグラフをプロットし、データセットをさらに検査することができます。例えば、PyGeometricとmatplotlibを使用する場合:

import networkx as nx
import matplotlib.pyplot as plt

# 最初のトレイングラフをプロットしたい
graph = dataset["train"][0]

edges = graph["edge_index"]
num_edges = len(edges[0])
num_nodes = graph["num_nodes"]

# networkx形式に変換
G = nx.Graph()
G.add_nodes_from(range(num_nodes))
G.add_edges_from([(edges[0][i], edges[1][i]) for i in range(num_edges)])

# プロット
nx.draw(G)

形式

Hubでは、グラフデータセットは主にグラフのリストとして格納されます(jsonl形式を使用)。

単一のグラフは辞書であり、以下はグラフ分類データセットの期待される形式です:

  • edge_indexはエッジ内のノードのインデックスを含み、エッジインデックスの2つのパラレルリストを含むリストとして格納されます。
    • タイプ:整数の2つのリストのリスト
    • :ノードが0、1、2、3の4つであり、接続が1→2、1→3、3→1の場合、edge_index = [[1, 1, 3], [2, 3, 1]]となります。ここでノード0が存在しないことに注意してください。次の属性が重要な理由です。
  • num_nodesはグラフ内の利用可能なノードの総数を示します(デフォルトでは、ノードは連続的に番号が付けられていると想定されています)。
    • タイプ:整数
    • :上記の例では、num_nodes = 4です。
  • yはグラフを予測するためのマッピングです(クラス、プロパティ値、または複数のタスク用のバイナリラベルなど)。
    • タイプ:整数のリスト(マルチクラス分類の場合)、浮動小数点数(回帰の場合)、または1と0のリスト(バイナリマルチタスク分類の場合)
    • :グラフのサイズ(小=0、VoAGI=1、大=2)を予測することができます。ここではy = [0]です。
  • node_featは、グラフの各ノードの利用可能な特徴(存在する場合)をノードインデックスの順に含みます。
    • タイプ:整数のリストのリスト(オプション)
    • :上記のノードは、例えば分子中の異なる原子のようなタイプを持つかもしれません。これはnode_feat = [[1], [0], [1], [1]]となります。
  • edge_attrは、エッジインデックスの順に、各エッジの利用可能な属性(存在する場合)を含みます。
    • タイプ:整数のリストのリスト(オプション)
    • :上記のエッジは、例えば分子内の化学結合のようなタイプを持つかもしれません。これはedge_attr = [[0], [1], [1]]となります。

前処理

グラフ変換フレームワークでは、通常、データセットに特定の前処理を適用して、学習タスク(この場合は分類)を支援するための追加の特徴とプロパティを生成します。ここでは、Graphormerのデフォルトの前処理を使用しています。これにより、ノード間の入出力度情報、最短経路行列など、モデルにとって興味のあるその他のプロパティが生成されます。

from transformers.models.graphormer.collating_graphormer import preprocess_item, GraphormerDataCollator

dataset_processed = dataset.map(preprocess_item, batched=False)

また、この前処理をオンザフライ(データコレータのパラメータでon_the_fly_processingをTrueに設定することで)適用することも可能です。すべてのデータセットがogbg-molhivほど小さくないため、大規模なグラフの場合、事前にすべての前処理済みデータを保存することは非常にコストがかかるかもしれません。

モデル

読み込み

ここでは、既存の事前学習済みモデル/チェックポイントを読み込み、下流タスクで微調整します。この下流タスクはバイナリ分類タスクです(したがってnum_classes = 2です)。また、回帰タスク(num_classes = 1)やマルチタスク分類タスクでもモデルを微調整することができます。

from transformers import GraphormerForGraphClassification

model = GraphormerForGraphClassification.from_pretrained(
    "clefourrier/pcqm4mv2_graphormer_base",
    num_classes=2, # 下流タスクのクラス数
    ignore_mismatched_sizes=True,
)

これを詳しく見てみましょう。

モデル上のfrom_pretrainedメソッドを呼び出すと、重みがダウンロードされ、キャッシュされます。予測のためのクラス数はデータセットに依存するため、新しいnum_classesをモデルのチェックポイントとともに渡します。これにより、タスクに特化したカスタム分類ヘッドが作成され、元のデコーダヘッドとは異なる可能性があることが保証されます。

また、既知のチェックポイントのパラメータを使用して、新しくランダムに初期化されたモデルを作成することも可能です。

トレーニングまたは微調整

モデルをシンプルにトレーニングするために、Trainerを使用します。インスタンス化するには、トレーニングの設定と評価メトリックを定義する必要があります。最も重要なのはTrainingArgumentsで、トレーニングをカスタマイズするためのすべての属性を含むクラスです。モデルのチェックポイントを保存するために使用されるフォルダ名を指定する必要があります。

from transformers import TrainingArguments, Trainer

training_args = TrainingArguments(
    "graph-classification",
    logging_dir="graph-classification",
    per_device_train_batch_size=64,
    per_device_eval_batch_size=64,
    auto_find_batch_size=True, # バッチサイズはOOMを防ぐために自動的に変更される可能性があります
    gradient_accumulation_steps=10,
    dataloader_num_workers=4, #1, 
    num_train_epochs=20,
    evaluation_strategy="epoch",
    logging_strategy="epoch",
    push_to_hub=False,
)

グラフデータセットの場合、十分なサンプルでトレーニングする一方で、メモリ不足のエラーを回避するために、バッチサイズと勾配蓄積ステップを調整することが特に重要です。

最後の引数push_to_hubは、Trainerがモデルをトレーニング中に定期的にHubにプッシュすることを可能にします。

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=dataset_processed["train"],
    eval_dataset=dataset_processed["validation"],
    data_collator=GraphormerDataCollator(),
)

グラフ分類のためのTrainerでは、特定のグラフデータセット用のデータコレータを渡すことが重要です。これにより、個々のグラフがバッチに変換され、トレーニングに使用されます。

train_results = trainer.train()
trainer.push_to_hub()

モデルがトレーニングされたら、push_to_hubを使用して関連するトレーニングアーティファクトとともにモデルをハブに保存することができます。

このモデルは非常に大きいため、CPU(IntelCore i7)で20エポックのトレーニング/微調整に約1日かかります。より高速にするには、パワフルなGPUと並列化を使用し、Colabノートブックまたは選択したクラスターでコードを直接実行することができます。

エンディングノート

今、あなたはtransformersを使用してグラフ分類モデルをトレーニングする方法を知っているので、コミュニティの他のメンバーが使用できるように、お気に入りのグラフトランスフォーマーチェックポイント、モデル、データセットをHubで共有してみてください!

We will continue to update VoAGI; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

AIテクノロジー

「LXTのテクノロジーバイスプレジデント、アムル・ヌール・エルディン - インタビューシリーズ」

アムル・ヌール・エルディンは、LXTのテクノロジー担当副社長ですアムルは、自動音声認識(ASR)の文脈での音声/音響処理と機...

人工知能

「UVeyeの共同設立者兼CEO、アミール・ヘヴェルについてのインタビューシリーズ」

アミール・ヘヴァーは、UVeyeのCEO兼共同創設者であり、高速かつ正確な異常検出により、自動車およびセキュリティ産業に直面...

人工知能

「Kognitosの創設者兼CEO、ビニー・ギル- インタビューシリーズ」

ビニー・ギルは、複数の役職と企業を横断する多様で幅広い業務経験を持っていますビニーは現在、Kognitosの創設者兼CEOであり...

人工知能

Aaron Lee、Smith.aiの共同設立者兼CEO - インタビューシリーズ

アーロン・リーさんは、Smith.aiの共同創業者兼CEOであり、AIと人間の知性を組み合わせて、24時間365日の顧客エンゲージメン...

人工知能

『DeepHowのCEO兼共同創業者、サム・ジェン氏によるインタビューシリーズ』

ディープハウのCEO兼共同創設者であるサム・ジェンは、著名な投資家から支持される急速に進化するスタートアップを率いていま...

人工知能

「コマンドバーの創設者兼CEO、ジェームズ・エバンスによるインタビューシリーズ」

ジェームズ・エバンズは、CommandBarの創設者兼CEOであり、製品、マーケティング、顧客チームを支援するために設計されたAIパ...