PyTorchを使った転移学習の実践ガイド
Practical guide for transfer learning using PyTorch.
Naresh さんと Gaurav さんと共著しました。
この記事では、転移学習の「何、なぜ、そしてどのように」について説明します。
- 何が転移学習なのか
- なぜ転移学習を使用するべきなのか
- どのように実際の分類タスクで転移学習を使用できるか
具体的には、以下の転移学習の側面をカバーします。
- 転移学習のアイデアとその利点の背景
- ベースモデル選択の直感を開発する ( notebook )
- 異なる選択肢とそのトレードオフについて議論する
- PyTorchを使用した画像分類タスクの実装 ( notebook )
- さまざまなベースモデルのパフォーマンス比較
- 転移学習に関する学習リソースと最新状況
転移学習は広大で成長中の分野であり、この記事ではその一部の側面について説明しました。ただし、転移学習を議論するディープラーニングのオンラインコミュニティが多数あります。たとえば、以下は、モデルをゼロからトレーニングするよりも転移学習を利用してより高いベンチマークを達成する方法についての良い記事です。
- ChatGPTのバイアスを解消するバックパック:バックパック言語モデルはトランスフォーマーの代替AI手法です
- DeepMindのAIマスターゲーマー:2時間で26のゲームを学習
- 単一モダリティとの友情は終わりました – 今やマルチモダリティが私の親友です:CoDiは、合成可能な拡散による任意から任意への生成を実現できるAIモデルです
対象読者と前提条件
- 分類モデルを定義してトレーニングするなどの基本的な機械学習(ML)の概念に精通していること
- PyTorchとtorchvisionに精通していること
次のセクションでは、転移学習を正式に紹介して例を示します。
転移学習とは何ですか?
このページから、
「転移学習は、タスクのために開発されたモデルを、2番目のタスクのモデルの出発点として再利用する機械学習手法です。」
ディープラーニングモデルは、トレーニングプロセス中に損失関数を使用して最適化された重みのネットワークです。ネットワークの重みは通常、トレーニングプロセスの開始前にランダムに初期化されます。転移学習では、関連するタスクでトレーニングされた事前にトレーニングされたモデルを使用します。これにより、ランダムに初期化された重みよりも優れた初期重みセットが得られます。その後、特定のタスクに対して事前にトレーニングされた重みをさらに最適化します。
fast.aiのJeremy Howard氏は、
「可能な限り、事前トレーニングされたモデルでニューラルネットワークトレーニングを開始し、微調整することを目指す必要があります。ランダムな重みで開始することは本当に望ましくありません。なぜなら、それは全く何もできないモデルで開始することを意味するからです!事前トレーニングでは、ゼロから開始するよりも1000倍少ないデータを使用できます。」
以下では、転移学習の概念を人間に関連付けて考える方法を紹介します。
転移学習の人間によるアナロジー
- モデルトレーニング:子供が生まれてから立ったり、バランスをとったり、歩いたりするまでには時間がかかります。この間、彼らは身体の筋肉を作り上げ、脳は立つ、バランスをとる、歩くというスキルを理解し内部化するために学習します。成功と失敗が混在する試行を何度も繰り返して、一定の一貫性を持って立ち、バランスをとり、歩くまでに至ります。これは、トレーニングエポックが多くかかるディープラーニングモデルのトレーニングに似ています(たとえば、1000 ImageNetクラスの1つに属する画像を分類するなどの一般的なタスクを学習する)。
- 転移学習:歩くことを学んだ子供は、ジャンプや走るなどの関連する高度なスキルを学ぶのがはるかに簡単です。転移学習は、すでに一般的なスキルを学んだ事前トレーニングされたモデルを効率的に他の関連するタスクのトレーニングに活用することに類似しています。
転移学習の直感的な理解と人間の学習との類似点ができたので、MLモデルで転移学習を使用する理由について見ていきましょう。
なぜ転移学習を使用するべきなのか?
画像分類、画像セグメンテーション、オブジェクトローカリゼーション、または検出などの多くのビジョンAIタスクは、分類、セグメンテーション、または検出する特定のオブジェクトが異なるだけです。これらのタスクでトレーニングされたモデルは、トレーニングデータセットのオブジェクトの特徴を学習しています。したがって、関連するタスクに簡単に適応できます。たとえば、画像内に車が存在するかどうかを識別するためにトレーニングされたモデルは、猫や犬を識別するために微調整できます。
転移学習の主な利点は、タスクに対してより高い精度を実現できることです。以下にその利点を分解して説明します:
- 訓練効率:一般的な特徴をすでに学習した事前学習済みモデルから始め、モデルを特定のタスクに微調整するだけで済むため、より迅速に(つまり、より少ない訓練エポックで)行うことができる。
- モデル精度:同じリソースを使用してゼロからモデルを訓練する場合に比べ、転移学習を使用すると大幅なパフォーマンス向上が得られる可能性がある。ただし、特定のタスクに対して適切な事前学習済みモデルを選択することが重要です。
- 訓練データサイズ:事前学習済みモデルは、タスク固有の特徴と重複する多くの特徴をすでに識別しているため、ドメイン固有のデータを少なく使用して事前学習済みモデルを訓練することができる。これは、特定のタスクに対してラベル付きデータがあまりない場合に役立ちます。
では、実際に転移学習をどのように実行するのでしょうか?次のセクションでは、花の分類タスクでPyTorchで転移学習を実装します。
PyTorchでの転移学習
PyTorchで転移学習を行うには、まずデータセットと事前学習された画像分類用ビジョンモデルを選択する必要があります。この記事では、torch-vision(PyTorchで使用されるドメインライブラリ)を使用することに焦点を当てています。このような事前学習済みモデルやデータセットをどこで見つけるかを理解しましょう。
画像分類のための事前学習済みビジョンモデルをどこで見つけるか?
高品質な事前学習済み画像分類モデルを提供するウェブサイトがたくさんあります。たとえば:
- Torchvision
- PyTorch Image Models
この記事では、torchvisionから事前学習済みモデルを使用します。これらのモデルがどのように訓練されたかについて少し学ぶ価値があります。次に、その問題を探求しましょう!
torchvisionモデルはどのデータセットで事前学習されていますか?
画像に関連するビジョンタスクでは、torchvisionモデルは通常、ImageNetデータセットで事前学習されています。研究者やモデルの事前学習ビジョンモデルによって使用される最も人気のあるImageNetサブセットには、1000クラスを横断する約120万枚の画像が含まれています。ImageNet分類は、次の理由で事前学習タスクとして使用されます:
- 研究コミュニティにとってすでに利用可能である
- 含まれる画像の幅広さとバラエティ
- 様々な研究者による使用 – Imagenet 1k分類の共通の基準を使用して結果を比較することが魅力的であるため
ImageNetチャレンジの歴史、背景、および完全なデータセットに関する情報については、このWikipediaページを参照してください。
事前学習済みモデルを使用する際の法的考慮事項
ImageNetは、非商用研究目的のためにリリースされています (https://image-net.org/download)。したがって、ImageNetで事前学習されたモデルの重みを商用目的で合法的に使用できるかどうかは明確ではありません。その場合は、法的アドバイスを求めてください。
これで、転移学習に使用する事前学習済みモデルがどこにあるかを知ったので、カスタム分類タスクで使用するデータセットをどこで入手できるかを見てみましょう。
データセット:Oxford Flowers 102
PyTorchを使用して転移学習を説明するために、Flowers 102データセットを使用します。このデータセットを使用して、Flowers 102データセット内の画像を102のカテゴリのいずれかに分類するモデルを訓練します。これは、予測されるクラスが相互に排他的である多クラス(単一ラベル)の分類問題です。Torchvisionを使用することにより、このデータセットをすでに使用できるようになっています。
Flowers 102データセットは、OxfordのVisual Geometry Groupから入手しました。データセットの使用に関するライセンス条項については、ページを参照してください。
次に、このプロセスに必要な高レベルの手順を見てみましょう。
転移学習とはどのように機能するのでしょうか?
画像分類タスクに対する転移学習は、図1に示すように、3つのステップの連続として表示できます。これらのステップは次のとおりです:
- 分類器レイヤの置換:この段階では、事前学習済みモデルの最後の “分類ヘッド”を識別して、自分自身の “分類ヘッド” に置き換えます。この “分類ヘッド” には、適切な出力特徴量数 (この例では102) が必要です。
- 特徴量抽出:この段階では、追加された分類レイヤ以外のすべてのモデルレイヤを凍結し(これらのレイヤを訓練不可にする)、新しく追加されたレイヤだけを訓練します。
- ファインチューニング:この段階では、モデルのいくつかのサブセットのレイヤをアンフリーズします(レイヤをアンフリーズすると、そのレイヤを訓練可能にします)。この記事では、モデルのすべてのレイヤをアンフリーズし、機械学習 (ML) PyTorch モデルを訓練する方法について説明します。
これらの各段階には、知っておく必要がある多くの追加の詳細とニュアンスがあります。これらの詳細については、すぐに説明します。今は、特徴抽出とファインチューニングの2つの主要な段階に深く入りましょう。
特徴抽出とファインチューニング
特徴抽出とファインチューニングについての詳細はこちらをご覧ください。
- 転移学習における特徴抽出とファインチューニングの違いは何ですか?
- 忘却しない学習
以下の図は、視覚的に特徴抽出とファインチューニングを説明しています。
カスタム分類タスク、このタスクで使用する事前学習済みモデル、転移学習の仕組みについて理解したので、転移学習を実行する具体的なコードをいくつか見てみましょう。
コードを見せてください
このセクションでは、探索的モデル分析、初期モデル選択、モデルの定義方法、転移学習ステップ(上記で説明した)、過学習を防ぐ方法などの概念を学びます。このデータセットの train/val/test スプリットについて説明し、結果を解釈します。
この実験の完全なコードは、こちら (pre-trained modelsを使用したFlowers102分類) にあります。探索的モデル分析のセクションは別のノートブックにあります。
探索的モデル分析
データサイエンスにおける探索的データ分析と同様に、転移学習の最初のステップは探索的モデル分析です。このステップでは、画像分類タスクに使用可能なすべての事前学習済みモデルを探索し、各モデルの構造を確認します。
一般的に、どのモデルがタスクに最適かはわからないため、有望であるか適用可能であるかのいくつかのモデルを試すことは珍しくありません。この仮想的なシナリオでは、モデルのサイズが重要ではないと仮定します(これらのモデルをモバイルデバイスやエッジデバイスなどに展開したくない場合など)。まず、torchvision で利用可能な事前学習済み分類モデルのリストを見てみましょう。
classification_models = torchvision.models.list_models(module=torchvision.models)
print(len(classification_models), "classification models:", classification_models)
出力:
80 classification models: ['alexnet', 'convnext_base', 'convnext_large', 'convnext_small', 'convnext_tiny', 'densenet121', 'densenet161', 'densenet169', 'densenet201', 'efficientnet_b0', 'efficientnet_b1', 'efficientnet_b2', 'efficientnet_b3', 'efficientnet_b4', 'efficientnet_b5', 'efficientnet_b6', 'efficientnet_b7', 'efficientnet_v2_l', 'efficientnet_v2_m', 'efficientnet_v2_s', 'googlenet', 'inception_v3', 'maxvit_t', 'mnasnet0_5', 'mnasnet0_75', 'mnasnet1_0', 'mnasnet1_3', 'mobilenet_v2', 'mobilenet_v3_large', 'mobilenet_v3_small', 'regnet_x_16gf', 'regnet_x_1_6gf', 'regnet_x_32gf', 'regnet_x_3_2gf', 'regnet_x_400mf', 'regnet_x_800mf', 'regnet_x_8gf', 'regnet_y_128gf', 'regnet_y_16gf', 'regnet_y_1_6gf', 'regnet_y_32gf', 'regnet_y_3_2gf', 'regnet_y_400mf', 'regnet_y_800mf', 'regnet_y_8gf', 'resnet101', 'resnet152', 'resnet18', 'resnet34', 'resnet50', 'resnext101_32x8d', 'resnext101_64x4d', 'resnext50_32x4d', 'shufflenet_v2_x0_5', 'shufflenet_v2_x1_0', 'shufflenet_v2_x1_5', 'shufflenet_v2_x2_0', 'squeezenet1_0', 'squeezenet1_1', 'swin_b', 'swin_s', 'swin_t', 'swin_v2_b', 'swin_v2_s', 'swin_v2_t', 'vgg11', 'vgg11_bn', 'vgg13', 'vgg13_bn', 'vgg16', 'vgg16_bn', 'vgg19', 'vgg19_bn', 'vit_b_16', 'vit_b_32', 'vit_h_14', 'vit_l_16', 'vit_l_32', 'wide_resnet101_2', 'wide_resnet50_2']
わぁ!多くのモデルから選べるリストですね!もし混乱しているなら、心配しないでください。次のセクションでは、転移学習を行うための初期モデル選択の際に考慮すべき要因について見ていきます。
初期モデル選択
今、選択肢が80ある候補モデルリストがあるため、実験を実行できる数少ないモデルに絞り込む必要があります。事前学習モデルのバックボーンの選択はハイパーパラメータであり、最良のものがどれかを見つけるために複数のオプションを探索することができます(そしてすべきです)。実験を実行することは費用と時間がかかります。すべてのモデルを試すことはできないため、3〜4つのモデルにリストを絞り込むことを試みます。
以下の事前学習モデルバックボーンを使用することにしました。
- Vgg16:135Mパラメータ
- ResNet50:23Mパラメータ
- ResNet152:58Mパラメータ
以下は、これら3つを最初に選んだ理由です。
- モデルサイズや推論レイテンシに制約がないため、超効率的なモデルを見つける必要はありません。モバイルデバイス向けのさまざまなビジョンモデルの比較研究を行う場合は、「Comparison and Benchmarking of AI Models and Frameworks on Mobile Devices」という論文を読んでください。
- 選択したモデルは、ビジョンMLコミュニティでかなり人気があり、分類タスクの良い選択肢になる傾向があります。これらのモデルに関する論文の引用数は、これらのモデルがどの程度効果的であるかの比較的妥当な代理指標として使用できます。ただし、長い間存在するAlexNetなどのモデルの論文には、デフォルトの選択肢として本格的な分類タスクに使用しないにもかかわらず、より多くの引用があるという潜在的な偏りに注意してください。
- モデルアーキテクチャ内でも、多数のフレーバーやモデルサイズが存在する傾向があります。たとえば、EfficientNetはB0からB7というトリムで提供されています。これらのトリムが何を意味するかの詳細については、特定のモデルの論文を参照してください。
torchvisionで利用可能な事前学習分類モデルのさまざまな論文の引用数。
- Resnet:165k
- AlexNet:132k
- Vgg16:102k
- MobileNet:19k
- Vision Transformers:16k
- EfficientNet:12k
- ShuffleNet:6k
事前学習モデルの選択に影響する要因についてさらに読みたい場合は、以下の記事を読んでください。
- 転移学習に使用する4つの事前学習CNNモデル
- 畳み込みニューラルネットワーク用の最適な事前学習モデルの選択方法?
- 代表的な深層ニューラルネットワークアーキテクチャのベンチマーク分析
これらのモデルの分類ヘッドをチェックしてみましょう。
vgg16 = torchvision.models.vgg16_bn(weights=None)
resnet50 = torchvision.models.resnet50(weights=None)
resnet152 = torchvision.models.resnet152(weights=None)
print(“vgg16 \n “, vgg16.classifier)
print(“resnet50 \n “, resnet50.fc)
print(“resnet152 \n “, resnet152.fc)
vgg16
Sequential(
(0): Linear(in_features=25088, out_features=4096, bias=True)
(1): ReLU(inplace=True)
(2): Dropout(p=0.5, inplace=False)
(3): Linear(in_features=4096, out_features=4096, bias=True)
(4): ReLU(inplace=True)
(5): Dropout(p=0.5, inplace=False)
(6): Linear(in_features=4096, out_features=1000, bias=True)
)
resnet50
Linear(in_features=2048, out_features=1000, bias=True)
resnet152
Linear(in_features=2048, out_features=1000, bias=True)
探索的モデル分析の完全なノートブックはこちらです。
今回は、3つの事前学習済みモデルで実験を実行し、それぞれに転移学習を行うための抽象化とクラスを定義し、これらの実験を実行およびトラッキングするのに役立つものを定義しましょう。
事前学習済みモデルをラップするためのPyTorchモデルの定義
簡単な探索を許可するために、Flowers102Classifierという名前のPyTorchモデルを定義し、この演習全体で使用します。このクラスに機能を徐々に追加して、最終目標を達成するまで進めます。Flowers102分類の転移学習に関する完全なノートブックはここにあります。
以下のセクションでは、転移学習を実行するために必要な各機械的ステップについて詳しく説明します。
旧分類ヘッドの新しいものへの置き換え
ImageNet分類タスクで事前学習されたこれらのモデルの既存の分類ヘッドには、1000の出力フィーチャがあります。フラワー分類のカスタムタスクには102の出力フィーチャが必要です。したがって、最終分類ヘッド(層)を、102の出力フィーチャを持つ新しいヘッド(層)に置き換える必要があります。
クラスのコンストラクタには、事前学習済みの重みを使用してtorchvisionから興味のある事前学習済みモデルをロードするコードが含まれ、102クラスのカスタム分類ヘッドで分類ヘッドを置き換えます。
def __init__(self, backbone, load_pretrained):
super().__init__()
assert backbone in backbones
self.backbone = backbone
self.pretrained_model = None
self.classifier_layers = []
self.new_layers = []
if backbone == "resnet50":
if load_pretrained:
self.pretrained_model = torchvision.models.resnet50(
weights=torchvision.models.ResNet50_Weights.IMAGENET1K_V2
)
else:
self.pretrained_model = torchvision.models.resnet50(weights=None)
# end if
self.classifier_layers = [self.pretrained_model.fc]
# Replace the final layer with a classifier for 102 classes for the Flowers 102 dataset.
self.pretrained_model.fc = nn.Linear(
in_features=2048, out_features=102, bias=True
)
self.new_layers = [self.pretrained_model.fc]
elif backbone == "resnet152":
if load_pretrained:
self.pretrained_model = torchvision.models.resnet152(
weights=torchvision.models.ResNet152_Weights.IMAGENET1K_V2
)
else:
self.pretrained_model = torchvision.models.resnet152(weights=None)
# end if
self.classifier_layers = [self.pretrained_model.fc]
# Replace the final layer with a classifier for 102 classes for the Flowers 102 dataset.
self.pretrained_model.fc = nn.Linear(
in_features=2048, out_features=102, bias=True
)
self.new_layers = [self.pretrained_model.fc]
elif backbone == "vgg16":
if load_pretrained:
self.pretrained_model = torchvision.models.vgg16_bn(
weights=torchvision.models.VGG16_BN_Weights.IMAGENET1K_V1
)
else:
self.pretrained_model = torchvision.models.vgg16_bn(weights=None)
# end if
self.classifier_layers = [self.pretrained_model.classifier]
# Replace the final layer with a classifier for 102 classes for the Flowers 102 dataset.
self.pretrained_model.classifier[6] = nn.Linear(
in_features=4096, out_features=102, bias=True
)
self.new_layers = [self.pretrained_model.classifier[6]]
特徴抽出の後にファインチューニングを実行するため、新しく追加されたレイヤーをself.new_layersリストに保存します。これにより、重みがトレーニング可能かどうかを決定するために、これらのレイヤーの重みを設定するのに役立ちます。
旧分類ヘッドを新しいランダムに初期化された分類ヘッドに置き換えたので、その重みをトレーニングして、モデルが正確な予測を行えるようにする必要があります。これには、特徴抽出とファインチューニングが含まれます。それについて次に見ていきましょう。
転移学習(トレーニング可能なパラメータと学習率)
転移学習には、特徴抽出とファインチューニングを順番に実行する必要があります。それらがなぜその順序で実行する必要があるのか、および各転移学習段階のトレーニング可能なパラメータをどのように扱うかについて詳しく見ていきましょう。
特徴抽出:モデルのすべてのレイヤーの重みのrequires_gradをFalseに設定し、新しく追加されたレイヤーに対してのみrequires_gradをTrueに設定します。
新しいレイヤーを16エポック学習し、学習率を1e-3に設定します。これにより、新しいレイヤーがネットワークの特徴抽出部分の重みに合わせて重みを調整および適応することができるようになります。ネットワークの残りのレイヤーをフリーズし、新しいレイヤーのみをトレーニングすることが重要です。これにより、ネットワークがすでに学習したことを忘れさせることがなくなります。以前のレイヤーをフリーズしない場合、新しい分類ヘッドを追加したときにランダムに初期化されたジャンクの重みで再トレーニングされてしまいます。
ファインチューニング:モデルのすべてのレイヤーの重みに対してrequires_gradをTrueに設定します。ネットワーク全体を8エポック学習します。ただし、この場合は異なる学習率戦略を採用しています。入力レイヤーに向かって(出力分類ヘッドから離れて)、学習率(LR)を減衰させます。初期レイヤーは画像に関する基本的な特徴を学習しているため、ほとんどのビジョンAIタスクに共通するものです。したがって、初期レイヤーは、学習した内容を妨げないように非常に低いLRでトレーニングされます。分類ヘッドに向かってモデルを下に移動するにつれて、モデルは何らかのタスク固有のものを学習しているため、後のレイヤーをより高いLRでトレーニングすることが合理的です。ここでは異なる戦略を採用できます。この場合、私たちは2つの異なる戦略を使用して、両方の効果を示しています。
- VGG16:vgg16ネットワークの場合、LRを線形に減衰させ、LR=1e-4からLR=1e-7(分類層のLRの1000倍低い)に減衰させます。特徴抽出フェーズには44個のレイヤーがあるため、各レイヤーには前のレイヤーよりも2.3e-6低いLRが割り当てられます。
- ResNet:ResNet(50/152)ネットワークの場合、LRを指数関数的に減衰させ、上に移動するたびにLRを3倍減らします。
特徴抽出およびファインチューニングのフリーズと解除に関するコードは、以下のfine_tune()関数に示されています。
def fine_tune(self, what: FineTuneType):
# The requires_grad parameter controls whether this parameter is
# trainable during model training.
m = self.pretrained_model
for p in m.parameters():
p.requires_grad = False
if what is FineTuneType.NEW_LAYERS:
for l in self.new_layers:
for p in l.parameters():
p.requires_grad = True
elif what is FineTuneType.CLASSIFIER:
for l in self.classifier_layers:
for p in l.parameters():
p.requires_grad = True
else:
for p in m.parameters():
p.requires_grad = True
コードスニペット:特徴抽出(NEW_LAYERS)およびファインチューニング(ALL)フェーズでrequires_gradを使用してパラメーターをフリーズおよびアンフリーズする方法。
PyTorchでは、各レイヤーに異なるLRを設定する方法は、転移学習中に使用されるオプティマイザに必要なLRを指定することです。ノートブックでは、Adamオプティマイザを使用します。以下のget_optimizer_params()メソッドは、転移学習で使用するAdam(またはその他の)オプティマイザに渡すオプティマイザパラメーターを取得します。
def get_optimizer_params(self):
"""This method is used only during model fine-tuning when we need to
set a linearly or exponentially decaying learning rate (LR) for the
layers in the model. We exponentially decay the learning rate as we
move away from the last output layer.
"""
options = []
if self.backbone == "vgg16":
# For vgg16, we start with a learning rate of 1e-3 for the last layer, and
# decay it to 1e-7 at the first conv layer. The intermediate rates are
# decayed linearly.
lr = 0.0001
options.append(
{
"params": self.pretrained_model.classifier.parameters(),
"lr": lr,
}
)
final_lr = lr / 1000.0
diff_lr = final_lr - lr
lr_step = diff_lr / 44.0
for i in range(43, -1, -1):
options.append(
{
"params": self.pretrained_model.features[i].parameters(),
"lr": lr + lr_step * (44 - i),
}
)
# end for
elif self.backbone in ["resnet50", "resnet152"]:
# For the resnet class of models, we decay the LR exponentially and reduce
# it to a third of the previous value at each step.
layers = ["conv1", "bn1", "layer1", "layer2", "layer3", "layer4", "fc"]
lr = 0.0001
for layer_name in reversed(layers):
options.append(
{
"params": getattr(self.pretrained_model, layer_name).parameters(),
"lr": lr,
}
)
lr = lr / 3.0
# end for
# end if
return options
# end def
コードスニペット:モデルをファインチューニングする際に、各レイヤーごとに異なる学習率を使用する
各パラメータに対応するLRを持つモデルパラメータがある場合、単一のコードラインでオプティマイザに渡すことができます。get_optimizer_params()によって返される辞書で指定されていないウェイトを持つパラメータには、デフォルトLR 1e-8が使用されます。
optimizer = torch.optim.Adam(fc.get_optimizer_params(), lr=1e-8)
コードスニペット:AdamオプティマイザにパラメータをそれぞれのLRで渡す。
転移学習を実行する方法を理解したので、モデルをファインチューニングする前に考慮する必要がある他の点を見てみましょう。これには、過学習を防止するために必要な手順と、適切なトレイン/バリデーション/テスト分割の選択が含まれます。
過学習の防止
私たちは、ノートブックで以下のデータ拡張技術をトレーニングデータに使用して、過学習を防止し、モデルが得られないデータに基づいて予測できるようにするための特徴を学習するために以下のデータ拡張技術を使用しています。
- 色のゆらぎ
- 水平フリップ
- 回転
- シアー
バリデーション分割にはデータ拡張が適用されません。
モデルの複雑さを低減して過学習を防止する正則化技術であるウェイト減衰を探索することも重要です。
トレイン/バリデーション/テスト分割
Flowers 102データセットの著者は、1020/1020/6149のサイズのトレイン/バリデーション/テスト分割を推奨しています。多くの著者は異なる方法をとります。例えば、
- ResNet strikes back論文では、著者はトレイン+バリデーション(2040枚の画像)分割をトレインセットとして使用し、テストセットをテストセットとして使用しています。バリデーション分割があるかどうかは不明です。
- Flowers 102の分類に関するこの記事では、著者は6149のテスト分割をトレイン分割として使用しています。
- このノートブックでは、著者はそれぞれ6552、818、819のサイズのトレイン/バリデーション/テスト分割を使用しています。
著者が何をしているかを知る唯一の方法は、論文やコードを読むことです。
この記事のノートブック(本記事)では、サイズ6149の分割をトレイン分割として使用し、サイズ2040の分割をバリデーション分割として使用しています。私たちはここで競争しようとしていないため、テスト分割は使用しません。
この時点で、このノートブックを訪問し、すべての手順を実行し、結果を表示することができるようになりました。KaggleまたはGoogle Colabでノートブックをクローンして、GPUで実行してください。Google Colabを使用する場合は、データセットと事前トレーニング済みモデルがダウンロードされる場所、およびファインチューニングされたモデルの最適な重みが保存される場所など、いくつかのパスを修正する必要があります。
以下では、転移学習実験の結果を見ていきます!
結果
以下の結果には共通のテーマがあります。
- 特徴抽出ステップのみの場合、ほぼすべてのネットワークが91%〜94%の精度を持っています。
- ほとんどのネットワークは非常によく機能し、ファインチューニングステップ後に96%以上の精度を達成します。これは、転移学習においてファインチューニングステップが本当に役立つことを示しています。
ネットワークのパラメータ数には大きな違いがあり、vgg16が135Mパラメータ、ResNet50が23Mパラメータ、ResNet152が58Mパラメータであることを示しています。これは、同等の精度とパフォーマンスを持つより小さなネットワークを見つけることができる可能性があることを示唆しています。
垂直赤線は、特徴抽出(16エポック)からファインチューニング(8エポック)に切り替えたエポックを示しています。ファインチューニングに切り替えたとき、すべてのネットワークが精度を向上させたことがわかります。これは、特徴抽出後のファインチューニングが非常に効果的であることを示しています。
記事のまとめ
- 転移学習は、類似したが関連性の低いタスク上で事前にトレーニングされたネットワークから開始してネットワークを効率的にトレーニングする方法です。
- Torchvisionは、転移学習中に研究者が使用できるImageNetで事前にトレーニングされた多くのモデルを提供しています。
- プリトレーニングされたモデルを本番環境で使用する場合は、データセットのライセンスまたは使用条件に違反しないように注意する必要があります。
- 転移学習には、特徴抽出とファインチューニングの2つのステップが含まれており、特定の順序で実行する必要があります。
もっと学びたい方はこちら
異なるデータセットで事前学習されたモデルからカスタムタスクの転移学習を実行する方法を知った今、事前学習(前提タスク)に別のデータセットを使用せずに自分自身のデータセットを使用できるとしたら、素晴らしいことではないでしょうか? 実際、これは実現可能になっています!
最近、研究者や実践者は、自己教示学習を使用してモデルの事前学習(前提タスクの学習)を実行する方法を使用しており、これにより、モデルが本番で使用する予定のターゲットデータセットと同じ分布を持つデータセットでモデルをトレーニングするという利点があります。 自己教示プレトレーニングおよび階層的プレトレーニングについて詳しく学びたい場合は、2021年に発表された「self-supervised pretraining improves self-supervised pretraining」という論文をご覧ください。
特定のタスクのデータを所有している場合、自己教示学習を使用してモデルの事前トレーニングを行い、ImageNetデータセットを事前トレーニングステップで使用する必要がないため、ImageNetデータセットの使用に関して問題がない状態に留まることができます。
使用される用語集
- 分類ヘッド:PyTorchでは、これは多数の入力特徴を一連の出力特徴にマップするnn.Linearレイヤーです。
- 重みを固定する:重みをトレーニング不可能にします。PyTorchでは、requires_grad=Falseを設定することで行われます。
- 重みを解除する(または解凍する):重みをトレーニング可能にします。PyTorchでは、requires_grad=Trueを設定することで行われます。
- 自己教示学習:人間が生成したラベルがないデータでMLモデルをトレーニングする方法。ただし、ラベルは自動的にまたは機械的に生成される可能性があります。
参考文献およびさらなる読書
- PyTorchで事前トレーニングされたモデルを微調整する方法に関するアイデア
- 深層学習へのダイブ:ファインチューニング
- 自己教示学習とコンピュータビジョン
- ディープラーニングの転移学習の優しいイントロダクション
- ノートブック:探索的モデル分析
- ノートブック:転移学習を使用したFlowers 102分類
Dhruv Mataniは、PyTorch、CNN、ビジョン、音声、テキストAIに焦点を当てた機械学習愛好家です。オンデバイスAI、モデル最適化および量子化、MLおよびデータインフラストラクチャの専門家です。https://efficientdlbook.com/でEfficient PyTorchの章を執筆しています。彼の意見は、すべての雇用主(過去、現在、未来)のものではありません。
Nareshは、ニューラルネットワークの「学習」に深い関心を持っています。彼の仕事は、ニューラルネットワークのアーキテクチャに焦点を当て、単純なトポロジカル変更が彼らの学習能力を向上させる方法についてです。彼は、マイクロソフト、アマゾン、およびシトリックスでエンジニアリングの役割を務め、10年以上のプロのキャリアでディープラーニング分野に携わってきました。https://medium.com/u/1e659a80cffdでVoAGIで彼を見つけることができます。
Gauravは、Google Researchのスタッフソフトウェアエンジニアであり、Tiny MicrocontrollersからTensor Processing Unit(TPU)ベースのサーバーまで、効率的なトレーニングと推論のために大規模な機械学習モデルを最適化する研究プロジェクトをリードしています。彼の仕事は、YouTube、Cloud、Ads、Chromeなどのアクティブユーザー1億人以上に肯定的な影響を与えています。彼はまた、Manning PublicationのEfficient Machine Learningに関する本の著者でもあります。Googleの前に、Gauravは4.5年間Facebookで働き、FacebookのSearchシステムや大規模な分散データベースに大きく貢献しました。彼はStony Brook大学でコンピュータサイエンスの修士号を取得しています。
We will continue to update VoAGI; if you have any questions or suggestions, please contact us!
Was this article helpful?
93 out of 132 found this helpful
Related articles
- AWSが開発した目的に特化したアクセラレータを使用することで、機械学習ワークロードのエネルギー消費を最大90%削減できます
- Sealとは、大規模な3Dポイントクラウドに対して自己教示学習のための2Dビジョンファウンデーションモデルを活用し、「任意のポイントクラウドシーケンスをセグメント化する」AIフレームワークです
- NVIDIA CEO:クリエイターは生成的AIによって「スーパーチャージ」されるでしょう
- 量産自動運転におけるBEVパーセプション
- PyTorchモデルのパフォーマンス分析と最適化—Part2
- あなたのLLMアプリケーションは公開に準備ができていますか?
- 中国における大量生産自動運転の課題