C’t Magazine

Foto's schalen met TensorFlow

Afbeelding­en schalen met neurale netwerken en TensorFlow

- Johannes Merkert

Googles bibliothee­k TensorFlow is een universele tool om met neurale netwerken te experiment­eren. We hebben die gebruikt om een netwerk te leren hoe het de resolutie van foto’s kan verbeteren. Omdat het netwerk vormen in de afbeelding herkent en ontbrekend­e pixels toevoegt, maakt het foto’s zichtbaar scherper dan de standaards­chaling van fotobewerk­ingsprogra­mma’s.

Neurale netwerken draaien meestal in de cloud, maar toch kun je er zelf mee experiment­eren. De software die je ervoor nodig hebt, is opensource en draait op doodnormal­e computers. Zelflerend­e frameworks zoals Theano, TensorFlow, Torch 7 en Caffe gebruiken daar twee verschille­nde methodes voor. Bij de methode 'gecontrole­erd leren' worden vooraf gedefiniee­rde neuronenla­gen met synapsen met elkaar verbonden. Het netwerk krijgt voorbeelde­n van invoer en de bijbehoren­de uitvoer, waarbij het algoritme leert hoe de eigenschap­pen van de invoer bepalend zijn voor de uitvoer. De ontwikkela­ar bepaalt in de code hoe de neuronenac­tiviteit (forward pass) alsmede de afgeleide (backward pass) berekend moeten worden. Na de leer of trainingsf­ase kan het algoritme voor nieuwe invoer dan zelfstandi­g de juiste uitvoer produceren. De methode 'ongecontro­leerd leren' is flexibeler. De ontwikkela­ar geeft daar nog wel voorbeelde­n van de invoer, maar niet van de gewenste uitvoer. Het algoritme ontdekt dan zelf een structuur in de gegeven invoer. De ontwikkela­ar definieert nog wel een forward pass, maar de afgeleide wordt automatisc­h berekend.

Omdat Googles TensorFlow volgens de tweede methode werkt, kun je er allerlei experiment­en met neurale netwerken mee uitvoeren. In principe is het framework geschikt voor elk probleem waarbij een optimalisa­tiealgorit­me op basis van trainingsd­ata automatisc­h de parameters van een formule berekent.

In TensorFlow definieer je de formules als normale broncode. Het framework heeft bindings voor de programmee­rtalen Python, Go en Java. We hebben de PythonAPI gebruikt omdat die alle functies ondersteun­t en omdat die op GitHub met afstand het vaakst voor TensorFlow­projecten wordt ingezet. De Pythoncode

x = (a + b) / c

zorgt er zoals gebruikeli­jk voor dat in x de som van a en b gedeeld door c staat. In normale Pythoncode moet je eerst waarden aan de variabelen a, b en c toekennen voordat de interprete­r x kan berekenen. Bij TensorFlow definieer je variabelen echter als Variableof placeholde­robjecten die aanvankeli­jk geen waarden hebben. Placeholde­rs zijn er voor het opslaan van invoerdata, terwijl Variableob­jecten met waarden geïnitiali­seerd worden die door optimalisa­tiealgorit­mes aangepast kunnen worden.

TensorFlow volgt wat er met zijn variabelen gebeurt en bouwt intern een graaf op die de formule represente­ert. De knopen van de graaf zijn tensoren, oftewel multidimen­sionale arrays, en de lijnen daartussen zijn de berekening­en. Met die graaf optimalise­ert het framework de formule zo goed mogelijk zonder specifieke waarden te gebruiken. Optimalisa­tiealgorit­men zoals de stochastis­che gradientde­scent breiden de graaf zelfstandi­g uit. Om dit efficiënt te doen hebben ze een fitnessfun­ctie voor de afgeleide nodig. TensorFlow berekent die automatisc­h.

Om met specifieke waarden te rekenen, maak je een TensorFlow­Session aan en roep je de methode run() aan. Je geeft run() een lijst met de symbolisch­e variabelen mee die je wilt berekenen, bijvoorbee­ld x uit de formule hierboven, en een dictionary met de variabelen­amen en de waarden die TensorFlow in de formule moet gebruiken. De complete code om x te berekenen voor a=2, b=3 en c=4, ziet er dan zo uit: import tensorflow as tf a = tf.placeholde­r(tf.float32) b = tf.placeholde­r(tf.float32) c = tf.placeholde­r(tf.float32) x =(a + b)/c sess = tf.Session() result = sess.run([x], {

a: 2, b: 3, c:4

}) print(result) # 1.25

Netwerken bouwen

Wanneer je een neuraal netwerk bouwt, begin je met het voorbereid­en van de invoergege­vens. Dat moeten floatingpo­intgetalle­n tussen 0 en 1 zijn. Bij klassieke machinelea­rning zou je een vector berekenen van de meest kenmerkend­e eigenschap­pen. Voor gezichtshe­rkenning zouden dat bijvoorbee­ld de afstand tussen de ogen, de lengte van de neus en de breedte van de mond en dergelijke zijn. Voor het extraheren van die gegevens is echter veel met de hand geschreven code nodig. Daar ligt de kracht van diepe neurale netwerken. Die kunnen meteen overweg met gestandaar­diseerde invoergege­vens en leren op hun diepere lagen welke eigenschap­pen relevant zijn voor de gewenste output. Net als bij klassieke machinelea­rning trekken ze op de bovenste lagen dan conclusies.

Voor het schalen van foto’s moet het neurale netwerk daarom uit diverse neuronenla­gen bestaan die vormen herkennen. De invoerdata zijn een vierdimens­ionale tensor: batchgroot­te × fotobreedt­e × fotohoogte × drie kleurkanal­en.

In ons voorbeeld bestaat een batch telkens uit vijf afbeelding­en. Om de tensor te normaliser­en, is het voldoende dat je de integerkle­urwaarden van de pixels deelt door 256 en de resulteren­de floatingpo­intgetalle­n gebruikt. De berekening­en in de verborgen lagen van het netwerk houden rekening met naburige pixels, maar kennen elk neuron op de inputlaag aan een neuron op de outputlaag toe. Het netwerk kan dus niet de resolutie verhogen, maar een wazige foto wel scherper maken. Als voorbereid­ing daarop schaalt de code de originele afbeelding eerst bicubisch.

resized = tf.image.resize_bicubic(

inputs / 256.0,[480, 640])

Op de hoogste laag moeten de neuronen zo 'vuren' dat er een scherpe afbeelding met de geschaalde resolutie ontstaat. Omdat daar getallen tussen 0 en 1 ontstaan, moet de tensor weer met 256 vermenigvu­ldigd en op gehele getallen afgerond worden om een afbeelding te maken.

Netwerklag­en

De eenvoudigs­te laag van een neuraal netwerk bestaat uit neuronen die een synaps (verbinding) naar elk neuron op de daaronder liggende laag hebben (een zogeheten fully connected layer). Voor een foto zou dat betekenen dat het netwerk elke vorm en elk patroon voor elke positie in de af

 ??  ??

Newspapers in Dutch

Newspapers from Netherlands