Skip to content

Hvitbok om beste praksis for programvareutvikling innen dyp læring

Vi gratulerer Per John, medlem av Kepler-teamet vårt, med at artikkelen hans om «Best Practices for Software Development in a Deep Learning Environment» er blitt publisert på Towards Data Science. Towards Data Science er en plattform der tusenvis av mennesker kan utveksle ideer og utvide forståelsen av datavitenskap.

For enkelhets skyld følger det nedenfor en kopi av publikasjonen:

Programvareutvikling: beste praksis i et miljø for dyp læring

Deep learning-systemer brukes nå i stor utstrekning i mange miljøer. De skiller seg fra tradisjonelle programvaresystemer når det gjelder måten utdata genereres på: beslutningene som tas for å produsere resultater, læres fra treningsdata, i stedet for å være håndkodet, slik tilfellet er med tradisjonelle programvaresystemer.

Dette har ført til at folk feilaktig tror at programvareutvikling ikke er like nødvendig for maskinlæringssystemer, siden algoritmene – som utgjør kjernen i ethvert omfattende system – læres av systemet selv. Videre utvikler den nyeste teknologien innen maskinlæring (ML) seg så raskt at dataforskere hovedsakelig fokuserer på kortsiktige mål som modellpresisjon. Siden verdenen innen dyp læring vil ha forandret seg i løpet av få måneder, hvorfor kaste bort tid på å utvikle systemet ditt ordentlig i dag? For tiden er situasjonen innen dyp læringsutvikling slik at man eksperimenterer med et system inntil et bestemt presisjonsmål er oppnådd, for deretter å sette det i produksjon.

Selv om denne metoden for å utvikle et maskinlæringssystem skiller seg fra tradisjonelle systemer, er den skadelig av flere grunner:

    • Det er lett å gjøre en feil, noe som kan føre til feilaktig presisjon. For eksempel på grunn av en feil ved innlasting eller transformering av data, eller feil håndtering av trenings-, test- og valideringssett.
    • Det er tidkrevende å gjenskape treningsresultater, siden dataene og konfigurasjonen som brukes ofte ikke er dokumentert og ikke versjonert.
    • Det er vanskelig å kjøre ML-modellen i et produksjonsmiljø, siden systemet kun er testet i et dårlig dokumentert utviklingsmiljø.
    • Det er også vanskelig å tilpasse ML-systemet til endrede krav, siden vedlikeholdbarheten av kodebasen ikke var et fokusområde, og systemet mangler automatiserte tester.

Gitt disse utfordringene, hvordan utvikler man dyp læringssystemer samtidig som man unngår de skadelige effektene av engangskoding og eksperimentering? I denne artikkelen deler vi de beste praksisene som er utviklet og tatt i bruk hos Kepler Vision Technologies. Disse metodene er solid forankret i moderne programvareutviklingspraksis og tar hensyn til de spesielle forholdene ved utvikling av maskinlæringssystemer. Så hva er det som er spesielt ved utvikling av dyp læringssystemer, sammenlignet med tradisjonelle systemer?

Foto av Shane Rounce på Unsplash

Særtrekkene ved utvikling av dyp læring

I dette avsnittet redegjør vi for de aspektene ved deep learning-utvikling som utgjør store hindringer for å ta i bruk beste praksis fra tradisjonell programvareutvikling. I det påfølgende avsnittet presenterer vi tiltakene vi har iverksatt for å gjøre vår utviklingsprosess for deep learning mer robust og effektiv, og dermed overvinne (en del av) hindringene som er nevnt her.

1. Raskt utviklende rammeverk for dyp læring
Ved begynnelsen av den dype læringsrevolusjonen ble modeller bygget basert på lavnivåbiblioteker. En tid senere begynte spesialiserte biblioteker å dukke opp for å hjelpe ML-ingeniører, særlig med lanseringen av Caffe-biblioteket, grunnlagt i 2013. Tre år senere hadde en mengde andre dype læringsbiblioteker dukket opp. Blar vi frem til i dag, fortsetter antallet forskjellige biblioteker å øke, selv om en gruppe ledende frontløpere har dannet seg. Foruten fødselen av nye individuelle biblioteker, må hvert bibliotek i seg selv stadig gjennomgå rask utvikling ettersom de prøver å holde tritt med ny utvikling innen forskning på nevrale nettverk.

2. Datahåndtering
Et viktig kjennetegn ved dyp læringssystemer er at mengden inndata er mye større, og at størrelsen på hvert enkelt dataelement også er større, sammenlignet med tradisjonelle programvaresystemer. Dette gjelder særlig i treningsfasen, hvor datamengden som brukes ofte er svært omfattende. Selv om det også er sant at datalagre som administreres av tradisjonelle programvaresystemer kan bli enorme i størrelse, kan disse systemene likevel kjøres og testes ved å bruke bare en brøkdel av de tilgjengelige dataene. Trening av et dyp læringssystem kan derimot aldri lykkes uten at enorme datamengder tas i bruk.

3. Konfigurasjonshåndtering
Å håndtere konfigurasjonsdata er en intrikat kunst innen programvareutvikling, og beste praksis er at konfigurasjonsdata versjoneres på en slik måte at det er tydelig hvilke konfigurasjonsdata som tilhører hvilken versjon av kildekoden. Denne beste praksisen gjelder også for maskinlæringssystemer, men er fortsatt vanskelig å implementere, ettersom størrelsen på konfigurasjonsdataene er så stor sammenlignet med tradisjonelle systemer. Tross alt er vekten av et trent nevralt nettverk konfigurasjonsdata og kan lett måle seg opp til totalt 1 GB.

De såkalte hyperparametrene som brukes ved trening av en dyp læringsmodell, er også konfigurasjonsdata og må håndteres som sådan. Det viser seg at disse hyperparametrene ofte er spredt rundt i koden, og at de er innstilt på en slik måte at presisjonsmålet kan oppnås.

4. Testing av dyp læringssystemer
Testautomatisering er i dag utbredt i programvareutvikling. Innen dyp læring er testautomatisering imidlertid ikke i nærheten av å være like utbredt. Det er to årsaker til dette: For det første har utviklere innen dyp læring ikke tilstrekkelig opplæring i moderne programvareutviklingspraksis, og for det andre krever utviklingen av en dyp læringsmodell mye eksperimentering.

I tillegg er opplæring av et dyp læringssystem en ikke-deterministisk prosess. Dette gjør automatisert testing av opplæringsprosessen vanskeligere, siden enkle sjekker av opplæringsresultatene ikke vil være tilstrekkelig. Tar man hensyn til de lange opplæringstidene, er det lett å forstå hvorfor de fleste ingeniører innen dyp læring velger å ikke bruke automatisert testing.

Automatisert testing av inferens er enklere. Når en modell først er trent, gjenstår det bare små mengder ikke-determinisme på grunn av avrundingsfeil.

5. Implementering av dyp læringssystemer
To sentrale trekk skiller implementering av dyp læringssystemer fra tradisjonelle systemer: For det første trenger de fleste dyp læringssystemer spesiell maskinvare, en GPU, for å kjøre med tilstrekkelig gjennomstrømning. For det andre krever dyp læringssystemer en stor konfigurasjonsfil, vektfilen, for å kunne foreta prediksjoner. Dette gjør det vanskeligere å oppnå «dev/prod-paritet», det vil si et likt miljø for utvikling og testing. Videre er det uklokt å pakke vektfilen sammen med kildekoden i én distribusjonspakke på grunn av størrelsen. Dette medfører at du må distribuere vektfiler og systemet ved hjelp av separate artefakter, samtidig som du holder dem synkronisert.

Vår tilnærming til utvikling av dyp læringssystemer

Vår tilnærming bygger på det grunnleggende prinsippet om at opplæring og drift av et dyp læringssystem bør automatiseres i størst mulig grad. Det bør ikke være avhengig av at en enkelt person må trene og evaluere modellen etter flere ukers eksperimentering.

Bruk av kontinuerlig integrasjon til å bygge Docker-bilder
Vi bruker Docker til å definere utviklings- og kjøremiljøet for våre dyp læringssystemer. Når vi legger ut endringer i versjonskontrollsystemet vårt – i vårt tilfelle GitHub – trer Travis i kraft og kjører tester, og hvis disse er vellykkede, vil det deretter bygge de nyeste Docker-bildene og legge dem ut i Docker-repositoriet. Docker-bildene vil ikke inneholde modellen, da dette ville gjort dem for store til å kunne distribueres enkelt.

Ved å bruke Docker sikres kjøringsmiljøet sammen med koden, og det er mulig å distribuere og kjøre systemet på en pålitelig måte i ethvert miljø som støtter Docker, uavhengig av hvilket deep learning-rammeverk som brukes.

Foto av elCarito på Unsplash

Å prioritere skyen
Vi streber etter at modellene våre skal trenes og evalueres på en instans i skyen (vi bruker Amazon AWS), siden dette skiller plattformdetaljene fra driften av systemet vårt. Docker-bilde-tilnærmingen beskrevet ovenfor, sammen med Amazon AWS, passer perfekt sammen for å oppnå denne abstraksjonen.

Lagring av data på et sentralt sted
Datahåndtering er en integrert del av deep learning-systemer. Vi lagrer data og annotasjoner i et sentralt arkiv (AWS S3-bøtter) og bruker skript for å synkronisere data lokalt, slik at våre applikasjoner, jobber og utviklere har tilgang til de nyeste dataene. Jobber kjører alltid med rene kopier av data, og vi anser tiden det tar å laste ned dataene som vel anvendt; dette gir oss sikkerhet for at de riktige trenings- og testdataene blir brukt.

Lagring av vektfiler på et sentralt sted
Vi lagrer vektfiler på et sentralt sted og henter dem inn om nødvendig for å starte en inferenseringsserver eller en evalueringsjobb. Vektfilene oppdateres når en treningsjobb har produsert en forbedret versjon av modellen. Sentral lagring av vektfiler sikrer at jobber og utviklere har enkel tilgang til den nyeste modellen.

Feil i konfigurasjonen av hyperparametere på et sentralt sted
Vi lagrer (endringer i) hyperparametere som brukes til trening og evaluering i en konfigurasjonsfil. Dette hindrer at disse parametrene blir spredt utover kildekoden. Vi bruker et sentralt sted til å lagre disse konfigurasjonsfilene, slik at de er tilgjengelige for jobber og utviklere.

Jenkins-opplæringsoppgave

Konsolidering av trening og evaluering i jobber
Vi konsoliderer trening og evaluering i jobber ved hjelp av automatiseringsserveren Jenkins. Jobbene henter inn de nyeste Docker-bildene, samt dataene og annotasjonene, og kjører opplæring eller evaluering inne i en Docker-container. Docker-containeren har tilknyttede volumer som peker til dataene, annotasjonene og modellfilen i tilfelle evaluering.

Når en treningsøkt er fullført, vil det bli generert en vektfil som kan lagres, forutsatt at den oppfyller modellens KPI-er.

Denne oppgaven vil samle all nødvendig kunnskap og data i skript, slik at hvem som helst vil kunne trene eller evaluere en modell på en pålitelig måte, uten å måtte forstå modellens finesser.

Vi arkiverer imidlertid annotasjonsfilene, konfigurasjonsfilene og de genererte vektfilene, slik at resultatene fra en jobb kan reproduseres.

Bruk av PyCharms funksjoner for ekstern utvikling
Det er mer produktivt når utviklere kan bruke et integrert utviklingsmiljø (IDE). Noen ganger kan det være nødvendig for utviklere å teste og feilsøke kildekoden og modellen på en GPU, som ofte ikke er tilgjengelig direkte på utviklingsmaskinen deres. En måte å kombinere bruk av et IDE med å kjøre koden på en GPU er å starte en Docker-container på en maskin med en GPU og deretter bruke PyCharms funksjoner for å kjøre en ekstern tolk. En ekstern tolk reduserer rundturstiden betydelig sammenlignet med å laste opp kildekoden til en ekstern server og legge til loggingsuttrykk for feilsøking.

Bruk av testautomatiserings
Som forklart ovenfor er det vanskeligere å skrive effektive og effektive automatiserte tester for dyp læringssystemer enn for tradisjonelle programvaresystemer. Vi skriver riktignok automatiserte tester for dyp læringssystemer ved hjelp av pytest-rammeverket, men ikke i like stor utstrekning som vi ville gjort for tradisjonelle programvaresystemer.

Vi fokuserer på å teste datainput og viktige algoritmer. Vi skriver også tester for trening og evaluering, men bare i den grad at koden skal kjøre problemfritt. Vi sjekker ikke om en fullstendig treningsrunde gir de riktige resultatene, da dette ville være for tidkrevende. I stedet skriver vi en automatisert test som kjører én eller to epoker på et svært lite datasett, og deretter sjekker vi at utdatametrikker genereres, men vi verifiserer ikke verdiene deres.

Resultatet av vårt arbeid med testautomatisering er at kodebasen vår er lettere å forstå, og at det krever mindre innsats å gjennomføre endringer.

Måling av vedlikeholdbarhetsmetrikker
Et programvaresystem må vedlikeholdes for å kunne tilpasses endrede krav og miljøer, og et dyp læringssystem er intet unntak. Jo mer vedlikeholdbart et system er, desto enklere blir det å endre og utvide det. Vi bruker bettercodehub.com til å sjekke 10 retningslinjer for programvareutvikling og til å varsle oss når et system avviker fra retningslinjene. Vi foretrekker dette verktøyet fremfor verktøy for kodesbrudd, siden det lar oss fokusere på de viktige retningslinjene for vedlikeholdbarhet, i stedet for å måtte håndtere enorme mengder brudd som et verktøy som PyLint vil rapportere.

Konklusjon
. Dyp læring er et relativt nytt tilskudd til organisasjonenes IT-verktøykasse. Det har delvis sine røtter i tradisjonell programvareutvikling og delvis i datavitenskap. Med tanke på at dyp læring fortsatt er i sin spede begynnelse, er det ikke overraskende at det ennå ikke er etablert standardiserte utviklingspraksiser. Utviklingen av dyp læringsprogramvare er imidlertid en integrert del av programvareutviklingen, og vi må hente inspirasjon fra prinsippene for moderne programvareutvikling som utgangspunkt for å forbedre programvareutviklingen innen dyp læring.

De ovennevnte metodene har gjort utviklingsprosessen vår for dyp læringsmodeller mer robust og repeterbar, og har skapt et felles grunnlag for samarbeid mellom fagfolk innen dyp læring og programvareingeniører. Prosessen er ikke perfekt, slik ingen prosess er, og vi søker kontinuerlig etter måter å forbedre våre nåværende arbeidsmetoder på.

Takk til Rob van der Leek.