PyTorch 1.8 : 画像と動画 : 配備のために Vision Transformer を最適化する

PyTorch 1.8 チュートリアル : 画像と動画 : 配備のために Vision Transformer を最適化する (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 04/17/2021 (1.8.1+cu102)

* 本ページは、PyTorch 1.8 Tutorials の以下のページを翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

無料セミナー実施中 クラスキャット主催 人工知能 & ビジネス Web セミナー

人工知能とビジネスをテーマにウェビナー (WEB セミナー) を定期的に開催しています。スケジュールは弊社 公式 Web サイト でご確認頂けます。
  • お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
  • Windows PC のブラウザからご参加が可能です。スマートデバイスもご利用可能です。
クラスキャットは人工知能・テレワークに関する各種サービスを提供しております :

人工知能研究開発支援 人工知能研修サービス テレワーク & オンライン授業を支援
PoC(概念実証)を失敗させないための支援 (本支援はセミナーに参加しアンケートに回答した方を対象としています。)

お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。

株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
E-Mail:sales-info@classcat.com  ;  WebSite: https://www.classcat.com/  ;  Facebook

 

画像と動画 : 配備のために Vision Transformer を最適化する

Vision Transformer モデルは、あらゆる種類の SOTA 結果を獲得するために自然言語処理で導入された、最先端の attention ベースの transformer モデルをコンピュータビジョン・タスクに応用します。Facebook Data-efficient 画像 Transformer DeiT は画像分類のために ImageNet 上で訓練された Vision Transformer モデルです。

このチュートリアルでは、最初に DeiT が何であるかそれをどのように利用するかをカバーし、それからモデルのスクリプト化、量子化、最適化そして iOS と Android apps での利用の完全なステップを通り抜けます。量子化、最適化モデルと非量子化、非最適化モデルのパフォーマンスも比較し、ステップととともにモデルに量子化と最適化を適用することの利益を示します。

 

DeiT とは何か

2012 年に深層学習がテイクオフしてから畳込みニューラルネットワーク (CNN) は画像分類のための主要モデルを持ってきましたが、CNN は典型的には SOTA 結果を獲得するには訓練のために何億もの画像を要求します。DeiT は遥かに少ないデータを必要とする vision transformer モデルで画像分類を遂行する際にトップクラスの CNN と競争するために訓練のためのリソースを計算し、これは DeiT の 2 つの主要コンポーネントにより可能にされます :

  • データ増強、これは遥かに大規模なデータセット上の訓練をシミュレートします ;
  • ネイティブ distillation (蒸留)、これは transformer ネットワークに CNN の出力から学習することを可能にします。

DeiT はデータとリソースへの制限されたアクセスで Transformer がコンピュータビジョン・タスクに成功的に適用できることを示します。DeiT のより多くの詳細については、レポジトリ論文 を見てください。

 

DeiT で画像を分類する

DeiT を使用してどのように画像を分類するかの詳細情報については DeiT レポジトリの README に従ってください、あるいは
素早いテストのためには、最初に必要なパッケージをインストールして :

pip install torch torchvision
pip install timm
pip install pandas
pip install requests

それから下のスクリプトを実行します :

from PIL import Image
import torch
import timm
import requests
import torchvision.transforms as transforms
from timm.data.constants import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD

print(torch.__version__)
# should be 1.8.0


model = torch.hub.load('facebookresearch/deit:main', 'deit_base_patch16_224', pretrained=True)
model.eval()

transform = transforms.Compose([
    transforms.Resize(256, interpolation=3),
    transforms.CenterCrop(224),
    transforms.ToTensor(),
    transforms.Normalize(IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD),
])

img = Image.open(requests.get("https://raw.githubusercontent.com/pytorch/ios-demo-app/master/HelloWorld/HelloWorld/HelloWorld/image.png", stream=True).raw)
img = transform(img)[None,]
out = model(img)
clsidx = torch.argmax(out)
print(clsidx.item())
1.8.1+cu102
269

この出力は 269 になるはずです、これはクラスインデックスから ラベルファイル への ImageNet リストによれば、‘timber wolf, grey wolf, gray wolf, Canis lupus’ にマップされます。

画像を分類するために DeiT モデルを利用できることを検証した今、モデルが iOS と Android apps 上で動作できるようにどのように変更するかを見ましょう。

 

DeiT のスクリプト化

モバイル上でモデルを使用するため、最初にモデルをスクリプト化する必要があります。素早い概要のためには Script and Optimize レシピ を見てください。前のステップで使用された DeiT モデルをモバイル上で実行できる TorchScript 形式に変換するためには下のコードを実行してください。

model = torch.hub.load('facebookresearch/deit:main', 'deit_base_patch16_224', pretrained=True)
model.eval()
scripted_model = torch.jit.script(model)
scripted_model.save("fbdeit_scripted.pt")

サイズ約 346MB のスクリプト化されたモデルファイル fbdeit_scripted.pt が生成されます。

 

DeiT を量子化する

ほぼ同じである推論精度を保持する一方で訓練モデルのサイズを本質的に減じるには、量子化がモデルに適用できます。DeiT で使用される transformer モデルのおかげで、動的量子化をモデルに容易に適用できます、何故ならば動的量子化は LSTM と transformer モデルのために最善に動作するからです (より詳細については ここ を見てください)。

今は下のコードを実行します :

# Use 'fbgemm' for server inference and 'qnnpack' for mobile inference
backend = "fbgemm" # replaced with qnnpack causing much worse inference speed for quantized model on this notebook
model.qconfig = torch.quantization.get_default_qconfig(backend)
torch.backends.quantized.engine = backend

quantized_model = torch.quantization.quantize_dynamic(model, qconfig_spec={torch.nn.Linear}, dtype=torch.qint8)
scripted_quantized_model = torch.jit.script(quantized_model)
scripted_quantized_model.save("fbdeit_scripted_quantized.pt")

これはモデル fbdeit_quantized_scripted.pt のスクリプト化そして量子化されたバージョンを生成します、サイズ約 89MB を持ち、346MB の非量子化モデルサイズの 74% 縮小です!

同じ推論結果を生成するために scripted_quantized_model を利用できます :

out = scripted_quantized_model(img)
clsidx = torch.argmax(out)
print(clsidx.item())
# The same output 269 should be printed
269

 

DeiT を最適化する

モバイル上で量子化そしてスクリプト化されたモデルを使用する前の最後のステップはそれを最適化することです :

from torch.utils.mobile_optimizer import optimize_for_mobile
optimized_scripted_quantized_model = optimize_for_mobile(scripted_quantized_model)
optimized_scripted_quantized_model.save("fbdeit_optimized_scripted_quantized.pt")

生成された fbdeit_optimized_scripted_quantized.pt ファイルは量子化、スクリプト化、しかし非最適化モデルとおよそ同じサイズを持ちます。推論結果は同じままです。

out = optimized_scripted_quantized_model(img)
clsidx = torch.argmax(out)
print(clsidx.item())
# Again, the same output 269 should be printed
269

 

インタープリタを使用する

Lite インタープリタがどのくらいのモデルサイズ縮小と推論スピードアップの結果を出せるかを見るために、モデルの lite バージョンを作成しましょう。

optimized_scripted_quantized_model._save_for_lite_interpreter("fbdeit_optimized_scripted_quantized_lite.ptl")
ptl = torch.jit.load("fbdeit_optimized_scripted_quantized_lite.ptl")

モバイル上で lite バージョンを実行するとき lite モデルサイズは非 lite バージョンと同等ですが、推論スピードアップは期待されます。

 

推論スピードを比較する

推論スピードが 4 つのモデル – 元のモデル、スクリプト化モデル、量子化とスクリプト化モデル、最適化・量子化とスクリプト化モデル – についてどのように異なるかを見るには、下のコードを実行します :

with torch.autograd.profiler.profile(use_cuda=False) as prof1:
    out = model(img)
with torch.autograd.profiler.profile(use_cuda=False) as prof2:
    out = scripted_model(img)
with torch.autograd.profiler.profile(use_cuda=False) as prof3:
    out = scripted_quantized_model(img)
with torch.autograd.profiler.profile(use_cuda=False) as prof4:
    out = optimized_scripted_quantized_model(img)
with torch.autograd.profiler.profile(use_cuda=False) as prof5:
    out = ptl(img)

print("original model: {:.2f}ms".format(prof1.self_cpu_time_total/1000))
print("scripted model: {:.2f}ms".format(prof2.self_cpu_time_total/1000))
print("scripted & quantized model: {:.2f}ms".format(prof3.self_cpu_time_total/1000))
print("scripted & quantized & optimized model: {:.2f}ms".format(prof4.self_cpu_time_total/1000))
print("lite model: {:.2f}ms".format(prof5.self_cpu_time_total/1000))
original model: 153.53ms
scripted model: 127.06ms
scripted & quantized model: 112.28ms
scripted & quantized & optimized model: 112.35ms
lite model: 137.46ms

Google Colab 上で実行した結果は :

original model: 1236.69ms
scripted model: 1226.72ms
scripted & quantized model: 593.19ms
scripted & quantized & optimized model: 598.01ms
lite model: 600.72ms

以下の結果は各モデルでかかった推論時間と元のモデルに相対する各モデルのパーセンテージ削減を要約しています。

import pandas as pd
import numpy as np

df = pd.DataFrame({'Model': ['original model','scripted model', 'scripted & quantized model', 'scripted & quantized & optimized model', 'lite model']})
df = pd.concat([df, pd.DataFrame([
    ["{:.2f}ms".format(prof1.self_cpu_time_total/1000), "0%"],
    ["{:.2f}ms".format(prof2.self_cpu_time_total/1000),
     "{:.2f}%".format((prof1.self_cpu_time_total-prof2.self_cpu_time_total)/prof1.self_cpu_time_total*100)],
    ["{:.2f}ms".format(prof3.self_cpu_time_total/1000),
     "{:.2f}%".format((prof1.self_cpu_time_total-prof3.self_cpu_time_total)/prof1.self_cpu_time_total*100)],
    ["{:.2f}ms".format(prof4.self_cpu_time_total/1000),
     "{:.2f}%".format((prof1.self_cpu_time_total-prof4.self_cpu_time_total)/prof1.self_cpu_time_total*100)],
    ["{:.2f}ms".format(prof5.self_cpu_time_total/1000),
     "{:.2f}%".format((prof1.self_cpu_time_total-prof5.self_cpu_time_total)/prof1.self_cpu_time_total*100)]],
    columns=['Inference Time', 'Reduction'])], axis=1)

print(df)

"""
        Model                             Inference Time    Reduction
0   original model                             1236.69ms           0%
1   scripted model                             1226.72ms        0.81%
2   scripted & quantized model                  593.19ms       52.03%
3   scripted & quantized & optimized model      598.01ms       51.64%
4   lite model                                  600.72ms       51.43%
"""
original model: 153.53ms
scripted model: 127.06ms
scripted & quantized model: 112.28ms
scripted & quantized & optimized model: 112.35ms
lite model: 137.46ms

 

更に学習する

 

以上