Fo­to's scha­len met Ten­sorFlow

Af­beel­din­gen scha­len met neu­ra­le net­wer­ken en Ten­sorFlow

C’t Magazine - - Inhoud - Jo­han­nes Mer­kert

Goog­les bi­bli­o­theek Ten­sorFlow is een uni­ver­se­le tool om met neu­ra­le net­wer­ken te ex­pe­ri­men­te­ren. We heb­ben die ge­bruikt om een net­werk te le­ren hoe het de re­so­lu­tie van fo­to’s kan ver­be­te­ren. Om­dat het net­werk vor­men in de af­beel­ding her­kent en ont­bre­ken­de pixels toe­voegt, maakt het fo­to’s zicht­baar scher­per dan de stan­daard­scha­ling van fo­to­be­wer­kings­pro­gram­ma’s.

Neu­ra­le net­wer­ken draai­en meest­al in de cloud, maar toch kun je er zelf mee ex­pe­ri­men­te­ren. De soft­wa­re die je er­voor no­dig hebt, is opens­our­ce en draait op dood­nor­ma­le com­pu­ters. Zelfle­ren­de fra­me­works zo­als The­a­no, Ten­sorFlow, Torch 7 en Caf­fe ge­brui­ken daar twee ver­schil­len­de me­tho­des voor. Bij de me­tho­de 'ge­con­tro­leerd le­ren' wor­den voor­af ge­de­fi­ni­eer­de neu­ro­nen­la­gen met sy­nap­sen met el­kaar ver­bon­den. Het net­werk krijgt voor­beel­den van in­voer en de bij­be­ho­ren­de uit­voer, waar­bij het al­go­rit­me leert hoe de ei­gen­schap­pen van de in­voer be­pa­lend zijn voor de uit­voer. De ont­wik­ke­laar be­paalt in de co­de hoe de neu­ro­nen­ac­ti­vi­teit (for­ward pass) als­me­de de af­ge­lei­de (bac­k­ward pass) be­re­kend moe­ten wor­den. Na de leer­ of trai­nings­fa­se kan het al­go­rit­me voor nieu­we in­voer dan zelf­stan­dig de juis­te uit­voer pro­du­ce­ren. De me­tho­de 'on­ge­con­tro­leerd le­ren' is flexi­be­ler. De ont­wik­ke­laar geeft daar nog wel voor­beel­den van de in­voer, maar niet van de ge­wens­te uit­voer. Het al­go­rit­me ont­dekt dan zelf een struc­tuur in de ge­ge­ven in­voer. De ont­wik­ke­laar de­fi­ni­eert nog wel een for­ward pass, maar de af­ge­lei­de wordt au­to­ma­tisch be­re­kend.

Om­dat Goog­les Ten­sorFlow vol­gens de twee­de me­tho­de werkt, kun je er al­ler­lei ex­pe­ri­men­ten met neu­ra­le net­wer­ken mee uit­voe­ren. In prin­ci­pe is het fra­me­work ge­schikt voor elk pro­bleem waar­bij een op­ti­ma­li­sa­tie­al­go­rit­me op ba­sis van trai­nings­da­ta au­to­ma­tisch de pa­ra­me­ters van een for­mu­le be­re­kent.

In Ten­sorFlow de­fi­ni­eer je de for­mu­les als nor­ma­le bron­co­de. Het fra­me­work heeft bin­dings voor de pro­gram­meer­ta­len Py­thon, Go en Ja­va. We heb­ben de Py­thon­API ge­bruikt om­dat die al­le func­ties on­der­steunt en om­dat die op GitHub met af­stand het vaakst voor Ten­sorFlow­pro­jec­ten wordt in­ge­zet. De Py­thon­co­de

x = (a + b) / c

zorgt er zo­als ge­brui­ke­lijk voor dat in x de som van a en b ge­deeld door c staat. In nor­ma­le Py­thon­co­de moet je eerst waar­den aan de va­ri­a­be­len a, b en c toe­ken­nen voor­dat de in­ter­pre­ter x kan be­re­ke­nen. Bij Ten­sorFlow de­fi­ni­eer je va­ri­a­be­len ech­ter als Va­ria­ble­of pla­ce­hol­der­ob­jec­ten die aan­van­ke­lijk geen waar­den heb­ben. Pla­ce­hol­ders zijn er voor het op­slaan van in­voer­da­ta, ter­wijl Va­ria­ble­ob­jec­ten met waar­den ge­ï­ni­ti­a­li­seerd wor­den die door op­ti­ma­li­sa­tie­al­go­rit­mes aan­ge­past kun­nen wor­den.

Ten­sorFlow volgt wat er met zijn va­ri­a­be­len ge­beurt en bouwt in­tern een graaf op die de for­mu­le re­pre­sen­teert. De kno­pen van de graaf zijn ten­so­ren, of­te­wel mul­ti­di­men­si­o­na­le ar­rays, en de lij­nen daar­tus­sen zijn de be­re­ke­nin­gen. Met die graaf op­ti­ma­li­seert het fra­me­work de for­mu­le zo goed mo­ge­lijk zon­der spe­ci­fie­ke waar­den te ge­brui­ken. Op­ti­ma­li­sa­tie­al­go­rit­men zo­als de sto­chas­ti­sche gra­dient­des­cent brei­den de graaf zelf­stan­dig uit. Om dit ef­fi­ci­ënt te doen heb­ben ze een fit­ness­func­tie voor de af­ge­lei­de no­dig. Ten­sorFlow be­re­kent die au­to­ma­tisch.

Om met spe­ci­fie­ke waar­den te re­ke­nen, maak je een Ten­sorFlow­Ses­si­on aan en roep je de me­tho­de run() aan. Je geeft run() een lijst met de sym­bo­li­sche va­ri­a­be­len mee die je wilt be­re­ke­nen, bij­voor­beeld x uit de for­mu­le hier­bo­ven, en een dic­ti­o­na­ry met de va­ri­a­be­le­na­men en de waar­den die Ten­sorFlow in de for­mu­le moet ge­brui­ken. De com­ple­te co­de om x te be­re­ke­nen voor a=2, b=3 en c=4, ziet er dan zo uit: im­port ten­sorflow as tf a = tf.pla­ce­hol­der(tf.flo­at32) b = tf.pla­ce­hol­der(tf.flo­at32) c = tf.pla­ce­hol­der(tf.flo­at32) x =(a + b)/c sess = tf.Ses­si­on() re­sult = sess.run([x], {

a: 2, b: 3, c:4

}) print(re­sult) # 1.25

Net­wer­ken bou­wen

Wan­neer je een neu­raal net­werk bouwt, be­gin je met het voor­be­rei­den van de in­voer­ge­ge­vens. Dat moe­ten flo­a­ting­point­ge­tal­len tus­sen 0 en 1 zijn. Bij klas­sie­ke ma­chi­ne­le­arning zou je een vec­tor be­re­ke­nen van de meest ken­mer­ken­de ei­gen­schap­pen. Voor ge­zichts­her­ken­ning zou­den dat bij­voor­beeld de af­stand tus­sen de ogen, de leng­te van de neus en de breed­te van de mond en der­ge­lij­ke zijn. Voor het ex­tra­he­ren van die ge­ge­vens is ech­ter veel met de hand ge­schre­ven co­de no­dig. Daar ligt de kracht van die­pe neu­ra­le net­wer­ken. Die kun­nen meteen over­weg met ge­stan­daar­di­seer­de in­voer­ge­ge­vens en le­ren op hun die­pe­re la­gen wel­ke ei­gen­schap­pen re­le­vant zijn voor de ge­wens­te out­put. Net als bij klas­sie­ke ma­chi­ne­le­arning trek­ken ze op de bo­ven­ste la­gen dan con­clu­sies.

Voor het scha­len van fo­to’s moet het neu­ra­le net­werk daar­om uit di­ver­se neu­ro­nen­la­gen be­staan die vor­men her­ken­nen. De in­voer­da­ta zijn een vier­di­men­si­o­na­le ten­sor: batch­groot­te × fo­to­breed­te × fo­to­hoog­te × drie kleur­ka­na­len.

In ons voor­beeld be­staat een batch tel­kens uit vijf af­beel­din­gen. Om de ten­sor te nor­ma­li­se­ren, is het vol­doen­de dat je de in­te­ger­kleur­waar­den van de pixels deelt door 256 en de re­sul­te­ren­de flo­a­ting­point­ge­tal­len ge­bruikt. De be­re­ke­nin­gen in de ver­bor­gen la­gen van het net­werk hou­den re­ke­ning met na­bu­ri­ge pixels, maar ken­nen elk neu­ron op de in­put­laag aan een neu­ron op de out­put­laag toe. Het net­werk kan dus niet de re­so­lu­tie ver­ho­gen, maar een wa­zi­ge fo­to wel scher­per ma­ken. Als voor­be­rei­ding daar­op schaalt de co­de de ori­gi­ne­le af­beel­ding eerst bi­cu­bisch.

re­si­zed = tf.ima­ge.re­si­ze_­bi­cu­bic(

in­puts / 256.0,[480, 640])

Op de hoog­ste laag moe­ten de neu­ro­nen zo 'vu­ren' dat er een scher­pe af­beel­ding met de ge­schaal­de re­so­lu­tie ont­staat. Om­dat daar ge­tal­len tus­sen 0 en 1 ont­staan, moet de ten­sor weer met 256 ver­me­nig­vul­digd en op ge­he­le ge­tal­len af­ge­rond wor­den om een af­beel­ding te ma­ken.

Net­werk­la­gen

De een­vou­dig­ste laag van een neu­raal net­werk be­staat uit neu­ro­nen die een sy­naps (ver­bin­ding) naar elk neu­ron op de daar­on­der lig­gen­de laag heb­ben (een zo­ge­he­ten ful­ly con­nec­ted lay­er). Voor een fo­to zou dat be­te­ke­nen dat het net­werk el­ke vorm en elk pa­troon voor el­ke po­si­tie in de af­

Newspapers in Dutch

Newspapers from Netherlands

© PressReader. All rights reserved.