Transformer ベースのビジョン モデルは徐々に進化しており、分類、セグメンテーション、アクション認識タスクでは畳み込みモデルと同等であると報告されています。ビジョン タスク用の一連の畳み込みモデルがあり、Transformer ベースのモデルよりも人気があります。このブログでは、Microsoft Research Team が International Conference for Computer Vision (ICCV) 2021 で発表した SWin Transformer Vision モデルについて詳しく説明します。これは、Dog Breed 画像分類タスクで、いくつかの SOTA 畳み込みベースのモデルに対してパフォーマンスのベンチマークを行います。
トランスフォーマー ベースのモデルは、コンピューター ビジョンの次の大きなものになるでしょうか?トランスフォーマーは言語タスクの成功したソリューションであり、さまざまな AI サブフィールドを統合し、より複雑な問題に対する強力なソリューションを提示するでしょうか?腕をまくり上げて、そもそも分類タスクでどれだけ優れているかを評価します。
見た目が微妙に変化する無数の犬種は、獣医師、犬の所有者、動物保護施設のスタッフ、および潜在的な犬の所有者にとって、適切な品種を特定する上での課題となっています。適切なトレーニング、治療を提供し、栄養ニーズを満たすためには、犬種を特定する必要があります。データは、世界中の 120 種の犬の約 20,000 枚の画像を含むStanford Dog Datasetから提供されています。このデータは、Kaggle 競技犬の品種識別用のトレーニング セットとテスト セットにほぼ均等に分割されています。
このソリューションの目的は、最小限のデータで犬種を正しく識別し、見た目が似ている犬種であっても正しく識別できる犬種識別システムを構築することです。これはマルチクラス分類タスクであり、すべての画像について、モデルは 120 品種すべての確率を予測する必要があります。確率が最も高いのは、画像内の犬の可能性が最も高い品種です。
クラスの不均衡はありませんが、ニューラル ネットワークをトレーニングするにはデータが不十分な場合があります。ランダムな画像の摂動と事前トレーニング済みのモデルを使用した画像拡張により、この問題を回避できます。
画像が最も多い上位 5 品種は、scottish_deerhound、maltese_dog、afghan_hound、entlebucher、bernese_mountain_dog です。画像が最も少ない下位 5 品種は、golden_retriever、brabancon_griffon、komondor、eskimo_dog、briard です。
画像の高さ、幅、およびそれらの縦横比の分布を理解するために、トレーニング画像の空間寸法に関する迅速な分析が行われます。
アスペクト比が非常に低い (<0.5) および非常に高い (>2.3) 画像は、異常画像と見なされます。 1.5 が適切なアスペクト比と見なされます。
さまざまな犬種を分析すると、以下のペアの犬種は一般的に似ていることがわかりました。
このアーキテクチャは、Microsoft Research Team によって開発された「Swin Transformer: Shifted Windows を使用した Hierarchical Vision Transformer」に基づいています。この論文では、特徴マップの階層表現を生成する改良された ViT アーキテクチャについて説明し、自己注意メカニズムの計算の複雑さを二次から線形に削減します。 Imagenet 分類問題で EfficientNet のような SOTA 畳み込みネットワークと同じ結果が得られることが証明されています。
このアーキテクチャのビルディング ブロックについては、以下の注記で説明します。
NLP では、モデルの処理要素であるトークンは、1 トークンのサイズが 1 (ちょうど 1 単語) である文内の単語です。 ViT ( Vision Transformers) は、「画像パッチ」をトークンとして扱います。各パッチは、隣接するピクセルのグループで構成される画像のパーティションです。各画像パッチはトークンです。 ViT の 1 トークンのサイズは、patch_height * patch_width * チャネル数です。パッチの寸法に基づいて、1 つの画像のパッチまたはトークンの数を取得します。画像サイズ (H*W*3) が 224 * 224 * 3 ピクセルで、パッチ サイズが 4 * 4 の場合、画像から 224/4 * 224/4 = 56 * 56 パッチまたは 3136 トークンを取得します。各トークンまたはパッチのサイズは 4*4*3 = 48 次元または 48 ピクセルのデータになります。したがって、このイメージのアーキテクチャへの入力は、それぞれサイズが 48 次元の 3136 個のトークンで構成されます。
SWIN トランスフォーマーの基本的なメカニズムは、画像の空間次元が減少し、チャネル数が増加する CNN ベースのアーキテクチャに似ています。階層アーキテクチャのすべての段階での SWIN トランスフォーマーは、トークンの次元を増やしながら、イメージ パッチの数またはトークンの数も減らします。このメカニズムを念頭に置いておくと、SWIN アーキテクチャを簡単に理解できます。
アーキテクチャのすべての段階で、トークンのサイズが増加している間、トークンの数が減少していることがわかります。
SWIN-T アーキテクチャは、「パッチ パーティショナー」とは別に、他の 3 つのビルディング ブロック (線形埋め込み、Swin Transformer ブロック、パッチ マージ) で構成されています。これらの構成要素は繰り返され、機能マップを階層的に処理します。
「Patch Partitioner」からのそれぞれ 48 次元の 3136 トークンがフィード フォワード レイヤーに供給され、48 特徴ベクトルのトークンがサイズ「C」の特徴ベクトルに埋め込まれます。ここで「C」は変圧器の容量として機能し、SWIN アーキテクチャにはそれに基づく 4 つのバリアントがあります。
画像のパッチングと線形埋め込みは、カーネル サイズとストライド長がパッチ サイズと同じ単一の畳み込みで一緒に実装されます。畳み込みのチャネル数は「C」になります。
SWin Transformer ブロックは、ViT アーキテクチャの標準の Transformer ブロックとは異なります。 SWin トランスフォーマーでは、
Stage1 は 2 つの SWIN-T Transformer ブロック (画像参照) で構成され、最初の Transformer Block には Window MSA (W-MSA) モジュールがあり、2 番目の Transformer Block には Shifted Window MSA (SW-MSA) モジュールがあります。 SWin Transformer ブロックでは、W-MSA 層と SW-MSA 層の入力と出力が正規化層を介して渡されます。次に、Gaussian Error Linear Units (GELU) がアクティブ化された 2 層のフィード フォワード ネットワークが適用されます。各ブロック内およびこれら 2 つのブロック間に残留接続があります。
Window MSA (W-MSA) および Shifted Window MSA (SW-MSA) モジュール
ViT の標準的なアテンション レイヤーは、画像内の他のすべてのパッチを含むパッチのアテンションを計算するグローバル レイヤーであったため、画像の寸法に比例する二次的な複雑さが生じました。これは、高解像度の画像にはあまり適していません。
W-MSA または SW-MSA モジュールの自己注意メカニズムは、画像の同じウィンドウ内のパッチ間でのみ自己注意を計算し、ウィンドウの外側では自己注意を計算しないローカル メカニズムです。
ウィンドウは、各ウィンドウが M*M パッチで構成されるイメージの大きなパーティションのようなものです。グローバルな自己注意をローカルな自己注意に置き換えると、計算の複雑さが二次から線形に減少しました。
W-MSA と SW-MSA アテンション モジュールの主な違いは、イメージのウィンドウの構成方法にあります。
W-MSA モジュールでは、通常のウィンドウ分割戦略に従います。イメージは、イメージの左上のピクセルから始まる重複しないウィンドウに均等に分割され、各ウィンドウには M*M または M2 パッチが含まれます。
SW-MSA モジュールでは、通常のパーティショニング戦略から (M/2, M/2) パッチだけウィンドウを移動することにより、ウィンドウ構成が W-MSA レイヤーのウィンドウ構成からシフトされます。
注意は W-MSA のウィンドウ内でローカルに制限されるため、シフトされたウィンドウにより、ウィンドウ間の注意が依然としてグローバルな注意の利点を生むことができます。これは、W-MSA レイヤーのウィンドウ 1 の境界が、SW-MSA レイヤーのウィンドウ W2、W4、および W5 と共有されているために可能です。したがって、グローバルな注意は、「シフトされたウィンドウでのローカルな注意」を介して間接的に発生します。
パッチ マージ レイヤーは、ネットワークがますます深くなるにつれて、トークンの数を減らします。第1のパッチマージ層は、2×2隣接パッチの各グループの特徴を連結する。
PyPI のパッケージtfswinには、SWIN Transformers の事前トレーニング済み TF-Keras バリアントがあり、公式の pytorch 実装に基づいて構築されています。そのコードはgithubで入手できます。 tfswin を使用して、犬種の画像をトレーニングします。
from tfswin import SwinTransformerBase224, preprocess_input def build_model1(swintransformer): tf.keras.backend.clear_session() inputs = Input(shape=(resize_height, resize_width, 3)) outputs = Lambda(preprocess_input)(inputs) outputs = swintransformer(outputs) outputs = Dense(num_classes, activation='softmax')(outputs) swin_model = Model(inputs=inputs, outputs=outputs) return swin_model #build the model swintransformer = SwinTransformerBase224(include_top=False,pooling='avg') swin_model1 = build_model1(swintransformer) #set the layers of the pretrained model as non-trainable for layer in swin_model1.layers[2].layers: layer.trainable = False swin_model1.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),loss='categorical_crossentropy',metrics=['accuracy'])
#Logloss of the test set using various ResNet variants +------------+---------------+-------------------------+----------+ | Model Name | Retrained | Top Layers Replacement | Log_Loss | +------------+---------------+-------------------------+----------+ | ResNet50 | None | ConvBlock_FC_Output | 0.96463 | | ResNet50 | None | GlobalAvgPooling_Output | 0.58147 | | ResNet50 | last 4 layers | ConvBlock_FC_Output | 2.10158 | | ResNet50 | last 4 layers | GlobalAvgPooling_Output | 0.57019 | +------------+---------------+-------------------------+----------+
ログ損失が最も少ない ResNet50 モデルに対応するコード
from tensorflow.keras.layers import Input,Conv2D,Dense,BatchNormalization,Flatten,Concatenate, Dropout,MaxPooling2D from tensorflow.keras.models import Model from tensorflow.keras.applications.resnet50 import ResNet50, preprocess_input def build_model(): tf.keras.backend.clear_session() inputs = Input(shape=(resize_height, resize_width, 3)) #added preprocess_input method as a layer to convert input images to those expected by Resnet processed_inputs = preprocess_input(inputs) #use the pretrained ResNet model (Parameter pooling = 'avg' will take care of the Gobal Average Pooling of the ResNet model features) base_model = ResNet50(weights="imagenet", include_top=False,pooling='avg')(processed_inputs) #output layer output = Dense(units=num_classes,activation='softmax',name='Output')(base_model) resnet_model = Model(inputs=inputs, outputs=output) return resnet_model #build the model resnet_model = build_model() #set the layers of the resnet pretrained model as non-trainable except for its last 4 layers which needs to be re-trained for this data for layer in resnet_model.layers[3].layers[:-4]: layer.trainable = False #compile the model resnet_model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.0001),loss='categorical_crossentropy',metrics=['accuracy']) print(resnet_model.summary()) history = resnet_model.fit(train_ds, epochs=50, validation_data=val_ds, callbacks=callbacks_list)
#Logloss of the standalone model variants +----------------------------+-------------+ | Model Name | Log_Loss | +----------------------------+-------------+ | EfficientNetV2M | 0.28347 | | Inception ResNet | 0.28623 | | NasNetLarge | 0.33285 | | Xception | 0.34187 | | Inception_V3 | 0.54297 | | EfficientNetV2M_GlobalAveg | 0.50423 | | InceptionV3_GlobalAveg | 0.46402 | +----------------------------+-------------+
+--------------------------------------------------------------------------+-----------+ | Model Name | Log_Loss | +--------------------------------------------------------------------------+-----------+ | Ensemble1 - EfficientNEt,InceptionResNet,NasNet,Xception) | 0.17363 | | Ensemble2 - EfficientNEt,InceptionResNet,NasNet,Xception and InceptionV3 | 0.16914 | | Ensemble3 - Ensemble2 with 50% dropout. | 0.16678 | | Ensemble4 - Ensemble of various EfficientNet Architecture | 0.16519 | +--------------------------------------------------------------------------+-----------+
Each of these models accepts varied input formats and in Keras they have their own preprocessing functions.
ベンチマーク結果
+----------------------------------+------------+----------------------+----------+ | Model Name | Parameters | Train time (seconds) | Log_Loss | +----------------------------------+------------+----------------------+----------+ | EfficientNet_ConvBlock_Output | 54.7M | ~260s | 0.28347 | | InceptionResNet_ConvBlock_Output | 56.1M | ~260s | 0.28623 | | NASNetLarge_ConvBlock_Output | 89.6M | ~330s | 0.33285 | | XCeption_ConvBlock_Output | 23.3M | ~240s | 0.34187 | | InceptionV3_ConvBlock_Output | 24.2M | ~225s | 0.54297 | | EfficientNet_GlobalAvg | 53.3M | ~260s | 0.50423 | | InceptionV3_GlobalAvg | 22M | ~215s | 0.46402 | | swin_base224 | 86.8M | ~550s | 0.47289 | | swin_base384 | 87M | ~600s | 0.41902 | | swin_large384 | 195M | ~1000s | 0.42207 | +----------------------------------+------------+----------------------+----------+
SWIN Transformers は、すべての ResNet50 バリアントおよび InceptionV3 モデルよりも優れたパフォーマンスを発揮しました。
このデータに対する SWIN Transformer のログ損失は、InceptionResNet、EfficientNet、Xception、および NasNet Large モデルと比較して、それらの出力が畳み込み層とそれに続く Maxpooling によって後で処理される場合に比べてわずかに高くなります。
ただし、平均出力が出力層によって直接処理される場合、SWIN は EfficientNet モデルと同等の性能を発揮します。
SWIN モデルは、どの畳み込みモデルよりも大きいため、システムのスループットとレイテンシーに影響を与えます。
この研究は、コンピューター ビジョン用の変換器ベースのモデルの適用を理解するのに役立つことが証明されました。
私のGithubのノートブックのコードと、このユースケースの GUI はこちらにあります。
https://www.kaggle.com/competitions/dog-breed-identification
https://arxiv.org/pdf/2103.14030.pdf