06.11.2013 Aufrufe

GPU-Implementation von “Neural Gas Principal Component Analysis”

GPU-Implementation von “Neural Gas Principal Component Analysis”

GPU-Implementation von “Neural Gas Principal Component Analysis”

MEHR ANZEIGEN
WENIGER ANZEIGEN

Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.

YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.

Universität Bielefeld<br />

Technische Fakultät<br />

AG Technische Informatik<br />

Bachelorarbeit<br />

<strong>GPU</strong>-<strong>Implementation</strong> <strong>von</strong> <strong>“Neural</strong> <strong>Gas</strong><br />

<strong>Principal</strong> <strong>Component</strong> <strong>Analysis”</strong> mit<br />

blockweisem Ansatz<br />

Christian Menßen<br />

26. September 2012<br />

im Studiengang<br />

Kognitive Informatik<br />

Betreuer<br />

Dr.-Ing. Wolfram Schenck


Diese Bachelorarbeit wurde <strong>von</strong> Dr.-Ing. Wolfram Schenck betreut und begutachtet.<br />

Der zweite Gutachter war Dipl.-Inform. Alexander Kaiser.<br />

Ich danke meinem Betreuer Dr.-Ing. Wolfram Schenck für das interessante Thema und<br />

die Unterstützung während der Bearbeitung.<br />

2 Universität Bielefeld, AG Technische Informatik


Kurzbeschreibung<br />

Die Verwendung der Grafikkarte als universelle Berechnungseinheit hat in den letzten<br />

Jahren stark zugenommen. Viele rechenintensive Anwendungen wie z.B. physikalische<br />

Simulationen, Bild- und Videoverarbeitung oder die automatische Spracherkennung<br />

können durch den Einsatz <strong>von</strong> Grafikkarten signifikant beschleunigt werden. In dieser<br />

Bachelorarbeit wird gezeigt, wie ein künstliches neuronales Netzwerk (genauer: ein<br />

Neural-<strong>Gas</strong>-Netzwerk mit lokaler Hauptkomponentenanalyse) mit Hilfe der Programmierschnittstelle<br />

OpenCL auf einem Grafikprozessor trainiert werden kann, wodurch<br />

eine deutliche Geschwindigkeitssteigerung erreicht wird.<br />

Universität Bielefeld, AG Technische Informatik 3


Inhaltsverzeichnis<br />

Inhaltsverzeichnis<br />

1 Einleitung 6<br />

2 Theoretische Grundlagen 7<br />

2.1 <strong>GPU</strong> Computing . . . . . . . . . . . . . . . . . . . . . . . . . . . 7<br />

2.1.1 Erreichbarer Speedup . . . . . . . . . . . . . . . . . . . . 7<br />

2.1.2 Programmierschnittstellen . . . . . . . . . . . . . . . . . . 8<br />

2.1.3 Speichermodell . . . . . . . . . . . . . . . . . . . . . . . . 8<br />

2.2 Hauptkomponentenanalyse . . . . . . . . . . . . . . . . . . . . . 8<br />

2.3 Vektorquantisierung . . . . . . . . . . . . . . . . . . . . . . . . . 9<br />

2.4 Neural <strong>Gas</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9<br />

2.5 Erweiterung zu NGPCA . . . . . . . . . . . . . . . . . . . . . . . 10<br />

2.5.1 Lokale PCA . . . . . . . . . . . . . . . . . . . . . . . . . . 10<br />

2.5.2 Distanzmaß . . . . . . . . . . . . . . . . . . . . . . . . . . 11<br />

2.5.3 Training . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12<br />

2.6 Orthonormalisierung . . . . . . . . . . . . . . . . . . . . . . . . . 12<br />

3 <strong>Implementation</strong> 13<br />

3.1 Initialisierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15<br />

3.2 Distanzberechnung . . . . . . . . . . . . . . . . . . . . . . . . . . 15<br />

3.2.1 Verwendetes Potential . . . . . . . . . . . . . . . . . . . . 16<br />

3.3 Ranking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16<br />

3.3.1 Sortierverfahren . . . . . . . . . . . . . . . . . . . . . . . 16<br />

3.4 Adaptierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16<br />

3.4.1 Hauptkomponentenanalyse . . . . . . . . . . . . . . . . . 17<br />

3.4.2 Orthonormalisierung . . . . . . . . . . . . . . . . . . . . . 17<br />

3.5 Harte Vektorquantisierung . . . . . . . . . . . . . . . . . . . . . . 18<br />

3.5.1 Adaptive Anpassung der parallelen Trainingsvektoren . . 19<br />

4 Experimentelle Ergebnisse 20<br />

4.1 Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20<br />

4.2 Roboterarmsteuerung . . . . . . . . . . . . . . . . . . . . . . . . 21<br />

4.3 CT Slices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22<br />

4.4 Speedup nach gewählten Parametern . . . . . . . . . . . . . . . 23<br />

4.4.1 Anzahl der Prototypen . . . . . . . . . . . . . . . . . . . . 23<br />

4.4.2 Anzahl der Eigenwerte . . . . . . . . . . . . . . . . . . . . 24<br />

4.4.3 Verwendetes Potential . . . . . . . . . . . . . . . . . . . . 25<br />

4.5 Kernellaufzeiten . . . . . . . . . . . . . . . . . . . . . . . . . . . 25<br />

4 Universität Bielefeld, AG Technische Informatik


Inhaltsverzeichnis<br />

5 Diskussion 27<br />

5.1 Pre-Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27<br />

5.1.1 PCA-Verfahren . . . . . . . . . . . . . . . . . . . . . . . . 27<br />

5.1.2 Orthonormalisierungsverfahren . . . . . . . . . . . . . . . 27<br />

5.1.3 <strong>Implementation</strong> einer OpenCL Matrix-Bibliothek . . . . . . 28<br />

5.2 Beurteilung der Ergebnisse . . . . . . . . . . . . . . . . . . . . . 28<br />

5.2.1 Einfluss der gewählten Parameter . . . . . . . . . . . . . 29<br />

5.2.2 Wahl der Plattform . . . . . . . . . . . . . . . . . . . . . . 31<br />

6 Ausblick 32<br />

6.1 EFORRLSA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32<br />

6.2 AVX, Nvidia Tesla, AMD Plattform . . . . . . . . . . . . . . . . . 32<br />

6.3 Orthonormalisierung . . . . . . . . . . . . . . . . . . . . . . . . . 33<br />

6.4 Adaptive Anpassung der parallelen Trainingsvektoren . . . . . . 33<br />

Literaturverzeichnis 34<br />

A Verwendete Parameter 36<br />

A.1 Roboterarmsteuerung . . . . . . . . . . . . . . . . . . . . . . . . 36<br />

A.2 CT Slices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36<br />

B Quelltexte 37<br />

C Kompilierung und Ausführung der Quelltexte 43<br />

D Verwendete Software-Bibliotheken 44<br />

E Kommandozeilenparameter 45<br />

Universität Bielefeld, AG Technische Informatik 5


1<br />

Einleitung<br />

In den letzten Jahren hat <strong>GPU</strong> Computing, also die Verwendung der Grafikkarte<br />

als universelle Berechnungseinheit, immer mehr an Bedeutung gewonnen. Moderne<br />

Grafikkarten besitzen mittlerweile ein Vielfaches der Rechenleistung aktueller Prozessoren<br />

1 , so dass sie auch für wissenschaftliche Anwendungen interessant werden.<br />

Zudem steht mit OpenCL eine Programmierschnittstelle zur Verfügung, mit der die<br />

Implementierung abstrakt zur eigentlichen Hardwareplattform stattfinden kann.<br />

Im Rahmen dieser Bachelorarbeit wurde eine <strong>GPU</strong>-Implementierung für ein Neural-<br />

<strong>Gas</strong>-Netzwerk mit lokaler <strong>Principal</strong> <strong>Component</strong> Analysis (Möller und Hoffmann,<br />

2004) erstellt. Aufgrund der Unterteilung in lokale PCAs verspricht die Umsetzung<br />

auf der Grafikkarte einen erheblichen Geschwindigkeitszuwachs, da die bei diesem<br />

Verfahren verwendeten Prototypen parallel berechnet werden können.<br />

Kapitel 2 beginnt mit einer näheren Betrachtung des <strong>GPU</strong> Computing und führt<br />

anschließend das zugrunde liegende Verfahren Neural <strong>Gas</strong> mit lokaler <strong>Principal</strong><br />

<strong>Component</strong> Analysis 2 mit den nötigen Grundlagen ein.<br />

In Kapitel 3 wird die grundlegende Struktur der Applikation erläutert, woraufhin auf die<br />

einzelnen Schritte des Lernverfahrens mit den nötigen <strong>GPU</strong>-spezifischen Anpassungen<br />

eingegangen wird.<br />

Die resultierende Geschwindigkeit der <strong>Implementation</strong> wird in Kapitel 4 anhand <strong>von</strong><br />

zwei ausgewählten Datensätzen evaluiert. Dabei wird der Speedup betrachtet, also das<br />

Verhältnis <strong>von</strong> CPU-Laufzeit zu <strong>GPU</strong>-Laufzeit.<br />

Abschließend werden in Kapitel 5 die vor dieser Bachelorarbeit durchgeführten Tests<br />

erläutert und die aus Kapitel 4 resultierenden Ergebnisse diskutiert. Einen Ausblick auf<br />

mögliche Erweiterungen und Verbesserungen gibt Kapitel 6.<br />

1 http://developer.download.nvidia.com/compute/DevZone/docs/html/C/<br />

doc/CUDA_C_Programming_Guide.pdf<br />

Datum: 03.09.2012<br />

2 Im Folgenden “NGPCA” genannt<br />

6 Universität Bielefeld, AG Technische Informatik


2<br />

Theoretische Grundlagen<br />

2.1 <strong>GPU</strong> Computing<br />

Mit <strong>GPU</strong> Computing (auch GP<strong>GPU</strong> 1 genannt) bezeichnet man die Verwendung der<br />

<strong>GPU</strong> für Berechnungen, die normalerweise auf der CPU ausgeführt werden.<br />

Im Laufe der letzten Jahre hat sich die Leistungsfähigkeit <strong>von</strong> Grafikkarten rasant<br />

entwickelt. Während moderne Prozessoren weniger als 500 GFLOPs 2 verarbeiten<br />

können, schaffen aktuelle Grafikkarten bereits über 3.000 GFLOPs 3 . Sie sind also<br />

theoretisch sehr gut zum wissenschaftlichen Rechnen geeignet. Leider lässt sich<br />

bestehende Software nicht 1:1 auf die <strong>GPU</strong> übertragen, was an der zugrunde liegenden<br />

Hardware-Architektur liegt:<br />

Während CPUs zum schnellen Abarbeiten <strong>von</strong> sequenziellen Befehlen ausgelegt sind,<br />

erreichen <strong>GPU</strong>s ihre Leistung durch starke Parallelisierung.<br />

2.1.1 Erreichbarer Speedup<br />

Sei P ∈ [0, 1] der parallelisierbare Anteil des Algorithmus, (1 − P ) der serielle Anteil<br />

und N ∈ N ∗ die Anzahl an parallelen Recheneinheiten. Dann wird der theoretische<br />

maximale Speedup S, also die erreichbare Beschleunigung, durch Amdahls Gesetz<br />

(Amdahl, 1988) beschrieben:<br />

S(N) =<br />

1<br />

(1 − P ) + P N<br />

Der Speedup wird dabei nach oben beschränkt durch:<br />

lim S(N) = 1<br />

N→∞ (1 − P )<br />

1 GP<strong>GPU</strong> = General Purpose Computation on Graphics Processing Unit<br />

2 GFLOPs = 10 9 Gleitkommaoperationen pro Sekunde<br />

3 http://developer.download.nvidia.com/compute/DevZone/docs/html/C/<br />

doc/CUDA_C_Programming_Guide.pdf<br />

Datum: 03.09.2012<br />

(2.1)<br />

(2.2)<br />

Universität Bielefeld, AG Technische Informatik 7


2 Theoretische Grundlagen<br />

Somit ist eine hohe Parallelisierbarkeit essenziell für eine schnelle Implementierung<br />

auf der Grafikkarte.<br />

2.1.2 Programmierschnittstellen<br />

Für die Programmierung <strong>von</strong> <strong>GPU</strong>s stehen einige Programmierschnittstellen zur<br />

Verfügung, <strong>von</strong> denen sich jedoch das proprietäre Nvidia CUDA C und der offene Standard<br />

OpenCL durchgesetzt haben. Der große Vorteil <strong>von</strong> OpenCL ist, dass die Implementierung<br />

abstrakt zur eigentlichen Hardwareplattform stattfindet, weshalb es auch für<br />

diese Bachelorarbeit verwendet wurde. Dem entgegen steht die etwas umständlichere<br />

Programmierung und die geringere Verbreitung im Gegensatz zu CUDA C.<br />

OpenCL<br />

OpenCL kann ein oder mehrere OpenCL-Geräte ansprechen, wobei diese <strong>von</strong> verschiedenen<br />

Treibern, den sog. Plattformen, gesteuert werden. Geschriebener Quellcode muss<br />

dabei für jede Plattform separat kompiliert werden, was jedoch zur Laufzeit geschieht.<br />

Funktionsaufrufe auf der <strong>GPU</strong> werden Kernel genannt. Kernel führen den selben Programmcode<br />

parallel auf mehreren sog. Work-Items aus, die ein-, zwei- oder dreidimensional<br />

angeordnet sein können. Work-Items werden zu Work-Groups zusammengefasst,<br />

in denen gemeinsamer lokaler Speicher (schnell, siehe Kapitel 2.1.3) und Synchronisationsmechanismen<br />

zur Verfügung stehen (Munshi, 2012).<br />

2.1.3 Speichermodell<br />

Während auf dem Host nur eine Art <strong>von</strong> Hauptspeicher vorhanden ist, besitzen Grafikkarten<br />

verschiedene Arten <strong>von</strong> Speicher mit unterschiedlichen Eigenschaften (Munshi,<br />

2012; Sanders und Kandrot, 2010):<br />

• Globaler Speicher<br />

Größter verfügbarer Speicherbereich (ca. 512 MB - 2 GB), langsamer Zugriff.<br />

• Konstanter Speicher<br />

Spezieller nur lesbarer Speicher, optimiert für schnellen parallelen Zugriff.<br />

• Lokaler Speicher<br />

Sehr schneller Speicherbereich, den sich die Work-Items einer Work-Group teilen.<br />

Typischerweise 16 KB groß.<br />

• Privater Speicher<br />

Innerhalb eines Work-Items genutzter Speicher. Wird z.B. für lokale Variablen<br />

verwendet.<br />

2.2 Hauptkomponentenanalyse<br />

<strong>Principal</strong> <strong>Component</strong> Analysis (PCA) (Jolliffe, 1986) ist ein lineares Dimensionsreduktionsverfahren.<br />

Dabei wird die Menge der Eingabevektoren X = { ⃗x 1 , ..., x⃗<br />

N } ⊂ R n auf<br />

Vektoren niedriger Dimensionalität Y = {⃗y 1 , ..., y⃗<br />

N } ⊂ R m mit m ≤ n abgebildet. Um<br />

8 Universität Bielefeld, AG Technische Informatik


2 Theoretische Grundlagen<br />

den Informationsverlust zu minimieren werden genau die Achsen weggelassen, die die<br />

geringste Varianz aufweisen. Dies sind die Eigenvektoren zu den kleinsten Eigenwerten<br />

der Kovarianzmatrix<br />

C = 1 N∑<br />

(⃗x n − ⃗µ)(⃗x n − ⃗µ) T (2.3)<br />

N<br />

mit ⃗µ = 1 N<br />

∑ N<br />

n=1 ⃗x n.<br />

n=1<br />

2.3 Vektorquantisierung<br />

Vektorquantisierung ist ein Verfahren zur Datenkompression bzw. zum Datenclustering.<br />

Hierbei werden die Eingabedaten durch k Merkmalsvektoren ausgedrückt. Die Menge<br />

der Prototypen C = {⃗c 1 , . . . , ⃗c k } wird auch als Codebuch bezeichnet. Grundsätzlich<br />

unterscheidet man 2 Arten <strong>von</strong> Vektorquantisierung:<br />

• Harte Vektorquantisierung<br />

Jedem Eingabevektor wird genau ein Merkmalsvektor zugewiesen:<br />

q : ⃗x ↦→ ⃗c i , i ∈ {1 . . . k} (2.4)<br />

• Weiche Vektorquantisierung<br />

Die Wahrscheinlichkeit p(⃗x|⃗c i ), i ∈ {1 . . . k}, dass der Eingabevektor <strong>von</strong> dem i-<br />

ten Merkmalsvektor erzeugt wurde, wird modelliert. Die Wahrscheinlichkeitsverteilung<br />

lässt sich nun als Summe der Zuordnungswahrscheinlichkeiten definieren:<br />

k∑<br />

p(⃗x) = π i p(⃗x|⃗c i ) (2.5)<br />

i=1<br />

Wobei die Mischkoeffizienten π i > 0 mit<br />

Wahrscheinlichkeiten angeben.<br />

2.4 Neural <strong>Gas</strong><br />

∑ k<br />

i=1 π i = 1 die A-priori-<br />

Der Neural-<strong>Gas</strong>-Algorithmus (NG) (Martinetz et al., 1993) kann als Generalisierung<br />

der Online-Variante des k-Means-Algorithmus verstanden werden. Im Unterschied<br />

zu k-Means ist Neural <strong>Gas</strong> jedoch ein weiches Vektorquantisierungsverfahren, da in<br />

jedem Lernschritt alle Merkmalsvektoren in Abhängigkeit <strong>von</strong> der Entfernung zum<br />

Datenpunkt angepasst werden. Hierdurch wird eine robuste und <strong>von</strong> der Initialisierung<br />

der Prototypen größtenteils unabhängige Konvergenz erreicht.<br />

Zunächst werden alle k Merkmalsvektoren mit zufällig ausgewählten Eingabevektoren<br />

initialisiert. Anschließend wird in jedem Lernschritt ein Eingabevektor ⃗x zufällig aus<br />

den Eingabedaten gezogen und der Rang<br />

r(⃗c i , ⃗x) = |{⃗c j | ‖⃗c j − ⃗x‖ < ‖⃗c i − ⃗x‖}| (2.6)<br />

jedes Prototypen ermittelt. Der Rang eines Prototypen ist also die Position des Merkmalsvektors<br />

in einer aufsteigend nach Distanz zum Eingabevektor sortierten Liste. Dieser<br />

geht direkt als Gewichtung in die Lernregel<br />

∆⃗c i = ɛ · h p (r(⃗c i , ⃗x)) · (⃗x − ⃗c i ) (2.7)<br />

Universität Bielefeld, AG Technische Informatik 9


2 Theoretische Grundlagen<br />

ein, wobei ɛ ∈ [0, 1] die Lernrate und h p (r) = e −r/p der Nachbarschaftsfaktor mit<br />

Nachbarschaftsreichweite p ist. Sowohl die Lernrate als auch der Nachbarschaftsfaktor<br />

fallen exponentiell während des Trainingsprozesses ab:<br />

ɛ(t) = ɛ init ·<br />

(<br />

ɛfinal<br />

ɛ init<br />

) t/tmax<br />

(2.8)<br />

p(t) = p init ·<br />

(<br />

pfinal<br />

p init<br />

) t/tmax<br />

(2.9)<br />

Durch das Abfallen der Trainingsparameter kann neben der “globalen Ordnung” auch<br />

gegen Ende des Lernprozesses die “lokale Ordnung” durch nur noch kleine lokale Änderungen<br />

der Merkmalsvektoren optimiert werden.<br />

2.5 Erweiterung zu NGPCA<br />

Das in dieser Bachelorarbeit auf der <strong>GPU</strong> implementierte Verfahren NGPCA (Möller<br />

und Hoffmann, 2004) basiert auf Neural <strong>Gas</strong>, erweitert es jedoch um lokale PCAs und<br />

benutzt dazu passende Distanzmaße.<br />

2.5.1 Lokale PCA<br />

Lokale PCA-Verfahren beruhen darauf, mit Hilfe eines Vektorquantisierers den Eingaberaum<br />

zu partitionieren und anschließend jede Partition durch eine PCA zu approximieren.<br />

Bei hinreichender Anzahl an Partitionen lassen sich so beliebig komplexe Mannigfaltigkeiten<br />

gut approximieren. NGPCA ist ein solches Verfahren, welches Neural<br />

<strong>Gas</strong> als Vektorquantisierer benutzt. Jede lokale PCA wird dabei zu einem Tupel, der<br />

sog. Unit U i = (⃗c i , W i , Λ i , σi 2 ) zusammengefasst. Dabei ist ⃗c i der Merkmalsvektor, W i<br />

eine Matrix mit den m größten Hauptachsen der PCA, Λ i eine Diagonalmatrix mit den<br />

entsprechenden Varianzen der Hauptachsen und σi 2 = ∑ n<br />

j=m+1 λ j die Residualvarianz,<br />

also die summierte Varianz der (n−m) Dimensionen, die nicht durch W i erfasst werden.<br />

Somit ergibt sich als neues Codebuch U = {U i , . . . , U k }<br />

Robust Recursive Least Squares Learning Algorithm (RRLSA)<br />

Robust Recursive Least Squares Learning Algorithm (RRLSA) (Ouyang et al., 2000)<br />

ist ein Verfahren zur Hauptkomponentenanalyse und kommt bei dieser Bachelorarbeit<br />

zum Einsatz.<br />

Grundlage für das Verfahren ist die Hebbsche Lernregel,<br />

∆⃗w = ɛ · y · ⃗x − λ⃗w (2.10)<br />

mit der die erste Hauptkomponente der Daten iterativ mit einem Perzeptron bestimmt<br />

werden kann. ɛ ist dabei die Lernrate, ⃗w der Gewichtsvektor, y = ⃗w T ⃗x die Ausgabe des<br />

Perzeptrons und λ⃗w ein Abklingterm, der durch λ parametrisiert wird. Dies spart die<br />

aufwändige Berechnung der Kovarianzmatrix.<br />

Um nun auch die weiteren Hauptachsen bestimmen zu können, werden Perzeptren sequenziell<br />

verknüpft.<br />

10 Universität Bielefeld, AG Technische Informatik


2 Theoretische Grundlagen<br />

Dem zweiten Perzeptron wird der Eingabevektor abzüglich der Projektion auf den ersten<br />

Gewichtsvektors als Eingabe präsentiert:<br />

⃗ξ i =<br />

{ ⃗x i = 1<br />

⃗ξ i−1 − y i−1 ⃗w i−1 i > 1<br />

(2.11)<br />

Führt man dieses als Deflation (Sanger, 1989) bezeichnete Verfahren fort, erhält man<br />

sequenziell verschaltete Neuronen, die zu den Eigenvektoren der Kovarianzmatrix konvergieren.<br />

Dieses Verfahren wird Generalized Hebbian Algorithm (Sanger, 1989) genannt.<br />

RRLSA baut auf der Deflation auf, verwendet jedoch unnormalisierte Gewichtsvektoren.<br />

Diese lassen sich rekursiv durch<br />

∆ ˜w i = ɛ( ⃗ ξ i y i − ˜w i ) (2.12)<br />

berechnen. Den Eigenwert erhält man aus der Länge des Gewichtsvektors, den Eigenvektor<br />

durch Normalisierung:<br />

λ i = ‖ ˜w i ‖, ⃗w i =<br />

˜w i<br />

‖ ˜w i ‖<br />

(2.13)<br />

Da die resultierenden Eigenvektoren nicht zwingend paarweise orthogonal zueinander<br />

sind, ist eine regelmäßige Orthonormalisierung notwendig (siehe Kapitel 2.6).<br />

2.5.2 Distanzmaß<br />

Neural <strong>Gas</strong> bestimmt den Rang eines Merkmalsvektors mit Hilfe des euklidischen Abstandes.<br />

Dadurch wird die Struktur der PCA-Unterräume jedoch nicht beachtet, weshalb<br />

es sinnvoll ist, die verwendete Metrik anzupassen. NGPCA beschreibt die normalisierte<br />

Mahalanobis-Distanz und ein volumenunabhängiges Abstandsmaß. In dieser Bachelorarbeit<br />

wurde das volumenunabhängige Abstandsmaß verwendet, da die normalisierte<br />

Mahalanobis-Distanz bei stark gestreuten Datenpunkten problematisch ist (Hoffmann,<br />

2004).<br />

Volumenunabhängiges Abstandsmaß<br />

Grundlage für das volumenabhängige Abstandsmaß ist die normalisierte Mahalanobis-<br />

Distanz. Diese basiert auf multivariaten Normalverteilungen, dessen Zentren die<br />

Merkmalsvektoren bilden. Als Achsen für den Hyperellipsoiden werden die Hauptachsen<br />

der PCA verwendet, skaliert mit der Standardabweichung der entsprechenden<br />

Richtungen. Da im Falle einer Dimensionsreduktion (m < n) nicht mehr alle Punkte<br />

korrekt zugeordnet werden können (Möller und Hoffmann, 2004), wird das Modell um<br />

den Rekonstruktionsfehler (Kambhatla und Leen, 1997) erweitert.<br />

Durch Normalisieren der Eigenwerte abhängig vom Volumen des Ellipsoiden (Hoffmann,<br />

2004) erhält man<br />

(<br />

d i (⃗x) = ⃗y i T Λ −1<br />

i ⃗y i + 1 )<br />

( ξ<br />

λ ⃗T ⃗ ∗ i ξ i − ⃗y i T ⃗y i ) V 2/n<br />

i (2.14)<br />

i<br />

mit ⃗ ξ i = ⃗x − ⃗c i , ⃗y i = W T<br />

i ⃗ ξ i , λ ∗ i =<br />

σ2 i<br />

und V = √ |Λ|.<br />

n−m<br />

Universität Bielefeld, AG Technische Informatik 11


2 Theoretische Grundlagen<br />

2.5.3 Training<br />

Das Training eines NGPCA-Netzwerkes verläuft analog zu Neural <strong>Gas</strong>. Zuerst werden<br />

die Mittelpunkte ⃗c i der Units zufällig mit Vektoren aus der Trainingsmenge initialisiert.<br />

Die Wahl der Eigenwerte ist beliebig, alle Units sollten jedoch mit den selben Eigenwerten<br />

initialisiert werden. W i kann ebenfalls frei gewählt werden, hier ist allerdings<br />

auf Orthonormalität zu achten.<br />

Während des Lernprozesses werden zufällig Trainingsvektoren ⃗x aus der Trainingsmenge<br />

gewählt und der Rang r(⃗c i , ⃗x) aller Prototypen bestimmt. Dabei wird die in Gl.<br />

2.14 definierte Metrik verwendet. Anschließend werden die Zentren der Units nach<br />

Gl. 2.7 aktualisiert, wobei die Trainingsparameter nach Gl. 2.8 und 2.9 exponentiell<br />

abfallen.<br />

Das Verfahren zur Bestimmung der lokalen PCAs ist austauschbar. In dieser Bachelorarbeit<br />

wurde RRLSA (Möller und Hoffmann, 2004) verwendet. Hierbei ist auf anschließende<br />

Orthonormalisierung <strong>von</strong> W i zu achten. Die Residualvarianz ergibt sich aus<br />

mit α = ɛ · h p (r(⃗c i , ⃗x)).<br />

∆σ 2 i = α( ⃗ ξ i T ⃗ ξi − ⃗y i T ⃗y i − σ 2 i ) (2.15)<br />

Das beschriebene Verfahren aktualisiert in jeder Iteration alle Units und wird im Folgenden<br />

Soft Clustering genannt. In einigen Szenarien kann es ausreichend sein, nur die Unit<br />

mit der niedrigsten Distanz zum Trainingsvektor ⃗x zu adaptieren (U i mit r(⃗c i , ⃗x) = 0).<br />

Dieser als Hard Clustering bezeichnete Ansatz hat den Vorteil, einen Großteil der für<br />

die Adaption der PCAs benötigten Rechenzeit einzusparen.<br />

2.6 Orthonormalisierung<br />

Zur Orthonormalisierung wird das Gram-Schmidtsche Orthonormalisierungsverfahren<br />

(Giraud et al., 2005) verwendet, welches zu den Vektoren ⃗a 1 , . . . , ⃗a n ein Orthonormalsystem<br />

⃗q 1 , . . . , ⃗q n berechnet. Der klassische Algorithmus (Listing 2.1) ist jedoch numerisch<br />

instabil (Björck, 1994), weshalb die mathematisch äquivalente modifizierte Variante<br />

benutzt wird (Listing 2.2).<br />

f o r i = 1 : n<br />

⃗q i = ⃗a i<br />

f o r i = 1 : n<br />

⃗q i = ⃗a i<br />

f o r j = 1 : i −1<br />

∆⃗q i = −〈⃗q j , ⃗a i 〉 · ⃗q j<br />

end<br />

f o r j = 1 : i −1<br />

∆⃗q i = −〈⃗q j , ⃗q i 〉 · ⃗q j<br />

end<br />

end<br />

⃗q i = ⃗q i / ‖⃗q i ‖<br />

end<br />

⃗q i = ⃗q i / ‖⃗q i ‖<br />

Listing 2.1: Klassische Gram-Schmidt Orthogonalisierung<br />

Listing 2.2: Modifizierte Gram-Schmidt Orthogonalisierung<br />

Dabei bezeichnet 〈⃗a, ⃗ b〉 das Skalarprodukt zwischen ⃗a und ⃗ b.<br />

12 Universität Bielefeld, AG Technische Informatik


3<br />

<strong>Implementation</strong><br />

In diesem Kapitel wird die Realisierung des NGPCA-Algorithmus auf der Grafikkarte<br />

erläutert. Hierfür wurde C++ als Programmiersprache und OpenCL als Schnittstelle<br />

zur Programmierung der <strong>GPU</strong> verwendet. Da OpenCL in C geschrieben ist, wurden<br />

die OpenCL C++ Bindings (siehe Anhang D) verwendet. Diese ermöglichen einen<br />

objektorientierten Zugriff auf die OpenCL-Funktionen und erlauben die elegante<br />

Fehlerabfrage mittels Exceptions.<br />

Die Anwendung wurde durchgehend objektorientiert entworfen, eine Übersicht über<br />

die wichtigsten erstellten Klassen können Sie dem Klassendiagramm in Abbildung 3.1<br />

entnehmen.<br />

CLI<br />

CLI(argc,argv)<br />

parse() : int<br />

units : Unit*<br />

params : NGPCAParams<br />

NGPCA<br />

NGPCA(params,threadCount,hardClustering,...,deviceId)<br />

loadFromFile(file)<br />

learn(iterations)<br />

write(file)<br />

NGPCAParams<br />

prototypes : uint<br />

eigenvalues : uint<br />

Unit<br />

center : T*<br />

w : T*<br />

lambda : T*<br />

sigma : T*<br />

write(out) : void<br />

Abbildung 3.1: Klassendiagramm der wichtigsten Klassen. Einzelne Attribute und Methoden wurden weggelassen.<br />

Einstiegspunkt der Applikation ist die CLI-Klasse. Hier werden die Kommandozeilenparameter<br />

mit Hilfe der Boost Program Options Bibliothek (siehe Anhang<br />

D) ausgewertet und durch sinnvolle Vorgabewerte erweitert. Des Weiteren werden<br />

Hilfsfunktionen wie die Anzeige aller verfügbarer OpenCL-Geräte oder die Darstellung<br />

einer Hilfeseite bereitgestellt. Die zuvor erfassten Trainingsparameter werden in einem<br />

NGPCAParams-Struct gespeichert und für die Instanziierung eines NGPCA-Objektes<br />

verwendet. Da die NGPCA-Klasse generisch programmiert wurde, ist eine einfache<br />

Umstellung <strong>von</strong> 32 Bit Fließkommazahlen auf 64 Bit möglich. In der Praxis muss ein<br />

NGPCA-Netzwerk aber mit doppelter Genauigkeit trainiert werden, da das Ergebnis<br />

Universität Bielefeld, AG Technische Informatik 13


3 <strong>Implementation</strong><br />

sonst unzureichend ist. Dies ist insbesondere für die Implementierung auf der Grafikkarte<br />

<strong>von</strong> Nachteil, da Berechnungen mit doppelter Genauigkeit deutlich langsamer<br />

durchgeführt werden (siehe Tabelle 4.1).<br />

Über die loadFromFile-Methode der NGPCA-Klasse kann nun eine Matrix mit<br />

Trainingsdaten geladen werden. Dabei wird der OpenCL-Quellcode für das gewählte<br />

Gerät kompiliert, wobei datensatzspezifische Precompiler-Direktiven wie z.B. die<br />

Größe der Eingabevektoren, die zu benutzende Eigenwertanzahl etc. gesetzt werden.<br />

Dadurch kann der OpenCL-Compiler Optimierungen wie z.B. Loop Unrolling (Murthy<br />

et al., 2010) vornehmen, die bei Übergabe der Parameter zur Laufzeit nicht möglich<br />

wären. Nach dem Kompiliervorgang werden die Units auf der Grafikkarte initialisiert<br />

und die Eingabedaten auf das OpenCL-Gerät kopiert (siehe Kapitel 3.1), so dass nach<br />

dem Ausführen der loadFromFile-Methode alle benötigten Daten initialisiert auf der<br />

Grafikkarte vorliegen.<br />

Der Lernprozess kann mit der learn-Methode der NGPCA-Klasse gestartet werden,<br />

wobei die Anzahl der Iterationen als Parameter übergeben wird. Grundidee<br />

ist, dass jede Unit eine Work-Group bildet, so dass die Distanzberechnung und die<br />

Adaption parallel über alle Units durchgeführt wird. Die Daten der Units U i =<br />

(⃗c i , W i , Λ i , σi 2 ) verbleiben dabei aus Performancegründen während des gesamten Lernprozesses<br />

im globalen Speicher der Grafikkarte und werden erst zur finalen Speicherung<br />

wieder in den Arbeitsspeicher kopiert. Da eine globale Synchronisation<br />

über alle Units nicht innerhalb eines Kernels möglich ist, jedoch für das Ranking<br />

benötigt wird, wurde jede Iteration in 4 Kernel unterteilt (siehe Abbildung 3.2).<br />

Zunächst wird die Distanzberechnung für<br />

einen Datenpunkt ⃗x parallel ausgeführt. Anschließend<br />

werden die Resultate zur Rangbestimmung<br />

r(⃗c i , ⃗x) sortiert und parallel dazu<br />

die Lernparameter bestimmt. Abschließend<br />

findet die Adaption (inkl. Orthonormalisierung)<br />

wieder parallel über alle Units statt. Bei<br />

der Verwendung <strong>von</strong> Hard Clustering (Kapitel<br />

2.5.3) wird jedoch nur eine Unit angepasst,<br />

weshalb die in Abbildung 3.2 rot markierten<br />

Schritte nicht ausgeführt werden.<br />

Alle j Iterationen wird ein weiterer Kernel<br />

zur Überprüfung der Units gestartet. Dieser<br />

erkennt “tote” Units und setzt diese zurück<br />

(Welsch, 2009).<br />

Der auf der CPU während einer Iteration<br />

ausgeführte Programmcode ist ein potentieller<br />

Flaschenhals und wurde somit möglichst<br />

effizient gestaltet. Es wird lediglich der<br />

nächste Trainingsvektor zufällig bestimmt,<br />

dessen Index als Kernelparameter übergeben<br />

Kernel: Distanzberechnung<br />

Unit 1 Unit 2 ... Unit k<br />

Kernel: Ranking und Parameterbestimmung<br />

Ranking<br />

Kernel: Adaption<br />

Parameterbestimmung<br />

Unit 1 Unit 2 ... Unit k<br />

Kernel: Überprüfung der Units<br />

Unit 1 Unit 2 ... Unit k<br />

Abbildung 3.2: Kernelaufrufe einer Iteration<br />

und der Start der entsprechenden Kernel angestoßen. In den Kapiteln 3.1 bis 3.4 werden<br />

die einzelnen Trainingsschritte näher erläutert.<br />

14 Universität Bielefeld, AG Technische Informatik


3 <strong>Implementation</strong><br />

Nachdem das NGPCA-Netzwerk erfolgreich trainiert wurde, kann mit der write-<br />

Methode der NGPCA-Klasse das Ergebnis in einer Datei gespeichert werden. Dabei<br />

werden die Daten U i <strong>von</strong> der Grafikkarte kopiert und in einem speziellen Format in die<br />

übergebene Datei geschrieben.<br />

3.1 Initialisierung<br />

Die Initialisierung beginnt mit der Bestimmung einer sinnvollen Work-Group-Größe<br />

aufgrund der festgelegten Thread-Anzahl. Dazu werden die zu benutzenden Threads<br />

auf ein zweidimensionales Gitter aufgeteilt, wobei dieses jeweils optimal zu den<br />

verwendeten Kerneln gewählt wird. Außerdem wird sichergestellt, dass aufgrund der<br />

verwendeten Reduktionen (Sanders und Kandrot, 2010) nur Zweierpotenzen benutzt<br />

werden.<br />

Anschließend wird der in die Applikation automatisch einkompilierte OpenCL-<br />

Quellcode für das gewählte Gerät kompiliert, wonach die Trainingsvektoren auf das<br />

Gerät kopiert werden. Abschließend wird (globaler) Speicher für die Units reserviert,<br />

welcher dann mit einem Kernel parallel für alle Units initialisiert wird. Der Trainingsvektor<br />

wird innerhalb des Kernels zufällig gewählt und gesetzt, wobei ein 32 Bit Xorshift<br />

Pseudozufallszahlengenerator 1 (Marsaglia, 2003) zum Einsatz kommt. Dieser wird<br />

auch für die Initialisierung der Gewichtsmatrix W i benutzt, die anschließend gemäß<br />

Kapitel 3.4.2 orthonormalisiert wird. Alle weiteren Parameter können einfach aus dem<br />

übergebenen NGPCAParams-Struct übernommen werden.<br />

3.2 Distanzberechnung<br />

Wie bereits erwähnt, berechnet jede Work-Group die Distanz einer Unit U i zum<br />

Trainingsvektor ⃗x. Bei Vektoroperationen wie z.B. ξ ⃗ i = ⃗x − ⃗c i werden die Work-Items<br />

eindimensional verwendet, so dass jedes Work-Item eine oder mehrere Positionen in<br />

dem resultierenden Vektor ermittelt. Matrixoperationen werden hingegen zweidimensional<br />

ausgeführt.<br />

Skalare Werte wie ⃗ ξ i T ⃗ ξi und ⃗y i T ⃗y i werden mittels Reduktion (Sanders und Kandrot,<br />

2010) berechnet, was sich insbesondere bei großen Trainingsvektoren positiv auf die<br />

Laufzeit auswirkt. Um doppelte Berechnungen zu vermeiden, wird das resultierende ⃗ ξ i ,<br />

⃗y i , ⃗ ξ i T ⃗ ξi und ⃗y i T ⃗y i für die spätere Adaption im globalen Speicher zwischengespeichert.<br />

Für die Erkennung <strong>von</strong> “toten” Units besitzt jede Unit einen Zähler, der die “Restlebensdauer”<br />

angibt. Dieser wird bei der Distanzberechnung dekrementiert und bei Adaptierung<br />

einer Unit wieder zurückgesetzt. Ein spezieller Kernel (siehe Abbildung 3.2)<br />

überprüft die verbleibende Lebensdauer aller Units in einem einstellbaren Intervall und<br />

setzt diese ggf. zurück (Welsch, 2009).<br />

1 Quellcode siehe Anhang B.1<br />

Universität Bielefeld, AG Technische Informatik 15


3 <strong>Implementation</strong><br />

3.2.1 Verwendetes Potential<br />

Das in Gl. 2.14 beschriebene Potential wurde implementiert und wird im Folgenden<br />

VConst bezeichnet. Es eignet sich jedoch nicht optimal für die <strong>GPU</strong>, da Wurzeln mit<br />

relativ hohen Wurzelexponenten berechnet werden müssen. Während das Wurzelziehen<br />

auf 32 Bit Fließkommazahlen hardwareseitig implementiert ist (Munshi, 2012), sind 64<br />

Bit Wurzeloperationen relativ langsam.<br />

Als Alternative wurde daher ein weiteres Potential<br />

(<br />

d i (⃗x) = ⃗y i T Λ −1<br />

i ⃗y i + 1 )<br />

( ξ<br />

λ ⃗T ⃗ ∗ i ξ i − ⃗y i T ⃗y i ) ·<br />

i<br />

(<br />

Tr (Λ −1<br />

i ) +<br />

) −1<br />

(n − m)2<br />

(3.1)<br />

σi<br />

2<br />

mit ξ ⃗ i = ⃗x − ⃗c i , ⃗y i = Wi T ξ ⃗ i und λ ∗ i = σ2 i<br />

implementiert, welches im Folgenden<br />

n−m<br />

TracePotential genannt wird (Kaiser und Schenck).<br />

3.3 Ranking<br />

Zur Bestimmung des Ranges r(⃗c i , ⃗x) einer Unit U i werden die in Kapitel 3.2 berechneten<br />

Distanzen aufsteigend sortiert. Der resultierende Rang ist dann die Position<br />

z ∈ [0 . . . k − 1] der zu der Unit gehörenden Distanz in der sortierten Distanzliste.<br />

3.3.1 Sortierverfahren<br />

Als Sortierverfahren wurde eine modifizierte Variante des Parallel Selection Sort 2,3<br />

verwendet. Dies ist ein naiver Algorithmus, der parallel jeden zu sortierenden Wert mit<br />

allen anderen Einträgen vergleicht.<br />

Da alle Work-Items gleichzeitig dieselbe Distanz zum Vergleich heranziehen, kann<br />

durch Broadcasting (Sanders und Kandrot, 2010) dennoch eine recht hohe Geschwindigkeit<br />

erreicht werden. Bei genügend Hardwareressourcen und damit einer echten<br />

parallelen Ausführung des Sortiervorganges wird eine Komplexität <strong>von</strong> O(n) erreicht.<br />

Es gibt durchaus noch schnellere und durch lokalen Speicher beschleunigte Sortierverfahren.<br />

Auf einen aufwändigen Algorithmus wurde aufgrund der niedrigen Anzahl der<br />

zu sortierenden Elemente und dem hierdurch geringen Anteil des Rankings an der Gesamtlaufzeit<br />

(siehe Tabelle 4.5) allerdings verzichtet.<br />

3.4 Adaptierung<br />

Die Adaptierung erfolgt wieder parallel für alle Units und basiert auf dem zuvor<br />

ermittelten Rang. Während beim Soft Clustering alle Units angepasst werden, wird<br />

beim Hard Clustering nur die Unit mit Rang 0 angepasst. Alle anderen Work-Groups<br />

beenden ihre Ausführung unmittelbar nach dieser Überprüfung.<br />

2 http://www.bealto.com/gpu-sorting_parallel-selection.html<br />

Datum: 21.09.2012<br />

3 Quellcode siehe Anhang B.2<br />

16 Universität Bielefeld, AG Technische Informatik


3 <strong>Implementation</strong><br />

Zunächst wird nach Gl. 2.7 das Zentrum der jeweiligen der Unit aktualisiert. Anschließend<br />

erfolgt die Berechnung der lokalen PCA mittels RRLSA (siehe Kapitel 3.4.1) und<br />

das wie in Kapitel 3.2 beschriebene Zurücksetzen des Alters der Unit. Die Residualvarianz<br />

wird nach Gl. 2.15 angepasst. Bei Erreichen des eingestellten Orthonormalisierungsintervalles<br />

(siehe Anhang E) erfolgt die Orthonormalisierung <strong>von</strong> W i nach Kapitel<br />

3.4.2.<br />

3.4.1 Hauptkomponentenanalyse<br />

Die lokale PCA wird mittels RRLSA (siehe Kapitel 2.5.1) berechnet. Dafür wird<br />

zunächst das während der Distanzberechnung ermittelte ⃗y i wegen der häufigen Verwendung<br />

in den lokalen Speicher geladen. Zur einfacheren Berechnung wird eine unnormalisierte<br />

Version <strong>von</strong> W i zusätzlich im globalen Speicher vorgehalten. W i und Λ i ergibt<br />

sich dann aus Gl. 2.13. Für die Normalisierung wird wie bei der Distanzberechnung eine<br />

Reduktion verwendet.<br />

3.4.2 Orthonormalisierung<br />

Das in Kapitel 2.6 beschriebene modifizierte Gram-Schmidtsche Orthogonalisierungsverfahren<br />

(MGS) ist zwar numerisch stabil, allerdings erzeugt es das Orthonormalsystem<br />

⃗q 1 , . . . , ⃗q n sequenziell. Aus diesem Grund ist es nur schlecht für eine<br />

Verwendung auf der <strong>GPU</strong> geeignet. Dennoch lässt sich das Verfahren parallel auf der<br />

<strong>GPU</strong> implementieren, so dass es deutlich schneller als die naive MGS Implementierung<br />

ist.<br />

Der Algorithmus 4 (Listing 3.1) arbeitet dabei direkt auf den zu orthonormalisierenden<br />

Vektoren, womit die Initialisierung ⃗q i = ⃗a i entfällt. Diese werden im Folgenden<br />

⃗q 1 , . . . , ⃗q n bezeichnet.<br />

Zunächst wird der erste Vektor ⃗q 1 mittels Reduktion normalisiert und das Ergebnis<br />

zurück in den globalen Speicher geschrieben. Der normalisierte Vektor ⃗q 1 verbleibt jedoch<br />

im lokalen Speicher der Work-Group und wird im Folgenden q last ⃗ genannt. Anschließend<br />

können alle Vektoren ⃗q i , i ∈ [2 . . . n] parallel das Skalarprodukt mit q last ⃗<br />

bilden. Dieses wird multipliziert mit q last ⃗ <strong>von</strong> dem Vektor ⃗q i subtrahiert:<br />

∆⃗q i = −〈⃗q i , q last ⃗ 〉 · q last ⃗ ∀ i ∈ [2 . . . n] (3.2)<br />

Durch Normalisierung ⃗q 2 = ⃗q 2 / ‖⃗q 2 ‖ ergibt sich der zweite Vektor des Orthonormalsystemes.<br />

Dieser wird nun als letzter orthonormalisierter Vektor q last ⃗ im lokalen<br />

Speicher gehalten, womit der Algorithmus mit der Aktualisierung aller Vektoren<br />

⃗q i , i ∈ [3 . . . n] fortfährt. Bei jeder Iteration ergibt sich also sequenziell ein Ergebnisvektor<br />

⃗q i , wobei die Anpassung der verbleibenden Vektoren ⃗q j , j ∈ [i + 1 . . . n] parallel<br />

geschieht.<br />

Der gesamte Algorithmus lässt sich zu Listing 3.1 zusammenfassen.<br />

4 Quellcode siehe Anhang B.4<br />

Universität Bielefeld, AG Technische Informatik 17


3 <strong>Implementation</strong><br />

⃗q 1 = ⃗q 1 / ‖⃗q 1 ‖<br />

q last ⃗ = ⃗q 1<br />

f o r j = 2 : n<br />

∆⃗q i = −〈⃗q i , q last ⃗ 〉 · q last ⃗ ∀ i ∈ [j . . . n]<br />

end<br />

⃗q j = ⃗q j / ‖⃗q j ‖<br />

q last ⃗ = ⃗q j<br />

Listing 3.1: Parallele Gram-Schmidt Orthonormalisierung<br />

Dabei erfolgt die Anpassung ∆⃗q i parallel über alle i. Alle Normierungen und Skalarprodukte<br />

werden durch Reduktionen berechnet.<br />

3.5 Harte Vektorquantisierung<br />

Wie bereits in Kapitel 2.5.3 und 3 erwähnt wurde, wird beim Hard Clustering nur eine<br />

Unit adaptiert. Dies spart einen Großteil der für die Adaption benötigten Rechenzeit<br />

ein. Es hat jedoch auch zur Folge, dass der Parallelitätsgrad während der Adaption sehr<br />

niedrig ist, wodurch nur ein Bruchteil der möglichen <strong>GPU</strong>-Leistung tatsächlich benutzt<br />

wird.<br />

Um die Auslastung der Grafikkarte zu<br />

erhöhen werden r Trainingsvektoren gleichzeitig<br />

Kernel: Distanzberechnung<br />

präsentiert (siehe Abbildung 3.3).<br />

Der Distanzkernel arbeitet folglich auf k · r<br />

Unit 1<br />

Unit k<br />

...<br />

x 1, x 2, ... x r<br />

x 1, x 2, ... x r<br />

Work-Groups, wobei k die Anzahl der benutzten<br />

Prototypen ist. Jede Work-Group berechnet<br />

also die Distanz einer bestimmten Unit U i<br />

Kernel: Ranking und Parameterbestimmung<br />

zu einem festgelegten Trainingsvektor ⃗x j .<br />

Ranking<br />

Ranking<br />

Parameterbestimmung<br />

Durch die Erweiterung auf mehrere Datenpunkte<br />

kann das Ranking ebenfalls erwei-<br />

...<br />

x 1<br />

x r<br />

tert werden. Dabei ermittelt jede Work-Group<br />

des Ranking-Kernels für einen bestimmten<br />

Kernel: Altersupdate der Units<br />

Datenpunkt ⃗x j die “Gewinnerunit” U i mit<br />

r(⃗c i , ⃗x j ) = 0. Bei den ermittelten “Gewinnerunits”<br />

Unit ... Unit<br />

kann es jedoch zu Überschneidungen<br />

kommen, falls zwei Trainingsvektoren derselben<br />

Kernel: Adaption<br />

Unit zugeordnet sind. Daher werden nur<br />

die zugeordneten Units der ersten s ≤ r Datenpunkte<br />

adaptiert, bei denen keine Überschneidung<br />

in den zu adaptierenden Units vorliegt.<br />

Unit<br />

Unit<br />

...<br />

x 1<br />

x s<br />

Kernel: Überprüfung der Units<br />

Im schlechtesten Fall wird nur eine Unit<br />

angepasst, im günstigsten Fall allerdings r<br />

Unit 1 ... Unit k<br />

Units auf einmal.<br />

Abbildung 3.3: Kernelaufrufe einer Iterationsreihe,<br />

Bitte beachten Sie, dass das in Kapitel 3.2 beschriebene<br />

dekrementieren der “Restlebens-<br />

Hard Clustering<br />

dauer” aller Units durch die geänderte Distanzberechnung nicht mehr im Distanzkernel<br />

18 Universität Bielefeld, AG Technische Informatik


3 <strong>Implementation</strong><br />

geschehen kann, weshalb für diese Aufgabe ein zusätzlicher Kernel “Altersupdate der<br />

Units” hinzugefügt wurde.<br />

3.5.1 Adaptive Anpassung der parallelen Trainingsvektoren<br />

Der in Kapitel 3.5 beschriebene Ansatz funktioniert bei passend gewählter Anzahl<br />

r an parallel zu verarbeitenden Trainingsvektoren sehr gut und liefert einen hohen<br />

zusätzlichen Speedup. Leider ist dieser Parameter nicht intuitiv zu wählen und hängt<br />

stark vom verwendeten Datensatz und der Anzahl an Prototypen ab. Zu kleine Werte<br />

<strong>von</strong> r lasten die <strong>GPU</strong> nicht vollständig aus und verschenken so einen möglichen<br />

Performancegewinn. Wählt man den Parameter zu hoch, werden Distanzen zu sehr<br />

vielen Datenpunkten berechnet, <strong>von</strong> denen allerdings nur ein geringer Teil tatsächlich<br />

verwendet wird. Die Folge ist ein schlechter Speedup.<br />

Lösung für dieses Problem ist eine adaptive Anpassung der Anzahl an parallelen Trainingsvektoren.<br />

Zu Beginn des Lernprozesses ist der Parameter hoch gewählt, wird aber<br />

in einem einstellbaren Intervall (siehe Anhang E) durch den beobachteten (aufgerundeten)<br />

Mittelwert der tatsächlich adaptierten Units ersetzt.<br />

Universität Bielefeld, AG Technische Informatik 19


4<br />

Experimentelle Ergebnisse<br />

In diesem Kapitel wird die erzielte Geschwindigkeit anhand <strong>von</strong> zwei ausgewählten<br />

Datensätzen mit der Referenz-CPU-Implementierung verglichen. Betrachtet wird dabei<br />

der Speedup S = tcpu<br />

t gpu<br />

, also die durch die <strong>GPU</strong>-Implementierung erzielte Beschleunigung<br />

des Lernprozesses.<br />

Zunächst wird in Kapitel 4.1 kurz auf die verwendete Hardware eingegangen, während<br />

anschließend in Kapitel 4.2 und 4.3 die analysierten Datensätze erläutert werden. Der<br />

Einfluss einzelner Parameter auf den Speedup wird in Kapitel 4.4 betrachtet. Eine Übersicht<br />

über die Laufzeiten der einzelnen Kernel liefert Kapitel 4.5.<br />

4.1 Hardware<br />

Sämtliche Analysen wurden auf baugleichen Rechnern 1 durchgeführt, einzig die Laufzeiten<br />

der AMD Karten sind auf einem etwas langsameren System 2 gemessen worden.<br />

Die Leistungsdaten der verwendeten Grafikkarten können Sie Tabelle 4.1 entnehmen,<br />

wobei die theoretische Maximalleistung durch<br />

P max = Prozessortakt · #Shader · Operationen<br />

Takt<br />

(4.1)<br />

berechnen wurde. Von besonderem Interesse ist hier die 64 Bit Performance, da NGPCA<br />

in doppelter Genauigkeit trainiert wird (siehe Kapitel 3). Dabei ergibt sich die 64 Bit<br />

Performance bei Nvidia Consumer Karten als 1/8 der 32 Bit Performance bzw. bei<br />

AMD als 1/4.<br />

1 Intel(R) Core(TM) i7-2600 CPU, 8 GB RAM<br />

2 Intel(R) Core(TM) i7-930 CPU, 6 GB RAM<br />

20 Universität Bielefeld, AG Technische Informatik


4 Experimentelle Ergebnisse<br />

Bezeichnung Takt #Shader P max (32 Bit) P max (64 Bit)<br />

Nvidia GTX 560 Ti 1,645 GHz 384 1263 GFLOPs 158 GFLOPs<br />

Nvidia GTX 570 1,4 GHz 480 1344 GFLOPs 168 GFLOPs<br />

AMD Radeon HD 6970 3 0,94 GHz 1536 2888 GFLOPs 722 GFLOPs<br />

AMD Radeon HD 7970 4 1,05 GHz 2048 4301 GFLOPs 1075 GFLOPs<br />

Tabelle 4.1: Theoretische Leistungsdaten der verwendeten Grafikkarten (Operationen/Takt = 2 bei FMA)<br />

4.2 Roboterarmsteuerung<br />

Bei diesem 68-dimensionalen Datensatz aus N = 3213 Datenpunkten soll die<br />

Steuerung eines Roboterarmes gelernt werden. Dabei soll der Roboterarm ein kleines<br />

Klötzchen greifen. Eine detaillierte Beschreibung des Szenarios finden Sie in Schenck<br />

(2008) und Hoffmann et al. (2005).<br />

Abbildung 4.1 zeigt den erreichten Speedup in Abhängigkeit <strong>von</strong> der verwendeten Grafikkarte.<br />

Dabei wurde jeweils die Threadanzahl mit dem besten Speedup gewählt (siehe<br />

Anhang A.1). Interessant ist hierbei die schlechte Performance der AMD Karten und<br />

der deutlich höhere Speedup beim Soft Clustering.<br />

12<br />

10<br />

Nvidia GTX 560 Ti<br />

Nvidia GTX 570<br />

AMD Radeon HD 6970<br />

AMD Radeon HD 7970<br />

6<br />

5<br />

Nvidia GTX 560 Ti<br />

Nvidia GTX 570<br />

AMD Radeon HD 6970<br />

AMD Radeon HD 7970<br />

8<br />

4<br />

speedup<br />

6<br />

speedup<br />

3<br />

4<br />

2<br />

2<br />

1<br />

0<br />

0 20 40 60 80 100 120 140 160 180 200<br />

clusters<br />

(a) Soft Clustering<br />

0<br />

0 20 40 60 80 100 120 140 160 180 200<br />

clusters<br />

(b) Hard Clustering<br />

Abbildung 4.1: Speedup der Grafikkarten nach Anzahl der Prototypen [4 Eigenwerte, 20.000 Iterationen, optimale<br />

Threadanzahl]<br />

Für die Evaluation der Lernqualität (Tabelle 4.2) wurde der in Schenck (2008) beschriebene<br />

Greiffehler betrachtet. Dabei ist erkennbar, dass die <strong>GPU</strong> <strong>Implementation</strong> bei diesem<br />

Datensatz qualitativ gleichwertig mit der CPU-Referenzimplementierung ist.<br />

CPU <strong>GPU</strong> (VConst) <strong>GPU</strong> (TracePot.)<br />

Avg. Error 0,871 0,862 0,872<br />

Std. Dev 0,030 0,036 0,041<br />

Tabelle 4.2: Greiffehler [4 Eigenwerte, 100 Prototypen, 20.000 Iterationen, Hard Clustering]<br />

3 http://www.msi.com/product/vga/R6970-Lightning.html<br />

Datum: 18.09.2012<br />

4 http://www.hisdigital.com/de/product2-692.shtml<br />

Datum: 18.09.2012<br />

Universität Bielefeld, AG Technische Informatik 21


4 Experimentelle Ergebnisse<br />

4.3 CT Slices<br />

Dieser 385-dimensionale Datensatz mit N = 53500 Datenpunkten enthält Merkmale<br />

aus Computertomographie-Schnittbildaufnahmen 5 . Der Merkmalsvektor wird dabei aus<br />

zwei Histogrammen gebildet, die die Knochenstruktur und die Lufteinschlüsse jeder<br />

Aufnahme beschreiben. Ziel dabei ist, die relative Position der Schnittbilder zu erlernen.<br />

In Abbildung 4.2 wird der erreichte Speedup bei optimaler Threadanzahl (siehe Anhang<br />

A.2) in Abhängigkeit <strong>von</strong> der verwendeten Grafikkarte gezeigt. Dabei ist die relative hohe<br />

Soft Clustering Performance der Radeon HD 7970 und der allgemein höhere Speedup<br />

beim Hard Clustering besonders bemerkenswert.<br />

4.5<br />

6<br />

4<br />

5<br />

3.5<br />

4<br />

speedup<br />

3<br />

2.5<br />

2<br />

1.5<br />

Nvidia GTX 560 Ti<br />

Nvidia GTX 570<br />

Radeon HD 6970<br />

Radeon HD 7970<br />

speedup<br />

3<br />

2<br />

1<br />

Nvidia GTX 560 Ti<br />

Nvidia GTX 570<br />

Radeon HD 6970<br />

Radeon HD 7970<br />

1<br />

50 100 150 200 250 300<br />

clusters<br />

(a) Soft Clustering<br />

0<br />

50 100 150 200 250 300<br />

clusters<br />

(b) Hard Clustering<br />

Abbildung 4.2: Speedup der Grafikkarten nach Anzahl der Prototypen [20 Eigenwerte, 20.000 Iterationen, optimale<br />

Threadanzahl]<br />

Die Lernqualität wurde mit dem normalized Mean Square Error (Normalized MSE)<br />

beurteilt, der über alle Datenpunkte berechnet wurde (Tabelle 4.3). Hierbei ist eine<br />

deutliche Qualitätverbesserung durch die <strong>GPU</strong>-Implementierung gegenüber der CPU-<br />

Referenzimplementierung sichtbar. Des Weiteren verbessert das vermeintlich schlechtere<br />

Potential das Ergebnis.<br />

CPU <strong>GPU</strong> (VConst) <strong>GPU</strong> (TracePot.)<br />

Avg. Error 4,663 1,306 0,899<br />

Std. Dev 1,478 0,315 0,301<br />

Tabelle 4.3: Normalized MSE [20 Eigenwerte, 200 Prototypen, 200.000 Iterationen, Hard Clustering]<br />

5 http://archive.ics.uci.edu/ml/datasets/Relative+location+of+CT+<br />

slices+on+axial+axis<br />

Datum: 18.09.2012<br />

22 Universität Bielefeld, AG Technische Informatik


4 Experimentelle Ergebnisse<br />

4.4 Speedup nach gewählten Parametern<br />

In diesem Kapitel wird der Einfluss einzelner Trainingsparameter auf den Speedup untersucht.<br />

Da sich die Architektur der verwendeten Nvidia Karten untereinander bzw.<br />

der AMD Karten untereinander nur gering unterscheidet, werden im Folgenden nur die<br />

Nvidia GTX 570 und die AMD Radeon HD 7970 betrachtet.<br />

4.4.1 Anzahl der Prototypen<br />

Abbildung 4.3 und 4.4 zeigen die Abhängigkeit des Speedup <strong>von</strong> der Anzahl der verwendeten<br />

Prototypen. Eine höhere Anzahl bewirkt einen größeren Speedup, wobei die<br />

Steigung mit steigender Anzahl an Unit’s abnimmt. Insbesondere das Hard Clustering<br />

profitiert <strong>von</strong> vielen Prototypen.<br />

11<br />

10<br />

9<br />

8<br />

32 threads<br />

64 threads<br />

128 threads<br />

256 threads<br />

512 threads<br />

5.5<br />

5<br />

4.5<br />

4<br />

7<br />

3.5<br />

speedup<br />

6<br />

speedup<br />

3<br />

5<br />

4<br />

3<br />

2.5<br />

2<br />

1.5<br />

32 threads<br />

64 threads<br />

128 threads<br />

256 threads<br />

512 threads<br />

2<br />

1<br />

1<br />

0 20 40 60 80 100 120 140 160 180 200<br />

clusters<br />

(a) Soft Clustering, Nvidia GTX 570<br />

0.5<br />

0 20 40 60 80 100 120 140 160 180 200<br />

clusters<br />

(b) Hard Clustering, Nvidia GTX 570<br />

Abbildung 4.3: Speedup nach Prototypen und Threads [Arm Datensatz, 4 Eigenwerte, 20.000 Iterationen]<br />

speedup<br />

4.5<br />

4<br />

3.5<br />

3<br />

2.5<br />

speedup<br />

5<br />

4.5<br />

4<br />

3.5<br />

3<br />

2.5<br />

2<br />

32 threads<br />

64 threads<br />

128 threads<br />

256 threads<br />

512 threads<br />

2<br />

1.5<br />

32 threads<br />

64 threads<br />

128 threads<br />

256 threads<br />

512 threads<br />

1.5<br />

1<br />

0.5<br />

1<br />

50 100 150 200 250 300<br />

clusters<br />

(a) Soft Clustering, Radeon HD 7970<br />

0<br />

50 100 150 200 250 300<br />

clusters<br />

(b) Hard Clustering, Radeon HD 7970<br />

Abbildung 4.4: Speedup nach Prototypen und Threads [CT Datensatz, 20 Eigenwerte, 20.000 Iterationen]<br />

Universität Bielefeld, AG Technische Informatik 23


4 Experimentelle Ergebnisse<br />

4.4.2 Anzahl der Eigenwerte<br />

Der Zusammenhang zwischen Speedup und der verwendeten Anzahl an Eigenwerten<br />

wird in Abbildung 4.5 gezeigt. Für diese Evaluation wurde der CT Datensatz ausgewählt,<br />

da die Qualität der Lernergebnisse relativ unempfindlich auf die gewählte<br />

Eigenwertanzahl ist.<br />

Beim Soft Clustering fällt der Speedup mit steigender Eigenwertanzahl auf einen Grenzwert<br />

ab, wobei dieser bei der AMD Radeon HD 7970 höher ausfällt und die Änderung<br />

geringer ist. Für Hard Clustering ist die Nvidia GTX 570 jedoch besser geeignet, da<br />

der Speedup hier deutlich höher ausfällt und ab einer gewissen Eigenwertanzahl auch<br />

wieder leicht ansteigt.<br />

speedup<br />

10<br />

9<br />

8<br />

7<br />

6<br />

5<br />

4<br />

32 threads<br />

64 threads<br />

128 threads<br />

256 threads<br />

512 threads<br />

speedup<br />

7<br />

6<br />

5<br />

4<br />

3<br />

32 threads<br />

64 threads<br />

128 threads<br />

256 threads<br />

512 threads<br />

3<br />

2<br />

2<br />

1<br />

0 5 10 15 20 25 30<br />

eigenvalues<br />

(a) Soft Clustering, Nvidia GTX 570<br />

1<br />

0 5 10 15 20 25 30<br />

eigenvalues<br />

(b) Soft Clustering, Radeon HD 7970<br />

7<br />

6<br />

5<br />

4<br />

3.5<br />

3<br />

32 threads<br />

64 threads<br />

128 threads<br />

256 threads<br />

512 threads<br />

speedup<br />

4<br />

speedup<br />

2.5<br />

3<br />

2<br />

32 threads<br />

64 threads<br />

128 threads<br />

256 threads<br />

512 threads<br />

2<br />

1.5<br />

1<br />

0 5 10 15 20 25 30<br />

eigenvalues<br />

(c) Hard Clustering, Nvidia GTX 570<br />

1<br />

0 5 10 15 20 25 30<br />

eigenvalues<br />

(d) Hard Clustering, Radeon HD 7970<br />

Abbildung 4.5: Speedup nach Eigenwerten und Threads [CT Datensatz, 20 Eigenwerte, 200 Prototypen, 20.000 Iterationen]<br />

24 Universität Bielefeld, AG Technische Informatik


4 Experimentelle Ergebnisse<br />

4.4.3 Verwendetes Potential<br />

Diese Auswertung untersucht die durch das angepasste Potential (siehe Kapitel 3.2.1)<br />

verursachte Beschleunigung. Hierbei wurde der CT Datensatz ausgewählt, obwohl<br />

bei dem Arm Datensatz deutlich höhere Beschleunigungen <strong>von</strong> etwa 27 % gemessen<br />

wurden. Auf eine Darstellung des Speedups in Abhängigkeit <strong>von</strong> der Eigenwertanzahl<br />

wurde für den Arm Datensatz aufgrund der in Kapitel 4.4.2 genannten Sensitivität<br />

allerdings verzichtet.<br />

Das Soft Clustering wird durch das angepasste Potential nicht nennenswert beschleunigt<br />

(deutlich unter 1 %). Beim Hard Clustering wird jedoch ein zusätzlicher Speedup <strong>von</strong><br />

etwa 5 % erreicht, wobei die Nvidia Karten ein wesentlich stabileres Verhalten zeigen.<br />

1.014<br />

1.5<br />

1.012<br />

1.01<br />

1.008<br />

Nvidia GTX 560 Ti<br />

Nvidia GTX 570<br />

Radeon HD 6970<br />

Radeon HD 7970<br />

1.4<br />

1.3<br />

Nvidia GTX 560 Ti<br />

Nvidia GTX 570<br />

Radeon HD 6970<br />

Radeon HD 7970<br />

speedup<br />

1.006<br />

1.004<br />

1.002<br />

speedup<br />

1.2<br />

1.1<br />

1<br />

1<br />

0.998<br />

0.996<br />

0.9<br />

0.994<br />

0 5 10 15 20 25 30<br />

eigenvalues<br />

(a) Soft Clustering<br />

0.8<br />

0 5 10 15 20 25 30<br />

eigenvalues<br />

(b) Hard Clustering<br />

Abbildung 4.6: Speedup nach Eigenwerten [CT Datensatz, 200 Prototypen, 20.000 Iterationen, 512 Threads]<br />

4.5 Kernellaufzeiten<br />

In diesem Kapitel wird der Laufzeitanteil der verwendeten Kernel an der Gesamtlaufzeit<br />

betrachtet.<br />

Beide Plattformen weisen auf dem Arm Datensatz (Tabelle 4.4) deutliche Unterschiede<br />

auf, während sich die Laufzeitcharakteristik bei dem aufwändigeren CT Datensatz (Tabelle<br />

4.5) annähert. Beim Hard Clustering des CT Datensatzes (Tabelle 4.5) trägt die Distanzberechnung<br />

und die Adaption etwa gleichwertig zur Gesamtlaufzeit bei, die Laufzeit<br />

des Soft Clusterings wird jedoch fast ausschließlich <strong>von</strong> der Adaption bestimmt.<br />

Auffällig ist auch, dass eigentlich sehr einfache Kernel wie die Unit Reset Heuristik<br />

und das Ranking auf der AMD Plattform deutlich stärker ins Gewicht fallen.<br />

Universität Bielefeld, AG Technische Informatik 25


4 Experimentelle Ergebnisse<br />

Kernel<br />

Laufzeitanteil<br />

Nvidia GTX 570 AMD Radeon HD 7970<br />

Hard Cl. Soft Cl. Hard Cl. Soft Cl.<br />

Distanzberechnung 43,5 % 4,3 % 25,6 % 17,5 %<br />

Unit Reset 15,9 % 0,8 % 14,8 % 1,9 %<br />

Ranking + Parameterbestimmung 6,7 % 2,6 % 26,4 % 30,5 %<br />

Unit Altersupdate 2,2 % 1,4 %<br />

Adaption 31,7 % 92,2 % 31,8 % 50,0 %<br />

Tabelle 4.4: Kernellaufzeiten [Arm Datensatz, 4 Eigenwerte, 100 Prototypen, 20.000 Iterationen, 512 Threads]<br />

Kernel<br />

Laufzeitanteil<br />

Nvidia GTX 570 AMD Radeon HD 7970<br />

Hard Cl. Soft Cl. Hard Cl. Soft Cl.<br />

Distanzberechnung 48,9 % 2,8 % 34,0 % 1,4 %<br />

Unit Reset 1,2 % 0,0 % 4,1 % 0,2 %<br />

Ranking + Parameterbestimmung 1,7 % 0,2 % 7,2 % 1,4 %<br />

Unit Altersupdate 0,3 % 0,2 %<br />

Adaption 47,9 % 97,0 % 54,5 % 97,0 %<br />

Tabelle 4.5: Kernellaufzeiten [CT Datensatz, 20 Eigenwerte, 200 Prototypen, 20.000 Iterationen, 512 Threads]<br />

Besonders interessant ist, dass die Laufzeit des Soft Clusterings beim CT Datensatz fast<br />

ausschließlich <strong>von</strong> der Adaption bestimmt wird. Die Vermutung liegt nahe, dass dieses<br />

Verhalten durch die höhere Eigenwertanzahl verursacht wird, da der Aufwand für die<br />

Orthonormalisierung quadratisch mit der Anzahl der Eigenwerte steigt (Möller, 2006).<br />

Aus diesem Grund wird in Abbildung 4.7 der Anteil der Orthonormalisierung an der<br />

Gesamtlaufzeit bei variierender Eigenwertanzahl untersucht.<br />

0.9<br />

0.45<br />

0.85<br />

0.4<br />

0.8<br />

0.35<br />

orthonormalization part<br />

0.75<br />

0.7<br />

0.65<br />

0.6<br />

orthonormalization part<br />

0.3<br />

0.25<br />

0.2<br />

0.15<br />

0.55<br />

0.5<br />

Nvidia GTX 570<br />

Radeon HD 7970<br />

0.1<br />

0.05<br />

Nvidia GTX 570<br />

Radeon HD 7970<br />

0.45<br />

0 5 10 15 20 25 30<br />

eigenvalues<br />

(a) Soft Clustering<br />

0<br />

0 5 10 15 20 25 30<br />

eigenvalues<br />

(b) Hard Clustering<br />

Abbildung 4.7: Anteil der Orthonormalisierung an der Gesamtlaufzeit [CT Datensatz, 200 Prototypen, 20.000 Iterationen,<br />

512 Threads]<br />

26 Universität Bielefeld, AG Technische Informatik


5<br />

Diskussion<br />

5.1 Pre-Tests<br />

Vor der eigentlichen Implementierung wurden einige Tests durchgeführt, die die Vorund<br />

Nachteile verschiedener Verfahren evaluiert haben. In diesem Kapitel werden die<br />

Verfahren erwähnt, die aufgrund ihrer Nachteile nicht implementiert wurden.<br />

5.1.1 PCA-Verfahren<br />

Das verwendete PCA-Verfahren RRLSA (Kapitel 2.5.1) liefert nicht mehr paarweise<br />

orthonormale Vektoren, weshalb eine regelmäßige Orthonormalisierung nötig ist.<br />

Coupled PCA (Möller und Konies, 2004) ist zwar etwas aufwändiger als RRLSA, soll<br />

allerdings die Orthonormalität der Hauptachsen größtenteils beibehalten. Dies würde<br />

den zeitaufwändigen Gram-Schmidt Algorithmus überflüssig machen. Leider hat sich<br />

dies nicht hinreichend bestätigt, so dass auch mit Coupled PCA in einem gewissen<br />

Intervall orthonormalisiert werden muss.<br />

Insgesamt gesehen ist RRLSA schneller als Coupled PCA, da auch Coupled PCA nur<br />

bei Orthonormalisierung nach jeder Iteration eine zu RRLSA vergleichbare Trainingsqualität<br />

liefert.<br />

5.1.2 Orthonormalisierungsverfahren<br />

Von Hyvärinen et al. (2001) wird ein iteratives symmetrisches Orthonormalisierungsverfahren<br />

beschrieben, welches sich <strong>von</strong> der Struktur her gut für <strong>GPU</strong>s eignet (wobei<br />

W die zu orthonormalisierende Matrix ist):<br />

W (1) = W (0)/‖W (0)‖ (5.1)<br />

W (t + 1) = 3 2 W (t) − 1 2 W (t)W (t)T W (t) (5.2)<br />

Dabei konvergiert W gegen die orthonormalisierte Matrix.<br />

Universität Bielefeld, AG Technische Informatik 27


5 Diskussion<br />

Der Test auf Konvergenz war allerdings zu aufwändig, weshalb mit einer festen Iterationszahl<br />

gearbeitet werden musste. Leider war dieses Verfahren nur bei geringer Iterationszahl<br />

schneller als die in Kapitel 3.4.2 beschriebene angepasste Gram-Schmidt<br />

Orthonormalisierung. Bei einer so geringen Iterationszahl war die Qualität der Orthonormalisierung<br />

allerdings nicht zufriedenstellend.<br />

5.1.3 <strong>Implementation</strong> einer OpenCL Matrix-Bibliothek<br />

NGPCA lässt sich mit Hilfe <strong>von</strong> Matrixoperationen sehr elegant programmieren. Daher<br />

wurde zunächst der Ansatz verfolgt, eine kleine Matrix-Bibliothek für OpenCL zu<br />

schreiben. Mit dieser sollte dann der NGPCA-Algorithmus implementiert werden.<br />

Zudem könnte die OpenCL-Bibliothek für weitere Projekte genutzt werden.<br />

Dieser Ansatz funktionierte gut und ermöglichte besonders leserlichen Code. Zudem<br />

konnte man bestehende Matlab-Algorithmen 1:1 auf der <strong>GPU</strong> implementieren. Leider<br />

müssen durch diese Herangehensweise viele Zwischenergebnisse gespeichert werden,<br />

welche zu groß für den lokalen Speicher sind und deshalb im globalen Speicher der<br />

Grafikkarte abgelegt werden müssen. Dies führt zu extrem vielen Speicherzugriffen<br />

und damit zu einer schlechten Gesamtperformance.<br />

Durch das explizite Implementieren der verwendeten Algorithmen konnten die Speicherzugriffe<br />

deutlich verringert und in den Matrix-Funktionen verwendete Schleifen<br />

zusammengefasst werden.<br />

5.2 Beurteilung der Ergebnisse<br />

Sowohl beim Hard- als auch bei Soft Clustering konnte ein erheblicher Geschwindigkeitszuwachs<br />

(Abbildung 4.1 und 4.2) gegenüber der CPU-Referenzimplementierung<br />

erreicht werden. Zusätzlich wird bei hochdimensionalen Datensätzen die Lernqualität<br />

signifikant verbessert (Tabelle 4.3). Dies liegt vermutlich an den verwendeten Reduktionen,<br />

die durch viele Zwischenergebnisse die numerische Stabilität verbessern.<br />

Während der Parallelitätsgrad beim Soft Clustering durch die gleichzeitige Berechnung<br />

der Prototypen hoch genug war, musste das Hard Clustering wie in Kapitel 3.5<br />

beschrieben angepasst werden. Hierdurch konnte auch beim Hard Clustering eine hohe<br />

<strong>GPU</strong>-Auslastung und ein damit verbundener signifikanter Speedup erreicht werden.<br />

Die Trainingsqualität wurde durch dieses Verfahren nicht negativ beeinflusst (Tabelle<br />

4.2 und 4.3).<br />

Es hat sich jedoch herausgestellt, dass sich der NGPCA-Algorithmus nicht so optimal<br />

wie ursprünglich gedacht für eine <strong>GPU</strong>-Implementierung eignet. Dies liegt vor allem an<br />

der nötigen doppelten Rechengenauigkeit, wodurch bei Nvidia Karten nur 1/8 der 32<br />

Bit Rechenleistung zur Verfügung steht (bei AMD Karten 1/4). In Hardware implementierte<br />

Funktionen, z.B. für das Wurzelziehen, stehen bei 64 Bit Berechnungen ebenfalls<br />

nicht zur Verfügung. Dies konnte jedoch durch ein angepasstes Potential (siehe Kapitel<br />

3.2.1 und 5.2.1) entschärft werden, welches auf langsame Wurzeloperationen verzichtet.<br />

Des Weiteren musste zur Synchronisation zwischen den Work-Groups jede Iteration in<br />

mehrere Kernel unterteilt werden, was hohe Ansprüche an die effiziente Gestaltung der<br />

28 Universität Bielefeld, AG Technische Informatik


5 Diskussion<br />

Kernelstarts in den entsprechenden Treibern stellt (siehe Kapitel 5.2.2).<br />

Der durch die <strong>GPU</strong>-Implementierung erzielte Speedup hängt jedoch teilweise stark <strong>von</strong><br />

den gewählten NGPCA-Parametern (Kapitel 5.2.1) und der verwendeten Hardware (Kapitel<br />

5.2.2) ab.<br />

5.2.1 Einfluss der gewählten Parameter<br />

In diesem Kapitel wird der Einfluss einzelner Parameter auf den Speedup diskutiert.<br />

Insbesondere wird auf die Anzahl der Prototypen, die Anzahl der Eigenwerte und das<br />

verwendete Potential eingegangen.<br />

Anzahl der Prototypen<br />

Latency Hiding (Fatahalian und Houston, 2008) ist ein Grundkonzept <strong>von</strong> <strong>GPU</strong>s,<br />

wobei mehr Threads zur Ausführung vorgehalten werden als Hardwareressourcen<br />

zur Verfügung stehen. Sind nun einzelne Gruppen <strong>von</strong> Threads durch ausstehende<br />

Speicheranforderungen nicht ausführbar, können andere Threads bearbeitet werden.<br />

Die Grundidee der <strong>Implementation</strong> ist es, alle verwendeten Prototypen parallel auf<br />

der Grafikkarte zu berechnen. Jede Work-Group besteht dabei aus einer vordefinierten<br />

Anzahl an Threads (siehe Anhang E). Die Anzahl der <strong>von</strong> der Grafikkarte zu verarbeitenden<br />

Threads steigt somit mit der Anzahl der Units. Damit funktioniert das o.g.<br />

Latency Hiding besser, was sich positiv auf die Auslastung der Grafikkarte auswirkt.<br />

Resultat ist ein höherer Speedup.<br />

In Abbildung 4.3 und 4.4 ist eine Verbesserung des Speedup bei steigender Anzahl<br />

an Protoypen deutlich erkennbar. Die Steigung des Speedup nimmt jedoch mit zunehmenden<br />

Units ab. Ab einer gewissen Prototypanzahl bringen weitere Units bei der<br />

Betrachtung des Speedup also keinen Mehrwert, da die Grafikkarte bereits vollständig<br />

ausgelastet ist.<br />

Bei hochdimensionalen Datensätzen und Soft Clustering wird jedoch bereits bei<br />

wenigen Prototypen ein Speedup nahe des Maximums erreicht. Dies liegt an den<br />

aufwändigeren Berechnungen für hochdimensionale Vektoren, so dass die maximale<br />

Auslastung der <strong>GPU</strong> schneller erreicht wird.<br />

Generell profitiert das Hard Clustering stärker <strong>von</strong> einer höheren Prototypanzahl, was<br />

sich aufgrund des in Kapitel 3.5 beschriebenen Verfahrens erklären lässt. Während beim<br />

Soft Clustering alle Units parallel angepasst werden, werden beim Hard Clustering gerade<br />

so viele Units parallel adaptiert, dass keine Überschneidungen entstehen. Mehr<br />

Prototypen senken die Wahrscheinlichkeit, dass eine Unit doppelt angepasst werden<br />

würde, was wiederrum den Parallelitätsgrad und damit auch den Speedup erhöht.<br />

Anzahl der Eigenwerte<br />

Die Anzahl der verwendeten Eigenwerte hat ebenfalls Einfluss auf den resultierenden<br />

Speedup, allerdings besteht dieser Zusammenhang nur indirekt.<br />

Universität Bielefeld, AG Technische Informatik 29


5 Diskussion<br />

Wie in Abbildung 4.5 ersichtlich ist, fällt der Speedup beim Soft Clustering zunächst<br />

mit steigender Eigenwertanzahl ab. Nach Erreichen eines Schwellwertes bleibt er<br />

jedoch nahezu konstant. In Tabelle 4.5 ist erkennbar, dass die Laufzeit und damit<br />

auch der Speedup beim Soft Clustering mit hoher Eigenwertanzahl nur durch die<br />

Adaption bestimmt wird. Da der Aufwand für die Orthonormalisierung quadratisch<br />

mit der Anzahl der Eigenwerte steigt (Möller, 2006), steigt auch der Anteil der<br />

Orthonormalisierung an der Adaption. Folglich erhöht sich der Laufzeitanteil der<br />

Orthonormalisierung bei steigender Eigenwertanzahl, was deutlich in Abbildung 4.7a<br />

ersichtlich ist. Die Steigung des Laufzeitanteils fällt jedoch ab, was den Grenzwert in<br />

Abbildung 4.5a und 4.5b erklärt.<br />

Hieraus lässt sich schließen, dass die einzelnen Abschnitte der <strong>Implementation</strong> stark<br />

unterschiedliche Beschleunigungen des NGPCA-Algorithmus verursachen. Die nach<br />

Kapitel 3.4.2 implementierte Gram-Schmidt Orthonormalisierung hat im Vergleich<br />

zu den anderen <strong>Implementation</strong>sabschnitten einen deutlich niedrigeren Speedup, was<br />

vermutlich mit den häufigen Lese- und Schreibzugriffen auf den globalen Speicher<br />

zusammenhängt. Durch Erhöhung der Eigenwerte konvergiert der Speedup der <strong>Implementation</strong><br />

gegen den Speedup der Orthonormalisierung.<br />

Im Gegensatz zum Soft Clustering wird beim Hard Clustering pro Trainingsvektor nur<br />

eine Adaption (und somit Orthonormalisierung) durchgeführt. Hierdurch verringert sich<br />

der Speedup bei steigender Eigenwertanzahl nur gering (Nvidia GTX 570, Abb. 4.5c)<br />

bzw. steigt sogar (Radeon HD 7970, Abb. 4.5d).<br />

Verwendetes Potential<br />

Während das verwendete Potential bei der Berechnung auf der CPU nahezu keinen<br />

Einfluss auf die Laufzeit hat, konnte durch die Verwendung des in Kapitel 3.2.1<br />

beschriebenen Potentials ein teilweise deutlicher zusätzlicher Speedup erreicht werden.<br />

Dies liegt an der Architektur <strong>von</strong> <strong>GPU</strong>s, bei der Wurzeloperationen besonders “teuer”<br />

sind und den Speedup somit verschlechtern. Insbesondere trifft dies auf 64 Bit Wurzeloperationen<br />

zu, die nicht in Hardware implementiert sind und daher nochmals deutlich<br />

zeitaufwändiger sind.<br />

Eine Beschleunigung der Potentialberechnung hat natürlich nur Auswirkungen auf<br />

die Distanzberechnung. Da die Laufzeit des Soft Clusterings größtenteils <strong>von</strong> der<br />

Adaption bestimmt wird (Tabelle 4.5), erzielt das angepasste Potential hier nur eine<br />

nicht nennenswerte Beschleunigung <strong>von</strong> unter 1 % (Abb. 4.6).<br />

Beim Hard Clustering geht die Distanzberechnung mehr in die Gesamtlaufzeit ein, weshalb<br />

hier ein höherer zusätzlicher Speedup erreicht wird. Auf dem in Abbildung 4.6 benutzten<br />

CT Datensatz liegt dieser bei etwa 5 %. Bei niedrigdimensionalen Datensätzen<br />

mit geringer Eigenwertanzahl sind jedoch deutlich höhere Beschleunigungen möglich,<br />

da hier die Potentialberechnung einen höheren Laufzeitanteil an der Gesamtberechnung<br />

besitzt. Auf dem Arm Datensatz konnte ein zusätzlicher Speedup <strong>von</strong> 27 % gemessen<br />

werden.<br />

30 Universität Bielefeld, AG Technische Informatik


5 Diskussion<br />

Anzahl der Threads<br />

Die Anzahl der Threads pro Work-Group steuert den Parallelitätsgrad und hat starke<br />

Auswirkungen auf die Geschwindigkeit der <strong>GPU</strong>-Implementierung. Bei niedrigdimensionalen<br />

Datensätzen und verwendetem Soft Clustering sollte die Anzahl der verwendeten<br />

Threads nicht deutlich über der Dimension der Trainingsdaten liegen (Abb. 4.3).<br />

Ansonsten empfiehlt sich aber die Wahl einer eher hohen Threadanzahl (Abb. 4.3 und<br />

4.4).<br />

5.2.2 Wahl der Plattform<br />

Die in Kapitel 4 gezeigten experimentellen Ergebnisse zeigen ein recht unterschiedliches<br />

Laufzeitverhalten der zwei verwendeten Plattformen, während sich die<br />

Grafikkarten derselben Plattform häufig nur durch einen bestimmten konstanten Faktor<br />

im Speedup unterscheiden.<br />

Dies führt zu der Frage, welche Plattform sich für die <strong>GPU</strong>-Implementierung des<br />

NGPCA-Algorithmus am besten eignet. Eine pauschale Antwort lässt sich nicht geben,<br />

da beide Plattformen ihre Vor- und Nachteile haben. Die theoretischen Leistungsdaten<br />

(Tabelle 4.1) bescheinigen den AMD Karten einen deutlichen Vorteil bei der Berechnung<br />

<strong>von</strong> 64 Bit Fließkommazahlen, die Radeon HD 7970 hat sogar mehr als die<br />

6-fache Leistung der Nvidia GTX 570. Dennoch erzielen beide Nvidia Karten auf dem<br />

niedrigdimensionalen Arm Datensatz deutlich bessere Resultate (Abb. 4.1).<br />

Die Laufzeit der einzelnen Kernel ist auf dem Arm Datensatz aufgrund der niedrigdimensionalen<br />

Vektoren sehr gering. Folglich ist eine effiziente Verarbeitung der großen<br />

Menge an Kernelstarts besonders wichtig. Diese Aufgabe erfüllt die Nvidia Plattform<br />

scheinbar besser. Des Weiteren sind Kontrollstrukturen und Divergenz (Nischwitz<br />

et al., 2012) besonders für die AMD Plattform problematisch. Dies wird durch den im<br />

Vergleich zu Nvidia Karten sehr hohen Laufzeitanteil des Ranking-Kernels deutlich<br />

(Tabelle 4.4), der eine hohe Divergenz und relativ viele Kontrollstrukturen aufweist. Eine<br />

weitere mögliche Erklärung für das schlechte Laufzeitverhalten der AMD Plattform<br />

ist eine schlechtere Quellcode-Optimierung, denn gerade bei dem niedrigdimensionalen<br />

Datensatz lässt sich der Code durch z.B. Loop Unrolling stark optimieren.<br />

Bei aufwändigeren Berechnungen, z.B. beim Soft Clustering des CT Datensatzes mit<br />

vielen Eigenwerten (Abb. 4.2a), kann die Radeon HD 7970 ihre hohe 64 Bit Leistung<br />

nutzen. Hier ist sie der Nvidia GTX 570 deutlich überlegen. Sobald die Komplexität<br />

der Berechnung allerdings gesenkt wird, z.B. durch Verwendung <strong>von</strong> Hard Clustering<br />

(Abb. 4.2b), erreicht die Nvidia GTX 570 wieder den besten Speedup.<br />

Betrachtet man diese Ergebnisse, so ist die AMD Plattform besonders für rechenintensive<br />

Anwendungen mit wenigen Kontrollstrukturen und geringer Divergenz geeignet.<br />

Die Nvidia Architektur ist universell verwendbar, allerdings erreichen die Nvidia Karten<br />

eine deutlich geringere 64 Bit Leistung.<br />

Universität Bielefeld, AG Technische Informatik 31


6<br />

Ausblick<br />

Die im Rahmen dieser Bachelorarbeit entwickelte <strong>GPU</strong>-Implementierung konnte einen<br />

deutlichen Geschwindigkeitszuwachs gegenüber der CPU-Referenzimplementierung<br />

erreichen. Dennoch ergeben sich einige Verbesserungsmöglichkeiten, die in diesem Kapitel<br />

vorgeschlagen werden.<br />

6.1 EFORRLSA<br />

EFORRLSA (Möller, 2002) ist ein Verfahren zur Vereinheitlichung <strong>von</strong> RRLSA und<br />

Gram-Schmidt Orthonormalisierung. Für hochdimensionale Trainingsvektoren lässt<br />

sich so die Geschwindigkeit <strong>von</strong> RRLSA + Orthonormalisierung theoretisch um den<br />

Faktor 2 steigern. Zudem würde eine Verschmelzung <strong>von</strong> Hauptkomponentenanalyse<br />

und Orthonormalisierung die Zugriffe auf den globalen Speicher verringern, was sich<br />

ebenfalls positiv auswirkt.<br />

6.2 AVX, Nvidia Tesla, AMD Plattform<br />

Die CPU-Implementierung arbeitet noch nicht mit explizit implementierten AVX-<br />

Befehlen 1 , wodurch eine Geschwindigkeitssteigerung bis zu Faktor 4 erreicht werden<br />

könnte. Andererseits hätte eine Nvidia Tesla Karte mit einer 64 Bit Leistungsfähigkeit<br />

<strong>von</strong> 515 GFLOPs 2 die dreifache Leistung der Nvidia GTX 570. Viel sinnvoller erscheint<br />

jedoch eine Optimierung speziell für die AMD Plattform. Hierdurch könnte die enorme<br />

Leistungsfähigkeit der Radeon HD 7970 besser genutzt werden.<br />

1 http://software.intel.com/en-us/avx<br />

Datum: 21.09.2012<br />

2 http://www.nvidia.de/content/PDF/data-sheet/NV_DS_Tesla_C2075_<br />

Sept11_US_HR.pdf<br />

Datum: 23.09.2012<br />

32 Universität Bielefeld, AG Technische Informatik


6 Ausblick<br />

6.3 Orthonormalisierung<br />

Beim Soft Clustering nimmt der Speedup mit steigender Eigenwertanzahl ab, was<br />

durch die verwendete angepasste Gram-Schmidt Orthonormalisierung verursacht wird.<br />

Durch eine weitere Optimierung dieses Algorithmus könnte der Speedup signifikant<br />

erhöht werden. Eine andere Möglichkeit wäre der Austausch des Algorithmus durch<br />

ein besser für die <strong>GPU</strong> geeignetes Verfahren.<br />

Das klassische Gram-Schmidtsche Orthonormalisierungsverfahren lässt sich grundsätzlich<br />

besser parallelisieren als die modifizierte Variante. Zur Verbesserung der numerischen<br />

Stabilität kann das Verfahren iteriert werden. Dies vervielfacht den Berechnungsaufwand,<br />

dennoch kann das Verfahren eine höhere Performance als MGS liefern. (Lingen,<br />

2000).<br />

6.4 Adaptive Anpassung der parallelen Trainingsvektoren<br />

Das Hard Clustering würde ebenfalls <strong>von</strong> einer verbesserten Orthonormalisierung profitieren.<br />

Es bietet sich jedoch an, die relativ einfache Heuristik zur adaptiven Anpassung<br />

der parallelen Trainingsvektoren zu erweitern. Durch eine verbesserte Heuristik könnte<br />

dieser Parameter besser geschätzt werden, was die Auslastung der <strong>GPU</strong> verbessern bzw.<br />

unnötige Distanzberechnungen vermeiden würde.<br />

Universität Bielefeld, AG Technische Informatik 33


LITERATURVERZEICHNIS<br />

Literaturverzeichnis<br />

Amdahl, G. Limits of expectation. 2(1):88–97, 1988.<br />

Bishop, C. M. Natural [Neural] networks for pattern recognition. Oxford Univ. Press,<br />

Oxford [u.a.], 2008.<br />

Björck, A. Numerics of gram-schmidt orthogonalization. Linear Algebra and its Applications,<br />

197198(0):297 – 316, 1994.<br />

Fatahalian, K. und Houston, M. Gpus a closer look. In ACM SIGGRAPH 2008 classes,<br />

SIGGRAPH ’08, pages 11:1–11:11, New York, NY, USA, 2008. ACM.<br />

Giraud, L., Langou, J., und Rozloznik, M. The loss of orthogonality in the gram-schmidt<br />

orthogonalization process. Computers & Mathematics with Applications, 50(7):1069<br />

– 1075, 2005.<br />

Hoffmann, H. Unsupervised learning of visuomotor associations. 2004.<br />

Hoffmann, H., Schenck, W., und Möller, R. Learning visuomotor transformations for<br />

gaze-control and grasping. Biological Cybernetics, 93:119–130, 2005.<br />

Hyvärinen, A., Karhunen, J., und Oja, E. Independent component analysis. Wiley, New<br />

York [u.a.], 2001.<br />

Jolliffe, I. T. <strong>Principal</strong> component analysis. Springer, New York [u.a.], 1986.<br />

Kaiser, A. Implementierung und Test des Twin-Birth-Verfahrens für Neural <strong>Gas</strong> <strong>Principal</strong><br />

<strong>Component</strong> Analysis. Diplomarbeit, Technische Fakultät der Universität Bielefeld,<br />

Bielefeld, 2008.<br />

Kambhatla, N. und Leen, T. K.<br />

analysis, 1997.<br />

Dimension reduction by local principal component<br />

Lingen, F. J. Efficient gramschmidt orthonormalisation on parallel computers. Communications<br />

in Numerical Methods in Engineering, 16(1):57–66, 2000.<br />

Marsaglia, G. Xorshift rngs. Journal of Statistical Software, 08(i14), 2003.<br />

Martinetz, T., Berkovich, S., und Schulten, K. ‘neural-gas’ network for vector quantization<br />

and its application to time-series prediction. Neural Networks, IEEE Transactions<br />

on, 4(4):558 –569, jul 1993.<br />

Milde, B. und Schneider, M. Parallel implementation of classical Gram-Schmidt orthogonalization<br />

on CUDA graphics cards. 2009.<br />

34 Universität Bielefeld, AG Technische Informatik


LITERATURVERZEICHNIS<br />

Möller, R. Interlocking of learning and orthonormalization in RRLSA. Neurocomputing,<br />

49(1-4):429–433, 2002.<br />

Möller, R. First-order approximation of Gram-Schmidt orthonormalization beats deflation<br />

in coupled PCA learning rules. Neurocomputing, 69(13-15):1582–1590, 2006.<br />

Möller, R. und Hoffmann, H. An extension of neural gas to local pca. Neurocomputing,<br />

62(0):305 – 326, 2004.<br />

Möller, R. und Konies, A. Coupled principal component analysis. Neural Networks,<br />

IEEE Transactions on, 15(1):214 –222, jan. 2004.<br />

Munshi, A. OpenCL programming guide. Addison-Wesley, Upper Saddle River, NJ<br />

[u.a.], 2012.<br />

Murthy, G., Ravishankar, M., Baskaran, M., und Sadayappan, P. Optimal loop unrolling<br />

for gpgpu programs. In Parallel Distributed Processing (IPDPS), 2010 IEEE<br />

International Symposium on, pages 1 –11, april 2010.<br />

Nischwitz, A., Fischer, M., Habercker, P., Socher, G., Nischwitz, A., Fischer, M., Habercker,<br />

P., und Socher, G. Gpu programmierung mit cuda und opencl. In Computergrafik<br />

und Bildverarbeitung, pages 481–505. Vieweg+Teubner Verlag, 2012.<br />

Oh, K.-S. und Jung, K. Gpu implementation of neural networks. Pattern Recognition,<br />

37(6):1311 – 1314, 2004.<br />

Ouyang, S., Bao, Z., und Liao, G.-S. Robust recursive least squares learning algorithm<br />

for principal component analysis. Neural Networks, IEEE Transactions on, 11(1):<br />

215 –221, jan 2000.<br />

Rünger, G. und Schwind, M. Comparison of different parallel modified gram-schmidt<br />

algorithms. In Euro-Par 2005 Parallel Processing, volume 3648 of Lecture Notes in<br />

Computer Science, pages 622–622. 2005.<br />

Sanders, J. und Kandrot, E. CUDA by example. Addison-Wesley, Upper Saddle River,<br />

NJ [u.a.], 2010.<br />

Sanger, T. D. Optimal unsupervised learning in a single-layer linear feedforward neural<br />

network. Neural Networks, 2(6):459 – 473, 1989.<br />

Schenck, W. Adaptive internal models for motor control and visual prediction. MPI<br />

series in biological cybernetics ; 20. Logos-Verl., 2008.<br />

Welsch, R. Adaptive Lernratensteuerung für Neural <strong>Gas</strong> <strong>Principal</strong> <strong>Component</strong> Analysis.<br />

Bachelorarbeit, Technische Fakultät der Universität Bielefeld, 2009.<br />

Universität Bielefeld, AG Technische Informatik 35


A<br />

Verwendete Parameter<br />

A.1 Roboterarmsteuerung<br />

Parameter<br />

Wert<br />

Eigenwerte 4<br />

Iterationen 20.000<br />

Threadanzahl (Soft Clustering) 64<br />

Threadanzahl (Hard Clustering) 256<br />

A.2 CT Slices<br />

Parameter<br />

Wert<br />

Eigenwerte 20<br />

Iterationen 20.000<br />

Threadanzahl (Soft Clustering, Nvidia GTX 560 Ti) 256<br />

Threadanzahl (Soft Clustering, Nvidia GTX 570) 512<br />

Threadanzahl (Soft Clustering, AMD Radeon HD 6970) 512<br />

Threadanzahl (Soft Clustering, AMD Radeon HD 7970) 256<br />

Threadanzahl (Hard Clustering, Nvidia GTX 560 Ti) 512<br />

Threadanzahl (Hard Clustering, Nvidia GTX 570) 512<br />

Threadanzahl (Hard Clustering, AMD Radeon HD 6970) 512<br />

Threadanzahl (Hard Clustering, AMD Radeon HD 7970) 256<br />

36 Universität Bielefeld, AG Technische Informatik


B<br />

Quelltexte<br />

OpenCL Pseudozufallszahlengenerator<br />

1 / ∗ ∗<br />

2 ∗ c a l c u l a t e random v a l u e i n [ 0 . . 1 ]<br />

3 ∗ /<br />

4 i n l i n e r e a l r a n d x o r s h i f t 3 2 ( g l o b a l u i n t ∗ s t a t e ) {<br />

5 u i n t x = ∗ s t a t e ;<br />

6 x ˆ= x > 1 7 ;<br />

8 x ˆ= x


B<br />

Quelltexte<br />

OpenCL Parallel Selection Sort 1<br />

1 i n l i n e void s o r t (<br />

2 c o n s t a n t u i n t ∗ s o r t A r r I d x ,<br />

3 c o n s t a n t r e a l ∗ s o r t A r r V a l ,<br />

4 g l o b a l u i n t ∗ s o r t A r r I d x O u t ,<br />

5 g l o b a l u i n t ∗ h c I d x s )<br />

6 {<br />

7 c o n s t u i n t chunkIdx = g e t g r o u p i d ( 0 ) − 1 ;<br />

8<br />

9 # i f PARALLEL HARDCLUSTERING == 1<br />

10 / / s h i f t t o c u r r e n t chunk<br />

11 s o r t A r r I d x += PROTOTYPES ∗ chunkIdx ;<br />

12 s o r t A r r V a l += PROTOTYPES ∗ chunkIdx ;<br />

13 # e n d i f<br />

14<br />

15 f o r ( s i z e t i = g e t l o c a l i d ( 0 ) ; i < PROTOTYPES ; i +=<br />

g e t l o c a l s i z e ( 0 ) )<br />

16 {<br />

17 u i n t i D a t a = s o r t A r r I d x [ i ] ;<br />

18 r e a l iKey = s o r t A r r V a l [ i ] ;<br />

19<br />

20 / / compute u n i t r a n k i n g<br />

21 i n t rank = 0 ;<br />

22 f o r ( i n t j =0; j


B<br />

Quelltexte<br />

Verwendung der NGPCA-Klasse<br />

1 # i n c l u d e ”NGPCA.H”<br />

2<br />

3 / / . . .<br />

4<br />

5 / / params<br />

6 NGPCAParams params ;<br />

7 params . p r o t o t y p e s = 2 0 ;<br />

8 params . o u t p u t D i m e n s i o n = 2 ;<br />

9 params . l a m b d a I n i t = 1 0 ;<br />

10 params . o r t h o i n t e r v a l = 1 ;<br />

11 params . r e s e t c h e c k i n t e r v a l = 1 5 ;<br />

12<br />

13 params . p h i = 2 . 0 ;<br />

14 params . mu = 0 . 0 0 5 ;<br />

15 params . r h o i n i t = 2 ;<br />

16 params . r h o f i n a l = 0 . 0 1 ;<br />

17 params . e p s i l o n i n i t = 0 . 5 ;<br />

18 params . e p s i l o n f i n a l = 0 . 0 1 ;<br />

19 params . pcaType = RRLSA;<br />

20 params . potType = VCONST;<br />

21<br />

22 u i n t t h r e a d C o u n t = 512;<br />

23 bool h a r d C l u s t e r i n g = t r u e ;<br />

24 u i n t maxChunkSize = 2 0 ;<br />

25 bool adaptiveMaxChunkSize = t r u e ;<br />

26 u i n t a d a p t i v e M a x C h u n k S i z e I n t e r v a l = 1 5 ;<br />

27 u i n t d e v i c e I d = 0 ;<br />

28 u i n t i t e r a t i o n s = 20000;<br />

29<br />

30<br />

31 / / i n i t<br />

32 NGPCA ngpca ( params , t h r e a d C o u n t , h a r d C l u s t e r i n g , maxChunkSize<br />

, adaptiveMaxChunkSize , a d a p t i v e M a x C h u n k S i z e I n t e r v a l , d e v i c e I d ) ;<br />

33<br />

34 / / l o a d d a t a<br />

35 ngpca . l o a d F r o m F i l e ( ” i n p u t . mat ” ) ;<br />

36<br />

37 / / l e a r n<br />

38 ngpca . l e a r n ( i t e r a t i o n s ) ;<br />

39<br />

40 / / w r i t e o u t p u t<br />

41 ngpca . w r i t e ( ” i n p u t . mat . ngpca ” ) ;<br />

Listing B.3: Verwendung der NGPCA-Klasse<br />

Universität Bielefeld, AG Technische Informatik 39


B<br />

Quelltexte<br />

OpenCL Gram-Schmidt Orthonormalisierung<br />

1 i n l i n e<br />

2 void o r t h o P a r a l l e l (<br />

3 g l o b a l r e a l ∗ w,<br />

4 g l o b a l r e a l ∗ v ,<br />

5 g l o b a l r e a l ∗ l ,<br />

6 l o c a l r e a l ∗ tempBuffer , / / WORKGROUP SIZE∗WORKGROUP SIZE<br />

7 l o c a l r e a l ∗ norm ,<br />

8 l o c a l r e a l ∗ buf ) / / VEC SIZE<br />

9 {<br />

10 / ∗ ∗<br />

11 ∗ Vars<br />

12 ∗ /<br />

13 c o n s t u i n t l i n e a r L o c a l I d x = g e t l o c a l i d ( 0 ) + g e t l o c a l i d ( 1 ) ∗<br />

g e t l o c a l s i z e ( 0 ) ;<br />

14 c o n s t s i z e t t h r e a d s = g e t l o c a l s i z e ( 0 ) ∗ g e t l o c a l s i z e ( 1 ) ;<br />

15<br />

16 / ∗ ∗<br />

17 ∗ O r t h o n o r m a l i z e W<br />

18 ∗ /<br />

19 {<br />

20 / ∗ ∗<br />

21 ∗ n o r m a l i z e f i r s t column<br />

22 ∗ /<br />

23 {<br />

24 / / quadr<br />

25 t e m p B u f f e r [ l i n e a r L o c a l I d x ] = 0 ;<br />

26 f o r ( s i z e t yIdx = l i n e a r L o c a l I d x ; yIdx < VEC SIZE ; yIdx +=<br />

t h r e a d s ) {<br />

27 r e a l v a l = w[ yIdx ∗OUT DIM ] ;<br />

28<br />

29 buf [ yIdx ] = v a l ;<br />

30<br />

31 t e m p B u f f e r [ l i n e a r L o c a l I d x ] += v a l ∗ v a l ;<br />

32 }<br />

33 b a r r i e r (CLK LOCAL MEM FENCE) ;<br />

34<br />

35 / / r e d u c e quadr p e r t h r e a d<br />

36 s i z e t r e d u c t i o n I d x = t h r e a d s / 2 ;<br />

37 w h i l e ( r e d u c t i o n I d x != 0) {<br />

38 i f ( l i n e a r L o c a l I d x < r e d u c t i o n I d x ) {<br />

39 t e m p B u f f e r [ l i n e a r L o c a l I d x ] += t e m p B u f f e r [ l i n e a r L o c a l I d x +<br />

r e d u c t i o n I d x ] ;<br />

40 }<br />

41<br />

42 b a r r i e r (CLK LOCAL MEM FENCE) ;<br />

43 r e d u c t i o n I d x = r e d u c t i o n I d x / 2 ;<br />

44 }<br />

45<br />

46 / / c a l c u l a t e norm<br />

47 i f ( l i n e a r L o c a l I d x == 0) {<br />

48 ∗norm = SQRT( t e m p B u f f e r [ 0 ] ) ;<br />

49 }<br />

50 b a r r i e r (CLK LOCAL MEM FENCE) ;<br />

51<br />

52 / / n o r m a l i z e and s t o r e<br />

53 r e a l f i r s t L = l [ 0 ] ;<br />

40 Universität Bielefeld, AG Technische Informatik


B<br />

Quelltexte<br />

54 f o r ( s i z e t yIdx = l i n e a r L o c a l I d x ; yIdx < VEC SIZE ; yIdx +=<br />

t h r e a d s ) {<br />

55 r e a l n o r m a l i z e d = buf [ yIdx ] / (∗ norm ) ;<br />

56<br />

57 / / s t o r e r e s u l t<br />

58 w[ yIdx ∗OUT DIM] = n o r m a l i z e d ;<br />

59 v [ yIdx ∗OUT DIM] = n o r m a l i z e d ∗ f i r s t L ;<br />

60<br />

61 / / keep r e s u l t i n l o c a l memory<br />

62 buf [ yIdx ] = n o r m a l i z e d ;<br />

63 }<br />

64 }<br />

65<br />

66 / ∗ ∗<br />

67 ∗ c a l c u l a t e s c a l a r p r o d u c t s<br />

68 ∗ /<br />

69 f o r ( s i z e t c o l = 1 ; c o l < OUT DIM ; c o l ++) {<br />

70 b a r r i e r (CLK LOCAL MEM FENCE) ;<br />

71<br />

72 s i z e t o f f s e t = c o l ;<br />

73 s i z e t xIdx = c o l + g e t l o c a l i d ( 0 ) ;<br />

74<br />

75 w h i l e ( o f f s e t < OUT DIM) {<br />

76 / / i n i t<br />

77 t e m p B u f f e r [ l i n e a r L o c a l I d x ] = 0 ;<br />

78<br />

79 i f ( xIdx < OUT DIM) {<br />

80 / / sum up<br />

81 f o r ( s i z e t yIdx = g e t l o c a l i d ( 1 ) ; yIdx < VEC SIZE ; yIdx +=<br />

g e t l o c a l s i z e ( 1 ) ) {<br />

82 t e m p B u f f e r [ l i n e a r L o c a l I d x ] += w[ xIdx + yIdx ∗OUT DIM] ∗<br />

buf [ yIdx ] ;<br />

83 }<br />

84 }<br />

85 b a r r i e r (CLK LOCAL MEM FENCE) ;<br />

86<br />

87 / / r e d u c e<br />

88 s i z e t r e d u c t i o n I d x = t h r e a d s / 2 ;<br />

89 w h i l e ( r e d u c t i o n I d x >= g e t l o c a l s i z e ( 0 ) ) {<br />

90 i f ( l i n e a r L o c a l I d x < r e d u c t i o n I d x ) {<br />

91 t e m p B u f f e r [ l i n e a r L o c a l I d x ] += t e m p B u f f e r [ l i n e a r L o c a l I d x +<br />

r e d u c t i o n I d x ] ;<br />

92 }<br />

93<br />

94 b a r r i e r (CLK LOCAL MEM FENCE) ;<br />

95 r e d u c t i o n I d x = r e d u c t i o n I d x / 2 ;<br />

96 }<br />

97<br />

98 / / t e m p B u f f e r c o n t a i n s s c a l a r p r o d u c t s i n f i r s t<br />

WORKGROUP SIZE e l e m e n t s<br />

99<br />

100 / / s u b t r a c t<br />

101 i f ( xIdx < OUT DIM) {<br />

102 f o r ( s i z e t yIdx = g e t l o c a l i d ( 1 ) ; yIdx < VEC SIZE ; yIdx +=<br />

g e t l o c a l s i z e ( 1 ) ) {<br />

103 w[ xIdx + yIdx ∗OUT DIM] −= t e m p B u f f e r [ g e t l o c a l i d ( 0 ) ] ∗<br />

buf [ yIdx ] ;<br />

104 }<br />

Universität Bielefeld, AG Technische Informatik 41


B<br />

Quelltexte<br />

105 }<br />

106<br />

107 o f f s e t += g e t l o c a l s i z e ( 0 ) ;<br />

108 xIdx += g e t l o c a l s i z e ( 0 ) ;<br />

109 }<br />

110 b a r r i e r (CLK GLOBAL MEM FENCE) ;<br />

111<br />

112 / ∗ ∗<br />

113 ∗ c a l c u l a t e r e s u l t i n g column<br />

114 ∗ /<br />

115 / / quadr<br />

116 t e m p B u f f e r [ l i n e a r L o c a l I d x ] = 0 ;<br />

117 f o r ( s i z e t yIdx = l i n e a r L o c a l I d x ; yIdx < VEC SIZE ; yIdx +=<br />

t h r e a d s ) {<br />

118 r e a l v a l = w[ c o l + yIdx ∗OUT DIM ] ;<br />

119<br />

120 buf [ yIdx ] = v a l ;<br />

121<br />

122 t e m p B u f f e r [ l i n e a r L o c a l I d x ] += v a l ∗ v a l ;<br />

123 }<br />

124 b a r r i e r (CLK LOCAL MEM FENCE) ;<br />

125<br />

126 / / r e d u c e quadr p e r t h r e a d<br />

127 s i z e t r e d u c t i o n I d x = t h r e a d s / 2 ;<br />

128 w h i l e ( r e d u c t i o n I d x != 0) {<br />

129 i f ( l i n e a r L o c a l I d x < r e d u c t i o n I d x ) {<br />

130 t e m p B u f f e r [ l i n e a r L o c a l I d x ] += t e m p B u f f e r [ l i n e a r L o c a l I d x +<br />

r e d u c t i o n I d x ] ;<br />

131 }<br />

132<br />

133 b a r r i e r (CLK LOCAL MEM FENCE) ;<br />

134 r e d u c t i o n I d x = r e d u c t i o n I d x / 2 ;<br />

135 }<br />

136<br />

137 / / c a l c u l a t e norm<br />

138 i f ( l i n e a r L o c a l I d x == 0) {<br />

139 ∗norm = SQRT( t e m p B u f f e r [ 0 ] ) ;<br />

140 }<br />

141 b a r r i e r (CLK LOCAL MEM FENCE) ;<br />

142<br />

143 / / n o r m a l i z e & s t o r e<br />

144 r e a l c u r r L = l [ c o l ] ;<br />

145 f o r ( s i z e t yIdx = l i n e a r L o c a l I d x ; yIdx < VEC SIZE ; yIdx +=<br />

t h r e a d s ) {<br />

146 r e a l n o r m a l i z e d = w[ c o l + yIdx ∗OUT DIM] / (∗ norm ) ;<br />

147<br />

148 / / s t o r e r e s u l t<br />

149 w[ c o l + yIdx ∗OUT DIM] = n o r m a l i z e d ;<br />

150 v [ c o l + yIdx ∗OUT DIM] = n o r m a l i z e d ∗ c u r r L ;<br />

151<br />

152 / / keep r e s u l t i n l o c a l memory<br />

153 buf [ yIdx ] = n o r m a l i z e d ;<br />

154 }<br />

155 }<br />

156 }<br />

157 }<br />

Listing B.4: OpenCL Gram-Schmidt Orthonormalisierung<br />

42 Universität Bielefeld, AG Technische Informatik


C<br />

Kompilierung und Ausführung der<br />

Quelltexte<br />

Kompilierung<br />

Die Kompilierung in der PROG4 Umgebung kann einfach mittels vmk gestartet werden.<br />

Soll das Projekt separat übersetzt werden, so kann dies mit Hilfe <strong>von</strong> CMake geschehen:<br />

cmake . && make<br />

Ausführung<br />

Das Trainieren eines NGPCA-Netzwerkes mit 100 Prototypen, 20.000 Iterationszyklen<br />

und einer Ausgabedimension <strong>von</strong> 4 kann z.B. mit folgendem Kommando gestartet werden<br />

1 :<br />

gpu_ngpca \<br />

-d 4 -p 100 -i 20000 \<br />

train INPUT_FILE<br />

Bitte beachten Sie, dass die Angabe dieser Parameter obligatorisch ist, während weitere<br />

Parameter (siehe Anhang E) optional sind.<br />

1 Wobei INPUT FILE ein Platzhalter für den Pfad zur Eingabematrix ist<br />

Universität Bielefeld, AG Technische Informatik 43


D<br />

Verwendete Software-Bibliotheken<br />

Für die Umsetzung der vorliegenden Bachelorarbeit wurden folgende Software-<br />

Bibliotheken benutzt:<br />

• OpenCL 1.1 - GP<strong>GPU</strong> Schnittstelle<br />

http://www.khronos.org/opencl/<br />

• OpenCL C++ Bindings 1.1 - C++ Wrapper für OpenCL<br />

http://www.khronos.org/registry/cl/specs/<br />

opencl-cplusplus-1.1.pdf<br />

• Matrix 4-6-WS1 - Matrix Bibliothek<br />

˜/PROG4/libraries/Matrix-4-6-WS1<br />

• Boost Program Options 1.46.1 - Parser für Kommandozeilenargumente<br />

http://www.boost.org/doc/libs/1_46_1/doc/html/program_<br />

options.html<br />

• CMake - Build System (optional)<br />

http://www.cmake.org<br />

44 Universität Bielefeld, AG Technische Informatik


E<br />

Kommandozeilenparameter<br />

Die Applikation kann mittels gpu_ngpca [command] {options} gestartet werden,<br />

wobei die möglichen Kommandos und Optionen im Folgenden erläutert werden.<br />

Kommandos<br />

Befehl<br />

list-platforms<br />

list-devices<br />

train [inputFile]<br />

Wirkung<br />

Zeigt alle verfügbaren OpenCL-Plattformen an<br />

Zeigt alle verfügbaren OpenCL-Geräte an<br />

Trainiert ein NGPCA-Netzwerk<br />

Generelle Optionen<br />

Befehl<br />

Vorgabewert<br />

--help<br />

Zeigt die Hilfe an<br />

--device<br />

Auswahl des OpenCL Gerätes 0<br />

--doublePrecision<br />

Soll mit doppelter Genauigkeit gerechnet werden?<br />

1 (Ja)<br />

--threadCount<br />

Maximale Anzahl der parallelen Ausführungsstränge 512<br />

--maxChunkSize<br />

Maximale Anzahl an parallelen harten Vektorquantisierungen 20<br />

--adaptiveMaxChunkSize<br />

Soll die Anzahl an parallelen harten Vektorquantisierungen automatisch<br />

angepasst werden?<br />

1 (Ja)<br />

--adaptiveMaxChunkSizeInterval<br />

In welchem Intervall soll die automatische Anpassung durchgeführt 20<br />

werden?<br />

Universität Bielefeld, AG Technische Informatik 45


E<br />

Kommandozeilenparameter<br />

NGPCA Optionen<br />

Befehl<br />

Vorgabewert<br />

-i [ --iterations ]<br />

Anzahl der Iterationszyklen<br />

-p [ --prototypes ]<br />

Anzahl der zu verwendenden Prototypen<br />

-d [ --outputDimensions ]<br />

Ausgabedimension<br />

--lambdaInit<br />

Initiales Lambda 10<br />

--orthoInterval<br />

Intervall, in dem die Orthonormalisierung durchgeführt werden 1<br />

soll<br />

--resetCheckInterval<br />

Intervall, in dem die Prototypen überprüft und ggf. zurückgesetzt 15<br />

werden<br />

--phi<br />

Phi 2<br />

--rhoInit<br />

Rho (Anfangswert) 2<br />

--rhoFinal<br />

Rho (Endwert) 0.01<br />

--epsilonInit<br />

Epsilon (Anfangswert) 0.5<br />

--epsilonFinal<br />

Epsilon (Endwert) 0.001<br />

--hardClustering<br />

Soll harte Vektorquantisierung verwendet werden?<br />

1 (Ja)<br />

--pcaType<br />

Art der lokalen PCA (1 = RRLSA,2 = CouplePCA)<br />

1 (RRLSA)<br />

--potType<br />

Art der Potentialberechnung (1 = VConst,2 = TracePotential) 2 (TracePotential)<br />

46 Universität Bielefeld, AG Technische Informatik


Hiermit versichere ich, dass ich diese Bachelorarbeit selbständig bearbeitet habe.<br />

Ich habe keine anderen als die angegebenen Quellen und Hilfsmittel benutzt und<br />

entsprechende Zitate kenntlich gemacht.<br />

Bielefeld, den 26. September 2012<br />

Christian Menßen<br />

Universität Bielefeld, AG Technische Informatik 47

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!