Entwicklungsverlauf - AlexanderMelde/3D-GAN GitHub Wiki

Auf dieser Seite werden der Verlauf der Entwicklung, die dabei aufgetretenen Probleme und unsere Lösungsansätze hierzu dokumentiert.

Entwicklungsverlauf

Inhaltsverzeichnis:

  1. Auswahl der Entwicklungsumgebung
  2. Einrichtung der Entwicklungsumgebung
  3. Generierung von 3D-Modellen
  4. Interpolation
  5. Visualisierung

1) Auswahl der Entwicklungsumgebung

Zunächst war nicht sicher, in welcher Umgebung entwickelt werden soll. Zur Auswahl standen ein Desktop-PC mit Ubuntu 16.04 im Labor für Maschinensehen (LfM), die Desktop-PCs der Autoren mit Windows 10 sowie die Notebooks der Autoren.

Schon während der ersten Besprechung wurde beschlossen, dass eine Entwicklung auf einem Notebook nicht Zielführend ist, da hier keine ausreichende Rechenleistung gewährleistet werden kann.

Um die Auswahl weiter einzuschränken wurde überprüft, mit welchen Betriebssystemen die benötigten Bibliotheken kompatibel sind. Auf der Website von Torch wird von einer Installation unter Windows abgeraten (Quelle), weshalb die Windows-Rechner nur bei Verwendung einer virtuellen Maschine (VM) in Frage kämen. Leider unterstützt keine der getesteten Virtualisierungsmöglichkeiten VirtualBox oder Docker eine GPU-Unterstützung bei Windows als Host-System, weshalb die Entscheidung auf den Ubuntu-PC im LfM fiel.

2) Einrichtung der Entwicklungsumgebung

Bei der Einrichtung des Desktop-PCs im LfM fiel auf, dass für Teile des Installationsverfahrens Adminrechte auf dem PC erforderlich sind. Um weniger Sicherheitsrisiken einzugehen wurde in Kooperation mit einem Admin das Containerisierungstool Docker auf den PC installiert und die Autoren bekamen die Genehmigung, Docker zu benutzen.

Um die Grafikkarte auch innerhalb des Containers direkt ansprechen zu können, wurde zudem das Programm nvidia-docker installiert. Da auf dem Host-PC die Grafikframeworks CUDA und CuDNN noch nicht installiert waren, wurden auch diese in Kooperation mit dem Admin installiert.

Ein weiterer Vorteil, der durch die Verwendung von Docker entsteht, ist die hohe Nachvollziehbarkeit aller ausgeführten Befehle.

2.1) Installation des GPU-unterstützten Docker (07.11.2018)

  1. Grafikkarte, Compiler etc. auf richtige Versionen bringen (Siehe Notizen des Admins Steffen Teichmann)
  2. CUDA installieren und Beispiele kompilieren (Anleitung)
  3. CuDNN installieren und Beispiele kompilieren (Anleitung)
  4. Docker installieren (Anleitung)
  5. Alle Nutzer, die Zugriff brauchen, in Docker-Gruppe hinzufügen (Anleitung)
  6. Proxy für Docker Daemon (Host) konfigurieren (Anleitung)
  7. nvidia-docker installieren (Anleitung)
Features Bugs
Docker funktioniert mit GPU (Test mit docker run --runtime=nvidia nvidia/cuda:9.0-base nvidia-smi erfolgreich) Download von externen Docker-Images nur möglich, wenn der Admin auf dem Host in die hier beschriebenen Dateien Proxy-Anmeldedaten im Klartext einträgt.
Es gibt noch kein Internet im Container (wegen Hochschul-Proxy), es funktioniert innerhalb daher kein Download.

2.2) Einrichten von Internet im Container

Um den Proxy innerhalb des Containers verfügbar zu machen, sind bei jeder Verwendung der Containers die folgenden Schritte notwendig.

  1. Auf dem Host die passenden Umgebungsvariablen setzen mit einem im Rahmen dieser Arbeit geschriebenem Skript: source ./prepare_host.sh
  2. Den jew. Docker-Container mit dem im Rahmen dieser Arbeit geschriebenem Build-Script bauen: ./build.sh
  3. Den jew. Docker-Container mit dem im Rahmen dieser Arbeit geschriebenem Run-Script ausführen: ./run.sh

Bei Aufruf des Build- oder Run-Scripts werden die aktuellen Einstellungen für eine Konfiguration des Proxys vom Host-Computer übernommen und anschließend wieder aus den Containern entfernt. So befinden sich nach Abschluss der Skriptdurchläufe keine persönlichen Passwörter in den von allen Nutzern nutzbaren Docker Containern.

Das prepare_host-Skript ermöglicht es, mit nur einer Anmeldung den Proxy an allen relevanten Stellen des Host-Systems einzurichten.

Innerhalb des Dockerfiles werden die übergebenen Proxy-Parameter entgegengenommen, als Umgebungsvariablen gesetzt und die apt-Konfiguration entsprechend modifiziert (siehe Dockerfile).

Features Bugs
Docker funktioniert mit GPU (Test mit docker run --runtime=nvidia nvidia/cuda:9.0-base nvidia-smi erfolgreich) Download von externen Docker-Images nur möglich, wenn der Admin auf dem Host in die hier beschriebenen Dateien Proxy-Anmeldedaten im Klartext einträgt.
Es gibt Internet im Container (Test mit apt update) Der Proxy muss innerhalb des Dockerfiles berücksichtigt werden. Keine Abstraktion möglich.

Die bisher erarbeiteten Grundlagen sind Bestandteil aller drei Dockerfiles.

2.3) Installation von Torch

Für den Ansatz 3dgan-release WU16(Quellenangaben) ist eine Installation von Torch erforderlich. Der folgende Abschnitt bezieht sich daher auf das Dockerfile lfm_base. Die Installation von Torch soll vollständig innerhalb des Dockerfiles geschehen.

Grundsätzlich wurden die Schritte des Getting Started Guide von Torch verwendet. Für das verwendete System mussten die folgenden Anpassungen vorgenommen werden.

  1. Bei der Installation von OpenBlas erscheint ein Fehler (siehe GitHub Issue). Wir installieren daher mit apt die Alternative Atlas und entfernen den Funktionsaufruf, der OpenBlas installiert, im Installationsskript vom Torch.

  2. Bei der Installation von Lua und Torch müssen Umgebungsvariablen gesetzt werden. Da mit export definierte Umgebungsvariablen bei Docker nur innerhalb eines RUN-Befehls gültig sind, wurden die Umgebungsvariablen manuell mit dem ENV-Befehl im Dockerfile definiert.

  3. Bei der Installation des luarocks-Paketes matio kann git nicht den Server github.com erreichen. Das liegt daran, das der Proxy alle Kommunikation über das git://-Protokoll blockiert. Git muss daher so konfiguriert werden, dass es alle diese Anfragen über https umleitet.

Die einzelnen Befehle zur Umsetzung der genannten Lösungsvorschläge können im Dockerfile nachgelesen werden.

Mit dem bis zu dieser Stelle entwickelten Dockerfile konnten die Experimente des 3dgan-release WU16(Quellenangaben) erfolgreich durchgeführt werden, die generierten Ergebnisse können aber noch nicht visualisiert werden.

2.4) Exkurs: Installation von 3dgan-release ohne Docker und Proxy

Für eine reine Installation von 3dgan-release WU16(Quellenangaben) auf einem freien Rechner mit Ubuntu 18.04 ist grundsätzlich keine Anpassung hinsichtlich des Proxy oder fehlender Adminrechte notwendig.

Die im Folgenden gezeigten Installationsschritte wurden in einer VM getestet, aufgrund dessen Rechenleistung aber nicht weiter verfolgt.

  1. Install Ubuntu 18.04

  2. Install Torch http://torch.ch/docs/getting-started.html

    1. sudo apt install -y git
    2. git clone https://github.com/torch/distro.git ~/torch --recursive
    3. cd ~/torch
    4. bash install-deps
    5. sudo apt install -y cmake build-essential libreadline-dev
    6. ./install.sh
    7. source ~/.bashrc
    8. th
  3. Install mat IO Interface

    1. sudo apt install -y libmatio4
    2. luarocks install matio
    3. ln -s /usr/lib/x86_64-linux-gnu/libmatio.so.4 /usr/lib/x86_64-linux-gnu/libmatio.so
  4. Download 3DGan-Release

    1. git clone https://github.com:zck119/3dgan-release.git ~/3dgan --recursive
    2. cd ~/3dgan
    3. ./download_models_cpu.sh
    4. ./download_models_gpu.sh
    5. ./download_demo_inputs.sh
  5. Test 3DGAN-Release

    1. th main.lua -gpu 0 -class chair (Oder andere Demo von hier)
  6. Installieren und Test der Visualisierung

    1. pip install numpy matplotlib scipy vtk=5.10.1
    2. python visualize.py output/chair.mat -u 0.9 -t 0.1 -i 1 -mc 2

Im Vergleich zu den von den Autoren von 3dgan-release WU16(Quellenangaben) vorgeschlagenen Schritten wurden die folgenden Anpassungen vorgenommen:

  • Da die Bibliothek libmatio2 nicht in der apt-repo von Ubuntu 18.04 ist, wurde stattdessen die neuere Version libmatio4 verwendet.
  • Die neue Version libmatio4 wird nicht direkt gefunden, weshalb eine zusätzliche Verlinkung erforderlich ist. Diese wurde mithilfe von ln -s /usr/lib/x86_64-linux-gnu/libmatio.so.4 /usr/lib/x86_64-linux-gnu/libmatio.so vorgenommen und als Pull Request an den Autor der matio-Bibliothek kommuniziert.
  • In den Installationsanleitungen wurden nicht alle zu installierenden Pakete genannt, so mussten git, build-essentials und weitere nach der jeweiligen Fehlermeldung nachträglich installiert werden.

2.5) Installation von 3D-IWGAN

Die neuere Implementierung von Edward Smith 3D-IWGAN SM17(Quellenangaben) basiert auf Tensorflow und verspricht zudem, bessere Ergebnisse zu liefern als das vorherige auf Torch basierte 3dgan-release WU16(Quellenangaben) Projekt.

Das Dockerfile für den Container basiert ebenfalls auf dem selben Base-Image und kann bis zu den torch-spezifschen Stellen übernommen werden. Zur Installation von Python und Tensorflow sowie zum initialisieren der Projektdateien sind die folgenden Schritte erforderlich:

  1. Benötigte Biblotheken und Programme installieren mit apt install python-dev python-pip python-tk wget und anschließend pip install tensorflow tensorlayer keras.

  2. Projekt Repository 3D-IWGAN klonen.

  3. Projektdateien modifizieren, um Kompabilität mit aktueller Version von Tensorflow sicherzustellen:

    1. In ~/3dIWGAN/3D-Generation/32-3D-Gan.py und 32-3D-IWGan.py die Stelle tl.ops.set_gpu_fraction(sess=sess, gpu_fraction=0.998) durch tl.utils.set_gpu_fraction(gpu_fraction=0.998) ersetzen
    2. In ~/3dIWGAN/scripts/models.py die veraltete (deprecated) Funktion tl.layers.set_name_reuse(reuse) rauslöschen (kleinere Performance-Einbuße möglich, mögliche Fehler in der Zukunft) und die Funktion tl.activation.leaky_relu durch tl.nn.leaky_relu ersetzen.
  4. Herunterladen der Beispiel-Trainingsdaten (Erforderlich für spätere Generierung von Modellen). Hierfür kann das Make_Data.sh-Skript ausgeführt werden, das die Trainingsdaten nicht nur herunterlädt, sondern auch mithilfe des convert_shapenet10.py-Skripts in das benötigte Datenformat umwandelt.

Es wurde getestet, ob bereits während dem Build des Containers ein erster Test der Skripte möglich ist, allerdings haben wir herausgefunden, dass es während dem Build bei nvidia-docker keine GPU Unterstützung gibt, weshalb alle Experimente mit der GPU später in run ausgeführt werden müssen.

Damit die Ergebnisse des Trainings auf dem Host gespeichert werden können wurde zudem ein Tauschordner erstellt, der mithilfe des Run-Files synchronisiert wird (Volume Share). Hierbei ist aufgefallen, dass Dateien im Shared Folder dem Nutzer des Docker Containers ("root") gehören, weshalb sie ohne Admin-Rechte nur vom Container aus gelöscht/bearbeitet werden können. Um dieses Problem zu umgehen, müssen die Datei-Zugriffsrechte vom Container aus entsprechend modifiziert werden, beispielsweise mit dem Befehl chmod -R 777 *.

2.6) Installation des coms-project

Das coms-projects RP17(Quellenangaben) kann ähnlich wie das im vorigen Abschnitt beschriebene 3D-IWGAN SM17(Quellenangaben) installiert werden. Das hierfür auszuführende Dockerfile befindet sich im Repository im Ordner lfm_coms.

Da an den heruntergeladenen Projektdateien einige Änderungen vorgenommen werden mussten, werden diese diesmal nicht innerhalb des Dockerfiles vorgenommen, sondern mithilfe eines Ordners in den Container inkludiert. Die modifizierten Dateien befinden sich im Repository im Ordner lfm_coms/include.

3) Generierung von 3D-Modellen

3.1) 3dgan-release

Nach der in 2.3) beschriebenen Installation von Torch konnten verschiedene Experimente aus dem Originalprojekt durchgeführt werden.

Die Demo „Synthesize chairs with pre-sampled demo inputs and a CPU“ kann mit dem Befehl th main.lua -gpu 0 -class chair aufgerufen werden. Bei Ubuntu 18.04 in einer VM mit 4GB RAM, Intel i5 2500K und GTX1070Ti kam nach einiger Zeit die Meldung von Torch, dass der RAM nicht ausreicht. Bei Ubuntu 16.04 auf dem LfM-Rechner sowie auf dem Privatrechner von Herrn Harlacher wurde im Ordner output/ ein 3D-Modell mit dem Namen chair_demo.mat gespeichert.

Dieses kann wie in 5) beschrieben visualisiert werden.

3.2) Training von 3D-IWGAN

Zur Generierung von Objekten im 3D-IWGAN SM17(Quellenangaben) Projekt muss zunächst das Modell trainiert werden. Hierfür kann der folgende Befehl genutzt werden:

cd ~/3dIWGAN/3D-Generation/ && python IWGAN_own.py --name "trainedChairs" --data "data/train/chair" && cd .. && cp -R 3D-Generation 3D-Generation_shared

Das Skript IWGAN_own.py ist eine angepasste Version des originalen 32-3D-IWGan.py Skripts. Die Daten werden standardmäßig im Unterordner savepoints gespeichert, es ist aber auch möglich, im Skript einen anderen Pfad anzugeben. In der modifizierten Version werden die Dateien daher direkt in einem mit dem Host geteilten Ordner abgespeichert. Um keine Daten vorhergegangener Versuche zu überschreiben, sollte in jedem Versuch ein anderer Name in den Befehl eingetragen werden.

Für jeden Savepoint werden 256 (=BatchSize) 3D-Objekte der Größe (32,32,32) generiert (=32^3 Voxel).

Die Zufallsvektoren werden am Anfang des Skripts 32-3D-IWGAN.py generiert in Form eines Tensorflow Tensors. Dieser wurde im von uns modifizierten Skript IWGAN_own.py in ein Numpy array umgeformt und abgespeichert in den aktuellen Ordner als .npy Datei. Diese kann wie folgt angesehen werden:

import numpy as np
np.load("NAME_z.npy").shape
>> (256, 200)

Die 256 Einträge entsprechen der Batch-Size. Auch die Savepoints des Skripts haben 256 Einträge (bzw. 3D-Objekte), sodass sich jedem 3D-Objekt (32,32,32) ein Zufallsvektor der Länge 200 zuordnen lässt.

Über Nacht wurden 1500 Epochen trainiert, es entstanden 300 Savepoints (10GB), 600 Checkpoints (7GB), ein Zufallsvektor und mehrere Plots (loss?) wie der folgende nach 1495 Epochen Training:

1495

3.3) Training von coms-project

Die Schritte, die zum Training des coms-projects RP17(Quellenangaben) sowie zur Generierung von 3D-Modellen mit diesem erforderlich sind, sind auf der Wiki-Seite "Interpolation" aufgeführt. So können die einzelnen Schritte besser in den Gesamtkontext der finalen Version eingeordnet werden.

4) Interpolation

4.1) Interpolation von 3DIWGAN-Modellen mit dem coms-project Interpolations-Code

In diesem Experiment wurde geprüft, ob mit 3D-IWGAN SM17(Quellenangaben) generierte Objekte mit dem Skript des coms-projects RP17(Quellenangaben) interpoliert werden können.

Hierfür muss man folgende Schritte durchführen:

  1. Zufallsvektoren für 3D Modelle initialisieren und 3D-Modelle generieren mit cd ~/3dIWGAN/3D-Generation/ && python IWGAN_own.py --name "lfmTestChair32" -b 32 --data "data/train/chair" && cd .. && cp -R 3D-Generation 3D-Generation_shared. Die Batchsize muss 32 entsprechen, da das später genutzte Interpolations-Skript nur diese Größe akzeptiert. In der modifzierten Datei IWGAN_own.py wurde die np.save(args.name+"_zvectors",sess.run(z))-Funktion genutzt, um die Vektoren zu speichern.

  2. Zwischen den ersten beiden Zufallsvektoren interpolieren mit cd ~/3dIWGAN/3D-Generation_shared/ && python interpolation_32chair.py

  3. Den interpolierten Zufallsvektor als Basis für das Trainieren weiterer 3D-Modelle nutzen mit cd ~/3dIWGAN/3D-Generation/ && python IWGAN_own.py -e 1500 -b 32 --name "lfmTestChair32_z_interpolated" --data "data/train/chair" --zvector lfmTestChair32_z_interpolated.npy && cd .. && cp -R 3D-Generation 3D-Generation_shared

Die einzelnen Befehle können mit dem generate.sh Skript im Ordner lfm_tensorflow automatisiert aufgerufen werden.

Als Ergebnis wurden 3D-Modelle erwartet, die zwischen den ersten beiden Modellen aus Schritt 1 interpolieren. Dies war leider nicht der Fall. Es wurden 3D-Modelle zurückgegeben, die nicht interpolieren, sondern wie ganz normale unterschiedliche Stühle aussehen.

Die Ergebnisse wurden wie in 5) beschriebenen mit MeshLab visualisiert:

Original lfmTestChair32[0] Original lfmTestChair32[1]
interpolation_original000 interpolation_original100
Interpolated lfmTestChair32_z_interpolated[0] Interpolated lfmTestChair32_z_interpolated[31]
interpolation_z_000 interpolation_z_3100

Beispielhafte Zwischenschritte:

lfmTestChair32_z_interpolated[1] lfmTestChair32_z_interpolated[2] lfmTestChair32_z_interpolated[17] lfmTestChair32_z_interpolated[24] lfmTestChair32_z_interpolated[30]
interpolation_z_100 interpolation_z_200 interpolation_z_1700 interpolation_z_2400 interpolation_z_3000

4.2) Interpolation komplett mit coms-project

Die Schritte, die zur Interpolation von mit dem coms-project RP17(Quellenangaben) generierten 3D-Modellen erforderlich sind, sind auf der Wiki-Seite "Interpolation" aufgeführt. So können die einzelnen Schritte besser in den Gesamtkontext der finalen Version eingeordnet werden.

In diesem Experiment konnte erfolgreich eine Interpolation zwischen zwei 3D-Objekten erzielt werden.

5) Visualisierung

5.1) Grafische Ausgaben mit Docker

Zur Visualisierung der im Container generierten Dateien muss im Container OpenGL ausgeführt werden können und im Container kreiierte GUIs sollten auf dem Host-System angezeigt werden können.

  1. Zur Durchreichung von grafischen Ausgaben ist auf dem Host-System ein XHost-Server erforderlich. Dieser kann mittels apt install x11-server-utils installiert werden.

  2. Um innerhalb des Containers OpenGL-Bibliotheken (LibGL) verwenden zu können, muss als Root-Image des Containers nvidia/cudagl:9.0-base statt nvidia/cuda:9.0-base verwendet werden.

5.2) Visualisierung von .mat 3D-Objekten mit vtk

Zur Visualisierung der mit 3dgan-release WU16(Quellenangaben) generierten .mat Dateien kann das vom selben Projekt mitgelieferte Skript visualize.py verwendet werden, das die GUI-Bibliothek vtk verwendet.

Nach Aufruf des Skripts mit dem folgenden Befehl wird ein interaktiver 3D-Viewer gestartet:

python /root/3dgan/visualization/python/visualize.py /root/3dgan/output/chair_demo.mat -u 0.9 -t 0.1 -i 1 -mc 2
Chair Chair Chair
chair1 chair2 chair3
chair1 chair2 chair3

5.2) Visualisierung von .npy 3D-Objekten mit MeshLab

Für die Visualisierung der 3D-Objekte/Voxel-Dateien im Ordner Savepoints kann ein mitgeliefertes Skript verwendet werden:

cd scripts && python visualize.py /root/3dIWGAN/3D-Generation/savepoint/trainedChairs/1495.npy

Für dieses muss zuvor das 3D-Viewer-Programm MeshLab installiert werden, beispielsweise mit apt install meshlab. Bei jedem Fenster-Schließen des 3D Viewers wird das nächste der 256 Samples geöffnet. Diese Schleife kann durch beenden des Prozesses im Docker-Container Terminal (STRG+C) beendet werden.

Von der interaktiven Visualisierung wurden zwei Videos erstellt:

Im Ordner lfm_coms/include befindet sich ein Skript, das nach dem Öffnen eines Objektes automatisiert einen Screenshot erstellt und das MeshLab Fenster schließt. Die so erstellten Screenshots sind für die Visualisierung als animiertes .gif Bild hilfreich.

python /root/visualize_screenshots.py "/root/coms4995-project/chairs/output/lfmTest_4200_intpol_2_4__interpolated_results.npy"

Die Screenshots werden im geteilten Ordner /root/share/screenshots gespeichert.

5.3) Visualisierung von .npy 3D-Objekten mit Blender

Die 3D-Grafiksuite Blender bietet im Gegensatz zu MeshLab eine umfangreiche Python-Schnittstelle an, die wir zur Generierung von automatisierten Visualisierungs-Videos der Interpolation nutzen können.

Die generierten 3D-Modelle (gespeichert in data.npy) können durch den Aufruf des folgenden im Rahmen dieser Arbeit ergänzten Python-Skripts durch Blender in die Blender-Szene importiert werden:

blender -b --python  blenderLoadNpy.py -- data.npy

Durch das Skript werden Keyframes für die Objekte angelegt, so dass alle 5 Frames das angezeigte Objekt versteckt und das nächste Objekt der Datei angezeigt wird. So können die einzelnen Schritte der Interpolation wie ein animiertes Gif angesehen werden. Der Parameter -b im Befehl gibt an, dass kein interaktives Blender-Fenster geöffnet werden soll, sondern direkt durch das Skript Kamera, Licht und Szene gesetzt sowie die Videoerstellung gestartet werden soll.

Im folgenden Video ist eine solche Animation dargestellt:

Blender Visualisierung partRotateChair3.mp4