はじめに
- 本記事は機械学習の精度向上の手法であるModel SoupsをTensolFlowで試したものです。
- よくわかっていない部分もあるので誤りなどあればコメントで教えてください。
Model Soupsとは
- 複数のファインチューニングモデルの「重み」を平均化することで精度を向上させる手法らしいです。
- よく使われる複数モデルでのアンサンブルとは異なり、Model soupsは推論時に余分な計算がいらないことが嬉しいようです。要はアンサンブルより早く結果がでるということだと思います。
- 詳細についてはリンク先を参照してください。
参考にしたソース
- Githubに実装を上げてくれている人がいましたのでリンク先を参考にしました。
- 今回はTensolFlowでの実装を流用させていただきました。(リンク先にはTorchでの実装もありました)
- Model Soupには以下3つの手法が存在します。
・uniform soup:全てのモデルを一律組み込んで平均する。
・greedy soup:検証データに対して精度が良かったもののみを平均する。
・learned soup:勾配ベースのミニバッチ最適化によって重みを補完する。 - リンク先ではuniform soupとgreedy soupが用意されています。今回はuniform soupの部分を流用します。使用する「重み」ですが、精度のよかったものを手動で選別しておきます。これでなんちゃってgreedy soupになると思います。
検証に利用する画像分類問題と使用したモデル
- 衛星画像からハリケーンで被害を受けたエリアか否かを判別するという画像分類問題で検証してみたいと思います。詳細は以下になります。
・学習用データサンプル数:5,991
・評価用データサンプル数:8,232
・使用モデル:VisionTransformer(vit_l16)
VisionTransformerでファインチューニングしただけの予測結果
- VisionTransformerで何回かファインチューニングを実施し以下4つの重みができました。
モデル名 | 予測結果(Accuracy) |
---|---|
weight1 | 0.9927114 |
weight2 | 0.9939261 |
weight3 | 0.9939261 |
weight4 | 0.9936832 |
- この4つの重みを使ってModel soupsをやっていきます。
Model soupsの実装部分
- 実装はこんな感じです。最後の行で「Modelsoups」という名前で重みファイルを保存します。
import numpy as np
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, Flatten, Activation, Dense, Dropout, MaxPooling2D, GlobalAveragePooling2D
!pip install vit-keras
!pip install tensorflow-addons
import tensorflow_addons as tfa
from vit_keras import vit, utils
import inspect
import time
def create_model():
vit_model = vit.vit_l16(
image_size = 384,
activation = 'sigmoid',
pretrained = True,
include_top = False,
pretrained_top = False)
model = tf.keras.Sequential([
vit_model,
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(2, 'softmax')
],
name = 'vision_transformer')
return model
# 重みのリスト
weight_list = ['weight1',
'weight2',
'weight3',
'weight4']
model = create_model()
soups = []
for i in range(len(weight_list)):
model.load_weights(weight_list[i])
soup = [np.array(w) for w in model.weights]
soups.append(soup)
if 0 < len(soups):
for w1, w2 in zip(model.weights, list(zip(*soups))):
tf.keras.backend.set_value(w1, np.mean(w2, axis = 0))
model.save_weights('Modelsoups')
Model soupsでの予測結果
- 保存した重みファイルを使用し評価用画像の予測を行ってみます。
- 結果は0.9946550でした。まあちょっとは上がったのか…?
まとめ
- とりあえずTensolflowでModel soupsやってみました。少しは予測結果も上がったので組み合わせる重みによっては効果は期待できると思います。実際、本記事執筆時点のImageNetのベンチマークでは、Model soups(ViT-G/14)が90.94%という高スコアを出しています。
- 次に何らかのコンペに参加する際は積極的に使ってみたいと思います。