Dieses Kapitel beschreibt, wie Deep Learning-basierte Semantische Segmentierung in der Trainings- und Inferenzphase genutzt wird.
In der Semantischen Segmentierung ordnet ein Deep Learning (DL) Netzwerk jedem Pixel des Eingabebildes eine Klasse zu.
Das Resultat der Semantischen Segmentierung ist ein Bild, in welchem die Pixelwerte für die zugeordnete Klasse des entsprechenden Pixels auf dem Eingabebild stehen. Somit hat das Ausgabebild in HALCON die gleiche Größe wie das Eingabebild. Im Allgemeinen sind im Netzwerk die Merkmalskarten, die komplexere Merkmale verkörpern, kleiner als das Eingabebild (siehe den Abschnitt „Das Netzwerk und der Trainingsprozess“ im Kapitel Deep Learning). Damit das Ausgabebild die gleiche Größe wie das Eingabebild hat, werden in HALCON Netzwerke mit den folgenden beiden Komponenten verwendet: Einem Encoder und einem Decoder. Der Encoder bestimmt die Merkmale des Eingabebildes, wie dies z.B. in der DL-basierten Klassifikation getan wird. Da diese Information in einem komprimierten Format 'kodiert' ist, braucht es einen Decoder, welcher das gewünschte Ergebnis rekonstruiert. Bei der Semantischen Segmentierung ist dies die Zuordnung jedes Pixels zu einer Klasse. Da das Netzwerk die einzelnen Pixel klassifiziert, werden sich überlappende Instanzen der gleichen Klasse nicht als eigenständig unterschieden.
In HALCON ist die Semantische Segmentierung mittels DL als Teil des allgemeinen DL Modells implementiert. Für weitere Informationen zum DL Modell wird auf das Kapitel Deep Learning / Modell verwiesen.
Die folgenden Abschnitte behandeln den generellen Ablauf der Semantischen Segmentierung, Informationen zu den involvierten Daten und Parametern, sowie Erklärungen zu den Evaluierungsmaßen.
Dieser Abschnitt beschreibt den generellen Ablauf einer Semantischen
Segmentierung mittels Deep Learning.
Er ist unterteilt in die vier Bereiche
Vorverarbeitung des Datensatzes, Trainieren des Modells,
Evaluierung des trainierten Modells und Inferenz auf neuen Bildern.
Dabei wird angenommen, dass der Datensatz bereits gelabelt ist,
siehe den Absatz „Daten“ unten.
Die HDevelop Beispiels-Reihe segment_pill_defects_deep_learning
zeigt eine mögliche Anwendung unterteilt in die einzelnen Bereiche.
Dieser Abschnitt behandelt die notwendigen Anpassungen des
Datensatzes an die Anforderungen eines Modells der Semantischen
Segmentierung.
Die einzelnen Schritte werden im HDevelop Beispiel
segment_pill_defects_deep_learning_1_preprocess.hdev
dargestellt.
Die Information, was auf welchem Bild des Trainings-Datensatzes gefunden werden soll, muss eingelesen und konvertiert werden. Dazu kann die Prozedur
read_dl_dataset_segmentation
verwendet werden. Dabei wird ein Dictionary
erstellt, welches als Datenbank dient und alle notwendigen
Informationen über die Daten abspeichert.
Für mehr Information zu den Daten und wie sie
übergeben werden, wird auf den unteren Absatz „Daten“ und das
Kapitel Deep Learning / Modell verwiesen.
DLDataset
Die Daten von
sollen in drei
getrennten Datensätze geteilt werden. Dazu kann die Prozedur
DLDataset
split_dl_dataset
verwendet werden.
Die resultierende Aufteilung wird für jeden Sample Eintrag von
jeweils über den Schlüssel DLDataset
gespeichert.
split
Der Datensatz kann nun vorverarbeitet werden. Dazu kann die Prozedur
preprocess_dl_dataset
verwendet werden. Für die Implementierung einer selbst erstellten Vorverarbeitung kann man sich an dieser Prozedur orientieren.
Um diese Prozedur zu verwenden, müssen die Vorverarbeitungsparameter
wie z.B. die Bildgröße festgelegt werden.
Für letztere sollte die kleinstmögliche Bildgröße gewählt werden,
mit der die einzelnen Regionen noch gut erkennbar sind.
Die Parameter und ihre Werte sind im Dictionary
zu speichern, wofür die Prozedur
DLPreprocessParam
create_dl_preprocess_param
verwendet werden kann.
Es wird empfohlen, dieses Dictionary
abzuspeichern, um während der späteren Inferenz-Phase Zugang zu
den Werten zu haben.
DLPreprocessParam
Während der Vorverarbeitung werden von der Prozedur
preprocess_dl_dataset
auch die Bilder
für den Trainings-Datensatz erstellt. Diese ordnen jeder Klasse das
Gewicht ('class weights') zu, welche ihre Pixel während des
Trainings erhalten (siehe den unteren Abschnitt „Modellparameter und
Hyperparameter“).
weight_image
Dieser Abschnitt behandelt das Trainieren des DL Modells für
Semantische Segmentierung.
Die einzelnen Schritte werden im HDevelop Beispiel
segment_pill_defects_deep_learning_2_train.hdev
dargestellt.
Einlesen eines Modells mit dem Operator
Die Modellparameter müssen mit dem Operator
gesetzt werden.
Solche Parameter sind z.B.
und
image_dimensions
,
siehe die Dokumentation von class_ids
.
get_dl_model_param
Die aktuellen Werte können jederzeit über den Operator
abgefragt werden.
Setzen der Trainingsparameter und Abspeichern derselben im
Dictionary 'TrainParam'
.
Diese Parameter beinhalten:
die Hyperparameter. Für eine Übersicht wird auf den unteren Abschnitt „Modellparameter und Hyperparameter“ sowie das Kapitel Deep Learning verwiesen.
Parameter zur eventuellen Datenanreicherung (optional).
Parameter zur Evaluierung während des Trainings.
Parameter zur Visualisierung von Trainingsergebnissen.
Parameter zur Serialisierung.
Für dies kann die Prozedur
create_dl_train_param
verwendet werden.
Trainieren des Modells. Dafür kann die Prozedur
train_dl_model
verwendet werden. Diese Prozedur benötigt:
das Handle des Modells, DLModelHandle
das Dictionary mit den Informationen über den Datensatz,
DLDataset
das Dictionary mit den Trainingsparametern,
'TrainingParam'
die Angabe, über wie viele Epochen trainiert werden soll.
Wird die Prozedur train_dl_model
verwendet, werden die
Gesamt-Zielfunktion sowie optionale Evaluierungsmaße visualisiert.
Dieser Abschnitt behandelt das Evaluieren eines DL Modells für
Semantische Segmentierung.
Die einzelnen Schritte werden im HDevelop Beispiel
segment_pill_defects_deep_learning_3_evaluate.hdev
dargestellt.
Setzen der Modellparameter, welche die Evaluierung
beeinflussen, wie z.B. 'batch_size'
, über den Operator
Die Evaluierung kann bequem mit der Prozedur
evaluate_dl_model
durchgeführt werden.
Das Dictionary
enthält die
angefragten Evaluierungsmaße.
Die Ergebnisse der Evaluierung können mit der Prozedur
EvaluationResults
dev_display_segmentation_evaluation
visualisiert werden.
Dieser Abschnitt behandelt die Inferenz auf neuen Bildern durch ein
DL Modell für Semantische Segmentierung.
Die einzelnen Schritte werden im HDevelop Beispiel
segment_pill_defects_deep_learning_4_infer.hdev
dargestellt.
Setzen der Parameter, wie z.B. 'batch_size'
über den Operator
Generieren des Dictionaries
für jedes Bild.
Dafür kann die Prozedur
DLSample
gen_dl_samples_from_images
verwendet werden.
Jedes Bild muss auf dieselbe Art und Weise wie für die Trainingsbilder vorverarbeitet werden. Es wird empfohlen, dafür die Prozedur
preprocess_dl_samples
zu verwenden. Wurde während der Vorverarbeitung das Dictionary
gespeichert, kann es direkt als Eingabe
verwendet werden, um die Parameterwerte festzulegen.
DLPreprocessParam
Anwenden des Modells über den Operator
Die Resultate können aus dem Dictionary 'DLResultBatch'
abgerufen werden.
Die Regionen der einzelnen Klassen kann man z.B. über den Operator
selektieren.
threshold
Es wird zwischen den Daten für Training und Evaluierung versus Daten für
Inferenz unterschieden. Letztere bestehen ausschließlich aus Bildern.
Für Erstere wird jedoch die Information benötigt, zu welcher Klasse jeder
einzelne Pixel gehört (über
, siehe die
Erklärungen weiter unten).
segmentation_image
Ein Grundgedanke der Datenhandhabung: Das Modell interagiert mit den Daten
über Dictionaries.
Dies bedeutet, das Modell erhält die Eingabedaten über das Dictionary
und gibt die Ausgabe über das Dictionary
DLSample
, bzw. DLResult
zurück.
Für weitere Informationen zur Datenhandhabung wird auf das Kapitel
Deep Learning / Modell verwiesen.
DLTrainResult
Die Trainingsdaten werden benötigt, um das Netzwerk für Ihre spezifische
Aufgabe zu trainieren.
Der Datensatz besteht aus Bildern und den dazugehörigen
Informationen.
Damit das Modell diese verarbeiten kann, müssen sie bestimmte
Anforderungen erfüllen.
Informationen zu den Bildanforderungen finden sich im unteren Abschnitt
„Bilder“.
Die Information über die Bilder und ihre Ground Truth Annotationen wird
über das Dictionary
und für jedes Sample das
entsprechende Bild DLDataset
gegeben, welches für
jedes Pixel die Klasse definiert.
segmentation_image
Die verschiedenen Klassen bilden die vom Netzwerk unterschiedene
Sets oder die unterschiedenen Kategorien.
Diese Klassen werden im Dictionary
gesetzt
und dem Modell über den Operator DLDataset
gegeben.
set_dl_model_param
Bei der Semantischen Segmentierung gibt es zwei Besonderheiten: Die Hintergrund-Klasse 'background' und Klassen, die ignoriert werden sollen und deshalb auf 'ignore' gesetzt werden:
'background' Klasse:
Das Netzwerk behandelt die Hintergrund-Klasse 'background' wie
jede andere Klasse auch. Ebenso ist es nicht notwendig, eine
Hintergrund-Klasse zu haben.
Aber falls im Datensatz verschiedene Klassen vorkommen, deren
Ergebnis nicht von Interesse ist, die aber trotzdem vom Netzwerk
gelernt werden sollen, können diese alle als Hintergrund deklariert
werden.
Als Resultat davon wird die Hintergrund-Klasse diverser.
Für weitere Informationen wird auf die Prozedur
preprocess_dl_samples
verwiesen.
'ignore' Klassen:
Eine oder mehrere Klassen können als 'ignore' deklariert werden.
Pixel, die einer solchen Klasse zugehören, werden bei der Berechnung
der Zielfunktion sowie allen Evaluierungsmaßen ignoriert.
Für weitere Informationen zur Zielfunktion wird auf den Abschnitt
„Das Netzwerk und der Trainingsprozess“ im Kapitel
Deep Learning verwiesen.
Das Netzwerk ordnet kein Pixel einer als 'ignore' deklarierte
Klasse zu. Die Pixel die mit einer solchen 'ignore'-Klasse
gelabelt wurden, werden vom Netzwerk wie alle anderen Pixel auch
einer nicht als 'ignore' deklarierten Klasse zugeordnet.
Im unten folgenden Beispiel bedeutet dies, dass das Netzwerk auch
die Pixel der Klasse 'Rand' klassifiziert, aber es wird kein
Pixel des Eingabebildes der Klasse 'Rand' zuordnen.
Eine Klasse kann über den Parameter 'ignore_class_ids'
im Operator
als 'ignore' deklariert
werden.
set_dl_model_param
DLDataset
Dieses Dictionary dient als Datenbank. Dies bedeutet, dass darin alle
für das Netzwerk notwendigen Informationen über den Datensatz
gespeichert werden, z.B. den Namen und Pfad zu den Bildern, die
Klassen, etc.
Für Informationen zum Konzept und den einzelnen Einträgen wird auf
das Kapitel Deep Learning / Modell verwiesen.
Nur auf die Semantische Segmentierung anwendbare Schlüssel
betreffen die Bilder
(siehe den unteren Eintrag).
Über die Schlüssel segmentation_image
und
segmentation_dir
werden die Informationen zur
Verfügung gestellt, wie die Bilder heißen und wo sie gespeichert sind.
segmentation_file_name
segmentation_image
Damit das Netzwerk lernen kann, wie die Angehörigen der verschiedenen
Klassen aussehen, muss für jedes Pixel jedes Bildes des
Trainings-Datensatzes mitgeteilt werden, zu welcher Klasse er gehört.
Um dies zu tun wird für jedes Pixel eines Eingabebildes die Klasse
im Bild
als Pixelwert gespeichert.
Diese Annotationen sind die Ground Truth Annotationen.
segmentation_image
(1) | (2) |
Es sollten genügend Trainingsdaten vorliegen, um diese in die drei
Untermengen aufzuteilen, welche für das Training, die Evaluierung und
das Testen des Netzwerks verwendet werden.
Diese Untermengen sind idealerweise unabhängig und gleich
verteilt, siehe den Abschnitt „Daten“ im Kapitel
Deep Learning. Zur Aufteilung kann die Prozedur
split_dl_data_set
verwendet werden.
Unabhängig von der Anwendung stellt das Netzwerk Anforderungen an die
Bilder wie z.B. die Bilddimensionen.
Die spezifischen Werte hängen vom Netzwerk selbst ab, für die
spezifischen Werte der verschiedenen Netzwerke siehe die Dokumentation
von
.
Für ein eingelesenes Netzwerk können die Werte mit
read_dl_model
abgefragt werden.
Um diese Anforderungen zu erfüllen, müssen die Bilder eventuell
vorverarbeitet werden.
Die Standard-Vorverarbeitung für das ganze Sample und damit auch für das
Bild kann mit Hilfe der Prozedur get_dl_model_param
preprocess_dl_samples
durchgeführt werden.
Für eine selbst erstellte Vorverarbeitung liefert diese Prozedur eine
Anleitung für die Implementierung.
Als Trainingsausgabe gibt das Modell ein Dictionary
mit dem aktuellen Wert der Gesamt-Zielfunktion
sowie den Werten aller weiteren im Modell enthaltenen Zielfunktionen.
DLTrainResult
Als Inferenz- und Evaluations-Ausgabe gibt das Netzwerk für jedes Bild
ein Dictionary
zurück.
Im Falle der Semantischen Segmentierung beinhaltet dieses Dictionary
für jedes Eingabebild das Handle der folgenden beiden Bildern:
DLResult
: In diesem Bild hat jedes Pixel den
Wert der Klasse, in welche das entsprechende Pixel des Eingabebildes
klassifiziert wurde (siehe die untere Darstellung).
segmentation_image
: In diesem Bild hat jedes
Pixel den Konfidenzwert der Klassifikation des entsprechenden Pixels
im Eingabebild (siehe die untere Darstellung).
segmentation_confidence
(1) | (2) |
Nebst den allgemeinen DL Hyperparametern aus dem Kapitel Deep Learning gibt es für die Semantische Segmentierung noch einen weiteren Hyperparameter:
'class weights', siehe die unten folgende Erklärung.
Für DL Modelle der Semantischen Segmentierung werden die Modellparameter
und Hyperparameter (mit Ausnahme der 'class weights') über den Operator
gesetzt.
Für Informationen zu den Modellparametern wird auf die Dokumentation
von set_dl_model_param
verwiesen.
get_dl_model_param
Es gilt zu beachten, dass aufgrund hohen Speicherbedarfs normalerweise
für das Training nur kleine Batchgrößen verwendet werden können.
Deshalb ist das Training eher langsam und es wird empfohlen, ein größeres
Momentum als z.B. bei der Klassifikation zu verwenden.
Das HDevelop Beispiel
segment_pill_defects_deep_learning_2_train.hdev
liefert
gute initiale Parameterwerte für das Training eines Modells der
Semantischen Segmentierung in HALCON.
Mit dem Hyperparameter 'class_weights' kann jeder Klasse ein Wert zugeordnet werden, mit welchem die jeweiligen Pixel während des Trainings gewichtet werden. Erhalten die verschiedenen Klassen unterschiedliche Gewichte, so wird das Netzwerk forciert, den Klassen beim Lernen eine unterschiedliche Bedeutung zu geben. Dies ist nützlich, wenn eine Klasse die Bildanteile dominiert, wie z.B. bei der Defekterkennung, wo die Defekte nur einen kleinen Teil des Bildes einnehmen. In solchen Fällen würde ein Netzwerk einen guten Wert für die Zielfunktion erzielen, indem es das gesamte Bild als Hintergrund (und somit als 'nicht defekt') klassifiziert. Den Klassen verschiedene Gewichte zuzuordnen hilft, die Verteilung besser auszubalancieren. Kurz, die Zielfunktion wird darauf fokussiert, insbesondere die Pixel zu lernen, die von Ihnen als wichtig bestimmt wurden.
Das Netzwerk erhält diese Gewichte über das Bild
,
welches für jedes Trainingsbild erstellt wird.
In weight_image
entspricht jeder Pixelwert dem Gewicht,
welches das entsprechende Pixel des Eingabebildes während des Trainings
erhält.
Ein solches Bild weight_image
kann durch Verwendung der
folgenden beiden Prozeduren erstellt werden:
weight_image
calculate_class_weights_segmentation
bestimmt die
verschiedenen Klassen-Gewichte. Die Prozedur verwendet das Konzept
der Gewichte nach inverser Klassenhäufigkeit.
gen_dl_segmentation_weight_images
verwendet die
Klassen-Gewichte und generiert die Bilder
.
weight_image
Dies muss vor dem Training getan werden. Normalerweise werden die Bilder
während der Vorverarbeitung generiert und dies ist Teil der Prozedur
preprocess_dl_samples
.
Es gilt zu beachten, dass dieser Hyperparameter in den verschiedenen
Prozeduren
oder class_weights
genannt wird.
Eine Darstellung, wie solche Bilder mit unterschiedlichen Gewichten
aussehen können, ist in der Abbildung weiter unten gegeben.
ClassWeights
Es gilt zu beachten, wird einem bestimmten Part eines Bildes das Gewicht von 0.0 gegeben, tragen diese Pixel nicht zur Zielfunktion bei (siehe „Das Netzwerk und der Trainingsprozess“ für mehr Informationen zur Zielfunktion).
(1) | (2) |
Für die Semantische Segmentierung werden in HALCON folgende
Evaluierungsmaße unterstützt.
Es gilt zu beachten, dass zur Berechnung eines solchen Maßes die
zugehörige Ground Truth Annotation notwendig ist.
Die verschiedenen Evaluierungsmaße die unten für ein einzelnes Bild
erklärt werden (wie z.B.
), können auch für eine
beliebige Anzahl Bilder berechnet werden.
Dafür kann man sich ein einzelnes, großes Bild vorstellen, gebildet aus
dem Ensemble an Einzelbildern.
Es gilt zu beachten, dass die Pixel aller Klassen, die als 'ignore'
deklariert wurden, für die Berechnung der Maße ignoriert werden.
mean_iou
pixel_accuracy
(1) | (2) | (3) |
class_pixel_accuracy
Die klassenweise Pixel Genauigkeit berücksichtigt nur die Pixel einer Klasse. Dieses Maß ist definiert als das Verhältnis aller korrekt dieser Klasse zugeordneten Pixel zur Gesamtzahl Pixel dieser Klasse.
Falls eine Klasse nicht vertreten ist, wird ihr für
ein Wert class_pixel_accuracy
'-1'
zugewiesen und sie
trägt nicht zum Mittelwert
bei.
mean_accuracy
mean_accuracy
Die durchschnittliche Genauigkeit ist der Mittelwert der klassenweisen
Pixel Genauigkeiten
über alle
vertretenen Klassen.
class_pixel_accuracy
class_iou
Die klassenweise Intersection over Union (IoU) gibt für eine Klasse das Verhältnis von korrekt zugeordneten Pixeln zur Anzahl an Pixeln, die entweder tatsächlich zu dieser Klasse gehören oder dieser zugeordnet wurden. Bildlich entspricht dies dem Verhältnis zwischen der Schnittmenge und der Vereinigungsmenge der Flächen, siehe auch die untere Darstellung.
Falls eine Klasse nicht vertreten ist, wird ihr für
ein Wert class_iou
'-1'
zugewiesen und sie trägt
nicht zum Mittelwert
bei.
mean_iou
(1) | (2) | (3) |
mean_iou
Die durchschnittliche IoU ist der Mittelwert der klassenweisen
IoU
über alle vertretenen Klassen.
Es gilt zu beachten, dass alle vertretenen Klassen den gleichen
Einfluss auf dieses Maß haben, unabhängig von ihrer Anzahl an Pixel.
class_iou
frequency_weighted_iou
Wie für die durchschnittliche IoU werden erst die klassenweisen IoU berechnet. Der Beitrag einer jeden Klasse zu diesem Maß ist abhängig von der Anzahl Pixel dieser Klasse. Dadurch können Klassen mit einer großen Anzahl an Pixeln dieses Maß dominieren.
pixel_confusion_matrix
Das Konzept der Konfusionsmatrix wird im Abschnitt „Das Training beaufsichtigen“ des Kapitels Deep Learning erklärt. Dieses ist auch für die Semantische Segmentierung anwendbar, wo die Instanzen einzelne Pixel sind.