ほとんどの実践者は、最初に畳み込みニューラル ネットワーク (CNN) アーキテクチャについて学びながら、それが次の XNUMX つの基本的なセグメントで構成されていることを学びます。
- 畳み込み層
- プーリング層
- 完全に接続されたレイヤー
ほとんどのリソースは 一部 私自身の本を含む、このセグメンテーションのバリエーション。 特にオンライン – 完全に接続されたレイヤーは、 平坦化層 そして(通常)複数 密な層.
これは以前は標準であり、VGGNets などのよく知られたアーキテクチャはこのアプローチを使用しており、次のようになります。
model = keras.Sequential([
keras.layers.MaxPooling2D((2, 2), strides=(2, 2), padding='same'),
keras.layers.Flatten(),
keras.layers.Dropout(0.5),
keras.layers.Dense(4096, activation='relu'),
keras.layers.Dropout(0.5),
keras.layers.Dense(4096, activation='relu'),
keras.layers.Dense(n_classes, activation='softmax')
])
ただし、何らかの理由で、VGGNet がこのアプローチを使用する実質的に最後のアーキテクチャであったことは、しばしば忘れられます。これは、明らかに計算上のボトルネックが生じるためです。 VGGNets のちょうど 7 年後 (および XNUMX 年前) に ResNets が公開されるとすぐに、すべての主流アーキテクチャはモデル定義を次のように終了しました。
model = keras.Sequential([
keras.layers.GlobalAveragePooling2D(),
keras.layers.Dense(n_classes, activation='softmax')
])
CNN の平坦化は 7 年間続いています。 7年! そして、それが学習経験と使用している計算リソースの両方に与える有害な影響について話している人は少ないようです.
多くのアカウントでは、平坦化よりもグローバル平均プーリングの方が適しています。 小さな CNN のプロトタイプを作成している場合は、グローバル プーリングを使用します。 CNN について誰かに教えている場合は、Global Pooling を使用してください。 MVP を作成している場合は、グローバル プーリングを使用します。 実際に必要な他のユースケースでは、平坦化レイヤーを使用してください。
ケーススタディ – フラット化 vs グローバル プーリング
グローバル プーリングは、すべての特徴マップを XNUMX つのマップに凝縮し、すべての関連情報を XNUMX つのマップにプールします。このマップは、複数のレイヤーではなく、XNUMX つの高密度の分類レイヤーによって簡単に理解できます。 通常、平均プーリングとして適用されます (GlobalAveragePooling2D
) または最大プーリング (GlobalMaxPooling2D
)、1D および 3D 入力でも機能します。
次のような機能マップを平坦化する代わりに (7, 7, 32)
長さ 1536 のベクトルに変換し、この長いベクトルからパターンを識別するために XNUMX つまたは複数のレイヤーをトレーニングします。 (7, 7)
そこから直接ベクトル化して分類します。 それはとても簡単です!
ResNets のようなネットワークのボトルネック レイヤーは、単なる 1536 ではなく、数万の機能に数えられることに注意してください。平坦化する場合、非常に非効率的な方法で奇妙な形のベクトルから学習するようにネットワークを苦しめています。 2D 画像がすべてのピクセル行でスライスされ、連結されて平面ベクトルになると想像してください。 垂直方向に 0 ピクセル離れていた XNUMX つのピクセルは、そうではありません。 feature_map_width
ピクセル離れて水平に! これは、空間的不変性を優先する分類アルゴリズムにとってはあまり問題にならないかもしれませんが、コンピューター ビジョンの他のアプリケーションにとっては概念的にも適切ではありません。
いくつかの密な層を持つ平坦化層を使用する小さな実証ネットワークを定義しましょう。
model = keras.Sequential([
keras.layers.Input(shape=(224, 224, 3)),
keras.layers.Conv2D(32, (3, 3), activation='relu'),
keras.layers.Conv2D(32, (3, 3), activation='relu'),
keras.layers.MaxPooling2D((2, 2), (2, 2)),
keras.layers.BatchNormalization(),
keras.layers.Conv2D(64, (3, 3), activation='relu'),
keras.layers.Conv2D(64, (3, 3), activation='relu'),
keras.layers.MaxPooling2D((2, 2), (2, 2)),
keras.layers.BatchNormalization(),
keras.layers.Flatten(),
keras.layers.Dropout(0.3),
keras.layers.Dense(64, activation='relu'),
keras.layers.Dense(32, activation='relu'),
keras.layers.Dense(10, activation='softmax')
])
model.summary()
要約はどのように見えますか?
...
dense_6 (Dense) (None, 10) 330
=================================================================
Total params: 11,574,090
Trainable params: 11,573,898
Non-trainable params: 192
_________________________________________________________________
おもちゃのネットワークの 11.5 万個のパラメーター – そして、より大きな入力でパラメーターが爆発するのを見てください。 11.5M パラメータ. EfficientNets は、これまでに設計された中で最高のパフォーマンスを発揮するネットワークの 6 つであり、最大 XNUMXM のパラメーターで動作し、実際のパフォーマンスとデータから学習する能力に関して、この単純なモデルと比較することはできません。
ネットワークをより深くすることで、この数を大幅に減らすことができます。これにより、特徴マップが平坦化される前に、より多くの最大プーリング (および潜在的にストライドされた畳み込み) が導入されます。 ただし、計算コストを削減するためにネットワークをより複雑にすることを検討してください。これはすべて、計画にレンチを投げかけている単一のレイヤーのためです。
レイヤーを深くすることは、データポイント間のより意味のある非線形の関係を抽出することであり、フラット化レイヤーに対応するために入力サイズを縮小することではありません。
グローバル プーリングを使用したネットワークは次のとおりです。
model = keras.Sequential([
keras.layers.Input(shape=(224, 224, 3)),
keras.layers.Conv2D(32, (3, 3), activation='relu'),
keras.layers.Conv2D(32, (3, 3), activation='relu'),
keras.layers.MaxPooling2D((2, 2), (2, 2)),
keras.layers.BatchNormalization(),
keras.layers.Conv2D(64, (3, 3), activation='relu'),
keras.layers.Conv2D(64, (3, 3), activation='relu'),
keras.layers.MaxPooling2D((2, 2), (2, 2)),
keras.layers.BatchNormalization(),
keras.layers.GlobalAveragePooling2D(),
keras.layers.Dropout(0.3),
keras.layers.Dense(10, activation='softmax')
])
model.summary()
概要?
dense_8 (Dense) (None, 10) 650
=================================================================
Total params: 66,602
Trainable params: 66,410
Non-trainable params: 192
_________________________________________________________________
ずっといい! このモデルをさらに深く掘り下げると、パラメーター数が増え、新しいレイヤーでより複雑なデータ パターンをキャプチャできる可能性があります。 ただし、単純に行うと、VGGNet をバインドしたのと同じ問題が発生します。
さらに進む – ハンドヘルド エンド ツー エンド プロジェクト
あなたの好奇心旺盛な性質は、さらに先へ進みたいと思わせますか? 私たちは私たちをチェックアウトすることをお勧めします ガイド付きプロジェクト: 「畳み込みニューラル ネットワーク – 基本アーキテクチャを超えて」.
ベストプラクティス、業界で認められた標準、および含まれているチートシートを含む、Gitを学習するための実践的で実用的なガイドを確認してください。 グーグルGitコマンドを停止し、実際に 学ぶ それ!
1998 年から 2022 年までの時間旅行にあなたを連れて行き、何年にもわたって開発された決定的なアーキテクチャ、それらをユニークにした理由、それらの欠点を強調し、注目すべきものをゼロから実装します。 これらに関しては、手に汚れがあることに勝るものはありません。
エンジンが 4 気筒なのか 8 気筒なのか、またエンジン内のバルブの配置を知らなくても車を運転できます。 ただし、エンジン (コンピューター ビジョン モデル) を設計して評価したい場合は、もう少し深く掘り下げる必要があります。 アーキテクチャの設計に時間を費やすのではなく、代わりに製品を構築したい場合でも、これは最もやりたいことですが、このレッスンで重要な情報を見つけることができます。 VGGNet のような古いアーキテクチャを使用すると製品やパフォーマンスが損なわれる理由、最新のものを構築する場合にそれらをスキップする理由、および実際の問題を解決するために使用できるアーキテクチャと、長所と短所はそれぞれです。
コンピューター ビジョンを自分の分野に適用しようとしている場合は、このレッスンのリソースを使用して、最新のモデルを見つけ、それらがどのように機能するかを理解し、どの基準でそれらを比較して、どれを適用するかを決定することができます。使用する。
You しない アーキテクチャとその実装については Google に依頼する必要があります。これらは通常、論文で非常に明確に説明されており、Keras のようなフレームワークにより、これらの実装がこれまでになく簡単になります。 このガイド付きプロジェクトの重要なポイントは、アーキテクチャと論文を見つけ、読み、実装し、理解する方法を教えることです。 世界中のどのリソースも、最新の開発すべてについていくことはできません。 ここには最新の論文を含めましたが、数か月後には新しい論文が出てくるでしょう。これは避けられないことです。 信頼できる実装がどこにあるかを知り、それらを論文と比較し、微調整することで、構築する可能性のある多くのコンピューター ビジョン製品に必要な競争力を得ることができます。
まとめ
この短いガイドでは、CNN アーキテクチャ設計におけるフラット化に代わる方法について説明しました。 簡潔ではありますが、このガイドでは、プロトタイプまたは MVP を設計する際の一般的な問題に対処し、フラット化に代わるより良い方法を使用するようアドバイスしています。
経験豊富なコンピューター ビジョン エンジニアは、この原則を知っており、適用することができます。 残念ながら、この分野に参入したばかりの新しい開業医には適切に伝えられていないようで、取り除くのに時間がかかる粘着性のある習慣を生み出す可能性があります.
コンピューター ビジョンを始めようとしている場合は、学習過程で分類ヘッドの前に平坦化レイヤーを使用しないでください。