huggingface transformers (ViT) の使い方(ファインチューニング、分類と回帰)
huggingface には様々な AI モデルのライブラリが公開されている。
今回のネタは、このライブラリを利用する方法について。
- 推論
- ファインチューニング
- 分類と回帰
なお、今回は ViT モデルを具体例として取り上げるが、 huggingface の transformers のモデルであれば、 ほとんどの場合、少しの変更だけで応用できる。
推論
以下に、 訓練済みの ViT モデルを使用して画像分類の推論を行なうサンプルソースを示す。
|
|
次にソースの各行について説明する。
ViT のロード
推論に使用する訓練済みの ViT モデルをロードする。
画像をベクトルに変換する ImageProcessor と、 ベクトルデータから分類を行なう ViT モデルをロードしている。
huggingface Transformer では、 ImageProcessor と モデルの組み合わせで制御する。
image_processor = AutoImageProcessor.from_pretrained("google/vit-base-patch16-224") model = ViTForImageClassification.from_pretrained("google/vit-base-patch16-224")
画像のベクトル変換
huggingface Transformer モデルは、 画像を各モデルが規定する所定のベクトルに変換する必要がある。 その変換を行なうのが ImageProcessor の役割である。
# ViT で分類する画像のロード image = loadImg( "img/photo.jpg" ); # 画像をベクトル変換 inputs = image_processor(image, return_tensors="pt")
推論
モデルにベクトルを渡して推論を行なう。 なお、モデルのオブジェクトを関数呼び出しすると、 そのモデルの forward メソッドが実行される。
推論結果は logits に格納されている。 この logits には分類ごとのスコアが格納されているので、 その最大スコアのインデックスを取得することで、 分類の推論結果を得る。
# ベクトルに変換したデータから分類を推論 outputs = model(**inputs) logits = outputs.logits # 推論結果の分類インデックスを取得 predicted_label = logits.argmax(-1).item()
ファインチューニング
公開されているトレーニング済みのモデルを使っても出来ることは限られている。
個々の目的の処理を行なうためには、 目的の処理を行なえるようにモデルをファインチューニングしなければならない。
ファインチューニングを行なうには次の手順で行なう。
- トレーニングデータの用意
- ImageProcessor とモデルの生成
- TrainingArguments の生成
- トレーニングデータから、モデルに投入するデータへの変換処理作成
- Trainer の生成とトレーニングの実行
- トレーニング後のモデルのセーブ
- Trainer を使った推論
- トレーニング後のモデルを使った推論
以下に、 ViT をファインチューニングするサンプルソースを示す。
|
|
次にソースの各行について説明する。
データセットのロード
ここでは、画像処理の機械学習サンプルとして公開されている beans を利用する。
beans の実際の画像は以下で確認できる。
<https://github.com/AI-Lab-Makerere/ibean/>
|
|
ImageProcessor, モデルのロード
ファインチューニングに利用するモデルをロードする。 また、今回の分類モデルの分類数 num_lables=(len(labels))) を設定する。
|
|
TrainingArguments の設定
トレーニングの設定を行なう。
- トレーニング結果を保存するディレクトリの設定: output_dir
- エポック数: num_train_epochs
- トレーニングに fp16 を利用するかどうか: fp16
- トレーニングの途中結果を保持するステップ数: save_state
- トレーニングの途中結果を評価するステップ数: eval_steps
- トレーニングの途中結果を保存する最大数: save_total_limit
- 指定エポック数のトレーニング終了後、 トレーニング途中の評価結果のうち一番良い結果をロードするかどうか: load_best_model_at_end
- トレーニングの演算に CPU を使うか: use_cpu
ここでは速度重視で GPU, FP16 を使う設定にしている。
なお、 相当古い GPU を使っている場合は逆に CPU の方が早い場合がある。
まぁ、 ディープラーニングをやろうって人の GPU がそんな古いなんてことはないと思う。 ちなみに私の GPU は、GT1030 でクソ重くて CPU の方が速かった。。
|
|
トレーニングデータから、モデルに投入するデータへの変換処理作成
後述する Trainer に、トレーニングデータを指定する。 このトレーニングデータは、リスト(あるいは配列)のデータであれば、 そのデータの中身は問われない。
とはいえ、モデルにデータを投入するには、 モデルが要求するデータ型に整える必要がある。
例えば、 Trainer に与えるデータとして、トレーニングデータの個数分のリストを与え、 モデルに与えるデータには { pixel_values:[], labels:[] } のデータを与える。
最初からトレーニング用の全画像データのリストを作成して Trainer に渡すことも可能だが、 その場合事前に全画像データを読み込んでおく必要があり、 データ数が多い場合や、データサイズが大きい場合にメモリを大量に消費することになる。 メモリが潤沢にある場合はその方が効率が良いが、 メモリが足りない場合はトレーニングが出来なくなってしまう。
このようにメモリが足らなくならないようにするため、 Trainer に与えるデータと、実際にモデルに与えるデータを分割する処理を行なう。
この時、Trainer に与えたデータから、 実際にモデルに与えるデータに変換する処理が必要になる。
それをここで定義する。
なお、モデルに与えるデータ形式はモデル毎に異なるので、 実際に利用するモデル毎に合せて作成する必要がある。
|
|
Trainer の生成とトレーニングの実行
Trainer は、先に設定した TrainingArguments の設定で 実際にトレーニングを制御するクラスである。
ここでは以下を設定する。
- トレーニングするモデル: model
- TrainingArguments: args
- 上記のモデル用データに変換する関数: data_collator
- トレーニング用データ: train_dataset
- 評価用データ: eval_dataset
|
|
トレーニング後のモデルのセーブ
トレーニング後のモデルをセーブする。
|
|
Trainer を使った推論
trainer を使って推論を行なう。
|
|
トレーニング後のモデルを使った推論
トレーニング後のモデルを使って推論する。
|
|
分類と回帰
一般的に ViT は分類を行なうモデルであるが、回帰モデルとしても利用することができる。 なお、これは ViT に限らず huggingface の Transformers の分類モデルは基本的に 回帰としても利用できる。
使用方法は簡単で、モデルを作成する際の num_labels に 1 を指定するだけで、 回帰モデルとして作成できる。
ただし分類と比べて以下に注意すべきである。
- label は int 型ではなく float 型とする
- 推論結果は
logits.argmax(-1).item()
ではなくlogits.item()
label は、data_collator で label を渡す際に float 型に変えるだけで良い。
|
|