深層学習モデルに新しいカテゴリを追加する方法は?


15

10個のオブジェクトを認識するために、事前に訓練されたネットワークで転移学習を行ったとします。トレーニング済みの10個のすべてのカテゴリも、トレーニング済みの元のモデルからの情報も失うことなく、ネットワークが分類できる11番目の項目を追加するにはどうすればよいですか?友人から、この分野で活発な研究が行われていると言われましたが、関連する論文や検索する名前が見つかりませんか?

ありがとうございました。


もっと多くのクラスでトレーニングする場合はありますか?それは助けることができますか?たとえば、クラスが1000を超えないことがわかっているとしましょう。現在の10クラスの1000クラスで分類器を最初からトレーニングします。さらにクラスがある場合は、トレーニングを続けます。それは良い解決策でしょうか。このアプローチに関する論文はありますか?
マイケル

回答:


13

これが1回限りの場合、単純にニューラルネットワークを再トレーニングできます。頻繁に新しいクラスを追加する必要がある場合、これは悪い考えです。このような場合に行うことは、コンテンツベースの画像検索(CBIR)、または単に画像検索または視覚検索と呼ばれます。以下の回答で両方のケースを説明します。

一度限りのケース

これが一度だけ発生した場合-11番目のクラスを忘れた場合、または顧客が気が変わった場合- 再び発生しない場合は、11番目の出力ノードを最後のレイヤーに単純に追加できます。このノードの重みをランダムに初期化しますが、他の出力には既に持っている重みを使用します。その後、通常どおりトレーニングします。いくつかの重みを修正するのに役立つかもしれません。つまり、これらを訓練しないでください。

極端な場合は、新しい重みのみをトレーニングし、他のすべてを固定したままにすることです。しかし、これがうまくいくかどうかはわかりません。試してみる価値があるかもしれません。

コンテンツベースの画像検索

次の例を考えてみましょう。CDストアで働いており、顧客にアルバムカバーの写真を撮ってもらいたいと考えています。アプリケーションは、オンラインストアでスキャンしたCDを表示します。その場合、ストアにある新しいCDごとにネットワークを再トレーニングする必要があります。それは毎日5枚の新しいCDになる可能性があるため、そのようにネットワークを再トレーニングすることは適切ではありません。

解決策は、画像を特徴空間にマッピングするネットワークをトレーニングすることです。各画像は記述子で表されます。記述子は、たとえば256次元のベクトルです。この記述子を計算し、記述子のデータベース(ストアにあるすべてのCDの記述子)と比較することにより、イメージを「分類」できます。データベース内の最も近い記述子が優先されます。

このような記述子ベクトルを学習するために、ニューラルネットワークをどのようにトレーニングしますか?それは活発な研究分野です。「画像検索」や「メトリック学習」などのキーワードを検索して、最近の作品を見つけることができます。

現在、人々は通常、事前に訓練されたネットワーク、たとえばVGG-16を使用してFCレイヤーを切り離し、最終的な畳み込みを記述子ベクトルとして使用します。トリプレット損失のあるシャムネットワークを使用するなどして、このネットワークをさらにトレーニングできます。


私はワンショット学習を検討しています。それは私を助けることができると思いますか?
nnrales 16

ワンショット学習については本当に知りません。それは間違いなくあなたのために有用であることができるようにしかし、ワンショットが深い、私はCBIRのアプローチと非常によく似表情を発見した論文を学ぶ
hbaderts

2

ネットワークトポロジは異なって見えるかもしれませんが、最終的には、事前に訓練されたネットワークには10個の元のクラスの認識を処理するレイヤーがあります。11番目、12番目、.. n番目のクラスを導入する最も簡単な(そして機能する)トリックは、最後に付与される前のすべてのレイヤーを使用し、追加のレイヤー(新しいモデルまたは並列レイヤー)を追加することです。最後のレイヤーを除くすべてのレイヤーの上で、10クラスレイヤー(おそらく、密なレイヤーと[len(dense layer), 10]オプションのバイアスを持つ形状のマトリックスのマットル)に似ています。

新しいレイヤーは、shapeを持つmatmulレイヤーになります[len(dense layer), len(new classes)]

元のトレーニングデータにアクセスできない場合、次の2つのオプションがあります。

  1. 「新しい」モデルが新しいウェイトのみを最適化できるようにすることで、元のレイヤーのすべてのウェイトをフリーズします。これにより、元の10クラスでまったく同じ予測能力が得られ、新しいクラスでも十分なパフォーマンスが得られる可能性があります。
  2. (新しいクラスのエラーを伝播することにより)ネットワーク全体を一度にトレーニングしますが、これは新しいクラスで機能する可能性がありますが、最終的には10クラスの無効な元のソリューションになります(重みは下位クラスと最終層で変更されるため)これらの変更に合わせて更新されることはありません)。

元のトレーニングデータにアクセスできる場合は、元のネットワークに新しいクラスを簡単に追加し、再トレーニングしてすぐに11クラスをサポートできます。


2

これは簡単に行えます。

最初に、これらの10クラスでモデルを構築し、モデルをbase_modelとして保存します。

base_modelをロードし、new_model as-という名前の新しいモデルも定義します

new_model = Sequential()

次に、base_modelのレイヤーをnew_modelに追加します-

# getting all the layers except the last two layers
for layer in base_model.layers[:-2]: #just exclude the last two layers from base_model
    new_model.add(layer)

モデルを再度トレーニングしたくないので、新しいモデルのレイヤーをトレーニング不可にします。

# prevent the already trained layers from being trained again
for layer in new_model.layers:
    layer.trainable = False

学習を転送するときに、最後のレイヤーを削除すると、モデルは10個のクラスを忘れてしまうため、base_modelの重みをnew_modelに保持する必要があります-

weights_training = base_model.layers[-2].get_weights()
new_model.layers[-2].set_weights(weights_training) 

最後に密なレイヤーを追加します。この例では、この密なレイヤーのみをトレーニングします。

new_model.add(Dense(CLASSES, name = 'new_Dense', activation = 'softmax'))

ここでモデルをトレーニングすると、11のクラスすべてに適切な出力が得られることを願っています。

幸せな学習。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.