Wie füge ich einem Deep-Learning-Modell eine neue Kategorie hinzu?

15

Angenommen, ich habe das Transferlernen in einem vorab trainierten Netzwerk durchgeführt, um 10 Objekte zu erkennen. Wie füge ich ein 11. Element hinzu, das das Netzwerk klassifizieren kann, ohne alle 10 Kategorien, die ich bereits trainiert habe, oder die Informationen aus dem ursprünglichen vortrainierten Modell zu verlieren? Ein Freund erzählte mir, dass in diesem Bereich aktive Forschung betrieben wird, ich jedoch keine relevanten Artikel oder einen Namen finde, nach dem ich suchen kann?

Vielen Dank.

nnrales
quelle
Wenn Sie mit viel mehr Klasse trainieren, gibt es dann? kann das helfen Nehmen wir zum Beispiel an, Sie wissen, dass es nicht mehr als 1000 Klassen geben wird. Sie trainieren von Anfang an Ihren Klassifikator mit 1000 Klassen auf den 10 Klassen, die Sie aktuell haben, und wenn Sie mehr Klassen haben, lassen Sie einfach den Zug drauf ... Kann das eine gute Lösung sein? Gibt es Papier zu diesem Ansatz?
Michael

Antworten:

12

Wenn dies nur ein einmaliger Fall ist, können Sie das neuronale Netzwerk einfach neu trainieren. Wenn Sie häufig neue Klassen hinzufügen müssen, ist dies eine schlechte Idee. Was Sie in solchen Fällen tun möchten, wird als inhaltsbasierter Bildabruf (CBIR) oder einfach als Bildabruf oder visuelle Suche bezeichnet. Ich werde beide Fälle in meiner Antwort unten erläutern.

Einmaliger Fall

Wenn dies nur einmal vorkommt - Sie haben die 11. Klasse vergessen oder Ihr Kunde hat es sich anders überlegt -, aber es kommt nicht wieder vor , dann können Sie einfach einen 11. Ausgabeknoten bis zur letzten Ebene erstellen. Initialisieren Sie die Gewichte für diesen Knoten nach dem Zufallsprinzip, verwenden Sie jedoch die Gewichte, die Sie bereits für die anderen Ausgaben haben. Dann trainiere es einfach wie gewohnt. Es kann hilfreich sein, einige Gewichte zu fixieren, dh diese nicht zu trainieren.

Ein Extremfall wäre, nur die neuen Gewichte zu trainieren und alle anderen fest zu lassen. Ich bin mir aber nicht sicher, ob das so gut funktioniert - vielleicht ist es einen Versuch wert.

Inhaltsbasiertes Abrufen von Bildern

Stellen Sie sich das folgende Beispiel vor: Sie arbeiten für einen CD-Shop, der seinen Kunden die Möglichkeit geben soll, ein Foto von einem Albumcover zu machen, und die Anwendung zeigt ihnen die CD, die sie in ihrem Online-Shop gescannt haben. In diesem Fall müssten Sie das Netzwerk für jede neue CD im Laden neu trainieren. Das können 5 neue CDs pro Tag sein, daher ist es nicht geeignet, das Netzwerk auf diese Weise neu zu trainieren.

Die Lösung besteht darin, ein Netzwerk zu trainieren, das das Bild in einen Merkmalsraum abbildet. Jedes Bild wird durch einen Deskriptor dargestellt, der beispielsweise ein 256-dimensionaler Vektor ist. Sie können ein Bild "klassifizieren", indem Sie diesen Deskriptor berechnen und mit Ihrer Deskriptordatenbank (dh den Deskriptoren aller CDs, die Sie in Ihrem Geschäft haben) vergleichen. Der nächste Deskriptor in der Datenbank gewinnt.

Wie trainiert man ein neuronales Netzwerk, um einen solchen Deskriptorvektor zu lernen? Das ist ein aktives Forschungsgebiet. Sie können aktuelle Arbeiten finden, indem Sie nach Stichwörtern wie "Bildsuche" oder "Metrisches Lernen" suchen.

Derzeit wird normalerweise ein vorab trainiertes Netzwerk, z. B. VGG-16, verwendet, um die FC-Schichten abzuschneiden und die endgültige Faltung als Deskriptorvektor zu verwenden. Sie können dieses Netzwerk weiter trainieren, indem Sie z. B. ein siamesisches Netzwerk mit Triplettverlust verwenden.

hbaderts
quelle
Ich habe mich mit One-Shot-Lernen beschäftigt. Glaubst du, das kann mir helfen?
Nnrales
Ich weiß nicht wirklich, was One-Shot-Lernen ist. Aber die einmaligen vertieften Lernpapiere, die ich gefunden habe, sehen dem CBIR-Ansatz ziemlich ähnlich, so dass es definitiv für Sie nützlich sein könnte
hbaderts
2

Ihre Netzwerktopologie sieht möglicherweise anders aus, aber letztendlich verfügt Ihr vorab trainiertes Netzwerk über eine Ebene, die die Erkennung von 10 Originalklassen übernimmt. Der einfachste (und funktionierende) Trick, um die 11., 12. und n-te Klasse einzuführen, besteht darin, alle Ebenen vor der letzten als gegeben zu verwenden und eine zusätzliche Ebene hinzuzufügen (in einem neuen Modell oder als parallele Ebene), die ebenfalls vorhanden ist Auf allen Ebenen, bis auf die letzten, wird die 10-Klassen-Ebene (die höchstwahrscheinlich aus einer dichten Schicht und einer Formmatrix [len(dense layer), 10]mit optionaler Verzerrung besteht) gleich aussehen .

Ihre neue Schicht wäre eine matte Schicht mit Form [len(dense layer), len(new classes)].

Ohne Zugriff auf die ursprünglichen Trainingsdaten hätten Sie zwei Möglichkeiten:

  1. Frieren Sie alle Gewichte in den ursprünglichen Ebenen ein, indem Sie zulassen, dass "neues" Modell nur neue Gewichte optimiert. Dadurch erhalten Sie für die ursprünglichen 10 Klassen genau die gleiche Vorhersagekraft und können für neue Klassen eine gute Leistung erzielen.
  2. Trainieren Sie das gesamte Netzwerk auf einmal (indem Sie Fehler von neuen Klassen verbreiten), die möglicherweise für neue Klassen funktionieren. Sie erhalten jedoch eine ineffektive ursprüngliche Lösung für 10 Klassen (da die Gewichte für die unteren Klassen und die letzte Ebene geändert werden) werden nicht aktualisiert, um diesen Änderungen zu entsprechen).

Wenn Sie Zugriff auf die ursprünglichen Trainingsdaten haben, können Sie dem ursprünglichen Netzwerk auf einfache Weise eine neue Klasse hinzufügen und es neu trainieren, um 11 sofort einsatzbereite Klassen zu unterstützen.

chewpakabra
quelle
1

Dies ist einfach zu bewerkstelligen.

Erstellen Sie zuerst ein Modell mit diesen 10 Klassen und speichern Sie das Modell als base_model.

Laden Sie das Basismodell und definieren Sie ein neues Modell mit dem Namen new_model as-

new_model = Sequential()

Fügen Sie dann die Ebenen des Basismodells zum neuen Modell hinzu -

# 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)

Machen Sie nun die Ebenen des neuen Modells nicht trainierbar, da Sie nicht möchten, dass Ihr Modell erneut trainiert wird.

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

Wenn Sie jetzt das Lernen übertragen und die letzten Ebenen entfernen, vergisst das Modell die 10 Klassen, sodass wir die Gewichte des Basismodells auf das neue Modell übertragen müssen.

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

Fügen Sie nun am Ende eine dichte Ebene hinzu. In diesem Beispiel wird nur diese dichte Ebene trainiert.

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

Trainiere jetzt das Modell und ich hoffe, es gibt die richtige Ausgabe für alle 11 Klassen.

Viel Spaß beim Lernen.

Subham Tiwari
quelle