Convolutional Neuronal Networks und YOLO v3

Convolutional Neuronal Networks sind aus der Welt der KI nicht mehr wegzudenken. Ohne sie wäre es zum Beispiel nicht möglich, selbstfahrende Autos zu bauen. Damit sich ein Auto selbständig im Verkehr zurechtfindet, muss es seine Umgebung erkennen. Dazu gehört nicht nur der relativ einfache Fall, ein Objekt, wie z.B. einen Fußgänger als solchen zu erkennen, sondern auch seine Position zu bestimmen. In Bildern beliebig viele Objekte zu erkennen (Klassifikation) und deren Position zu bestimmen, bezeichnet man als Detection. Detection ist quasi die Königsdisziplin im Bereich der Computer Vision. Diese Herausforderung wird zurzeit mit einem Algorithmus bewerkstelligt, der sich YOLO v3 nennt. Die Abkürzung steht für You Only Look Once. Das v3 weist auf die derzeit aktuelle Version drei hin. Mit YOLO ist es möglich Detection bewegter Bilder in real-time zu bewerkstelligen.

Kern von YOLO ist ein extrem tiefes Convolutional Neuronal Network CNN. Wir haben in anderen Blogs bereits über CNNs gesprochen und gezeigt, wie man sie mit Keras gewinnbringend verbaut:

Einstieg in Convolutional Neuronale Netze mit Keras

So entwirft man ein Top CNN

Wie war das eigentlich früher? 

In diesem Blog möchte ich noch einmal einen Schritt zurückgehen und den mathematischen Hintergrund von Faltungen (Convolutions) zeigen. Dabei ist der Trick so verblüffend einfach, dass man eigentlich nur Plus und Minus verstanden haben muss. 

Bevor man maschinelles Lernen für die Bildverarbeitung einsetzte, musste man sich mit analytischen Algorithmen behelfen. Die Algorithmik der Faltungen beschäftigt sich damit, Kanten in Bildern zu erkennen. Der Traum der Wissenschaftler war dabei, dass man einen Gegenstand in einem Bild lokalisieren könnte, wenn man seine Kanten erkennen würde und den Rest einfach ignoriert. Das ist sowas wie Ausmalen nur andersherum (also quasi „entmalen“). 

Kleiner Einschub: Es gibt übrigens eine ganze Reihe von Algorithmen, die Kanten erkennen können. Wer sich dafür interessiert, sollte sich zum Beispiel MSER (Maximal Stable External Region) ansehen – ein sehr mächtiges aber auch kompliziertes Verfahren im Bereich der analytischen Lokation. 

Beim Falten eines Bildes lässt man einen kleinen Filter über das Bild gleiten und schreibt mit, was man durch diesen Filter vom Bild noch sieht. Jeder Filter ist auf bestimmte Kanten spezialisiert. Also horizontale, vertikale, gekrümmte, … Kanten. 

Eine Kante ist dabei ein starker Hell-Dunkel-Kontrast im Bild. Trifft der Filter also auf eine Stelle mit einem starken Kontrast, dann soll er heftig „ausschlagen“. Bei schwachen Kontrasten hingegen soll sich der Filter ruhig verhalten. Wie muss so ein Filter also gebaut sein, damit er dieses Verhalten bewerkstelligen kann? 

Um zum Beispiel vertikale Kanten zu erkennen, braucht man ein Verfahren, dass die Differenz aus allen Links-Rechts-Bildpunkt-Tupeln bildet. Ist die Differenz der Intensität zweier nebeneinander gelegener Bildpunkte besonders groß, dann muss der Filter dafür auch einen besonders großen Wert liefern. Das hört sich nach einer Art Einheitsmatrix an:

Abbildung 1: Filter für vertikale Kanten

Nehmen wir an, wir hätten ein sehr kleines Bild mit gerade mal drei auf drei Bildpunkten:

Abbildung 2: Sehr kleines Bild

Wenn man den 3×3 großen Filter nun auf ein 3×3 großes Bild anwendet, geschieht folgendes:

Wir erhalten also ein Maß für den vertikalen Kontrast von 216. Das klingt ehrlich gesagt nicht sehr spannend. Spannend wird es erst, wenn man das Verfahren auf größere Bilder anwendet und den Filter Stück für Stück verschiebt:

Abbildung 3: Verschieben des Filters

Als Ergebnis erhält man dann eine Matrix, die sich wieder als Bild darstellen lässt:

Abbildung 4: Ergebnis

Ein bisschen Python

Um die Faltungen ein wenig ausprobieren zu können, habe ich einige Zeilen Python Code geschrieben. Der Code soll möglichst klar den Algorithmus zeigen, ist aber alles andere als performant.

Boiler Plate

Zuerst alle nötigen Imports

Die Filter und ein kleines Beispiel

Ich baue mir jeweils einen Filter für vertikale und horizontale Linien.

Um die Filter grundlegend ausprobieren zu können, baue ich mir ein simples 100×100-Punkte-großes Beispielbild mit einer horizontalen, einer diagonalen und einer vertikalen weißen Linie.

Um die Bilder einheitlich darstellen zu können, spendiere ich mir eine kleine Hilfsmethode, zum Zeichnen von Bildern. Mit dem shift Parameter kann ich die Bilder ein wenig aufhellen, um mir Deteils besser anzuzeigen.

Abbildung 5: Das Testbild (100, 100)

Die eigentliche Faltung des Bildes läuft mit vier ineinander geschachtelten Schleifen über jede Filterposition und summiert die entsprechenden Kontraste auf. Wie bereits erwähnt ist der Code extrem unperformant, zeigt aber dafür sehr schön die Funktionsweise der Filter.

Jetzt kann man die beiden Filter auf das Testbild anwenden und sich das Ergebnis anschauen. Der vertikale Filter entfernt erwartungsgemäß den horizontalen Balken und andersherum. Von der Diagonale wird „nur“ ein Teil entfernt, da Diagonalen ja nichts anderes sind als sehr feine Treppen.

Abbildung 6: Der horizontale Filter löscht den vertikalen Balken (98, 98)
Abbildung 7: Der vertikale Filter löscht swn horizontalen Balken (98, 98)

Nun habe ich mir noch zwei echte Bilder herausgesucht, um die Filter auszuprobieren. Den Effekt finde ich beeindruckend. Es sieht aus, als würde man einen Kupferstich aus den Bildern erzeugen. Beachtenswert ist, dass eben immer die vertikalen oder horizontalen Aspekte der Bilder hervorgehoben werden. Es sieht aus, als würden sie mit einem Schatten versehen.

Abbildung 8: Vertikaler Anleger vor dem Horizont
Abbildung 9: Der horizontale Filter, mit deutlicher Horizontlinie (415, 623)
Abbildung 10: Der vertikale Filter. Der Horizont ist fast nicht zu sehen (415,623)

Und zum Schluss, weil es einfach dazugehört: Ein Hund:

Abbildung 11: Der Hallo Welt Hund (600, 900)
Abbildung 12: Der horizontale Filter (598, 908)
Abbildung 13: Der vertikale Filter (598, 908)

Schluss

Es ist erstaunlich wie einfach es ist, Kanten aus einem Bild herauszufiltern. Bei den Convolutional Neuronal Network greift man den Gedanken der Filter auf. Der einzige Unterschied besteht nur noch darin, dass man die Werte in den Filter Matrizen durch Gewichte ersetzt und diese dann trainiert. Somit lassen sich alle beschreibenden Ecken und Kanten herausarbeiten.

Jetzt teilen auf:

Jetzt kommentieren