Cursus
Elk machinelearningmodel dat je traint, lost een optimalisatieprobleem op — en wat je eigenlijk probeert op te lossen, heet de doelfunctie.
Simpel gezegd is het een wiskundige functie die meet hoe "goed" een oplossing is. Je geeft een set inputwaarden en krijgt één score terug. Het doel is altijd om de waarden te vinden die die score maximaliseren of minimaliseren. Doelfuncties vind je in de kern van alles, van lineaire programmering tot deep learning. Het is zoiets dat je overal terugziet zodra je begrijpt hoe het werkt.
In dit artikel leg ik uit wat doelfuncties zijn, hoe ze verschillen van verlies- en kostenfuncties, en hoe ze worden gebruikt in machine learning en optimalisatie.
Op zoek naar een deep dive in deep learning die in 2026 nog steeds relevant is? Schrijf je in voor onze Deep Learning in Python-cursus om een PyTorch-portfolio op te bouwen.
Wat is een doelfunctie?
Een doelfunctie is een wiskundige functie die beoordeelt hoe goed een oplossing is.
Je voert er een set inputs in — modelparameters, beslissingsvariabelen — en je krijgt één getal terug. Dat getal vertelt hoe goed je huidige oplossing presteert. Hoe hoger (of lager) dat getal, hoe beter (of slechter) je oplossing.
Nu we toch bezig zijn, laten we optimalisatie in het algemeen bespreken.
Het is het proces van het vinden van de inputs die dat getal de gewenste kant op duwen. Als je minimaliseert, wil je de kleinst mogelijke waarde. Als je maximaliseert, wil je de grootst mogelijke. Hoe dan ook, de doelfunctie is waar je tegen meet.
In gewone taal: zie het als een scoresysteem. Elke kandidaatoplossing krijgt een score, en jouw taak is de oplossing met de beste score te vinden.
Doelfunctie vs. verliesfunctie vs. kostenfunctie
Deze drie termen worden voortdurend door elkaar gebruikt — maar ze betekenen niet precies hetzelfde.
De doelfunctie is de breedste term. Het is elke functie die je probeert te maximaliseren of minimaliseren. Het hoeft helemaal niet over fouten of voorspellingen te gaan — het definieert gewoon wat "beter" betekent voor jouw probleem.
Een verliesfunctie meet de fout voor één trainingsvoorbeeld — hoe ver de voorspelling van je model afligt van de werkelijke waarde. De gemiddelde kwadratische fout voor één datapunt, bijvoorbeeld, is een verliesfunctie.
Een kostenfunctie aggregeert de verlieswaarde over je hele dataset, meestal door te middelen. De kostenfunctie is dus wat je tijdens training daadwerkelijk minimaliseert — ze vat de modelprestatie samen over alle voorbeelden, niet slechts één.
In de praktijk gebruiken de meeste ML-frameworks en papers deze termen losjes. Je ziet "loss" gebruikt waar "cost" preciezer zou zijn, en "objective" gebruikt als verzamelnaam voor alle drie.
De nuances doen ertoe wanneer je onderzoeksartikelen leest. De context vertelt welke van de drie de auteur daadwerkelijk bedoelt.
Voor een concretere vergelijking, zie de tabel hieronder:

Vergelijkingstabel doelfunctie/verlies/kosten
Doelfuncties in optimalisatie
Elk optimalisatieprobleem heeft een doel en een set beperkingen.
De doelfunctie definieert het doel — wat je probeert te maximaliseren of minimaliseren. De constraints definiëren de grenzen — de kaders waarbinnen je oplossing moet blijven. Samen kaderen ze het probleem.
Neem een eenvoudig voorbeeld van middelen toewijzen.
Stel, je runt een fabriek die twee producten maakt en je wilt de winst maximaliseren. Je doelfunctie vangt de totale winst als functie van hoeveel eenheden je van elk product maakt. Je constraints vangen de grenzen — beschikbare grondstoffen, machine-uren, arbeidscapaciteit. De doelfunctie vertelt wat je moet optimaliseren en de constraints waar je mee werkt.
Lineaire programmering is een van de meest voorkomende contexten waarin dit geldt. Het is een methode om een lineaire doelfunctie te optimaliseren onder lineaire constraints. Het wordt overal gebruikt, van logistiek, planning, supply chain tot finance. De wiskunde is goed begrepen en solvers kunnen problemen met duizenden variabelen aan.
Belangrijk om te onthouden: de doelfunctie verandert niet welke constraints er bestaan — ze vertelt de solver alleen waar die achteraan moet. Als je de doelfunctie verandert, krijg je een compleet andere oplossing, zelfs met dezelfde constraints.
Doelfuncties in machine learning
In machine learning bepaalt de doelfunctie wat je model daadwerkelijk leert te doen.
Elke keer dat je een model traint, draai je een optimalisatie-algoritme (denk aan gradient descent, Adam, RMSProp) dat modelparameters aanpast om de doelfunctie te minimaliseren of maximaliseren. Het model weet niets over je probleem. Het kent alleen de score die de doelfunctie geeft en probeert die score bij elke update te verbeteren.
Dat betekent dat je keuze van doelfunctie de uitkomst vormt. Het is een goed idee om er een paar te proberen en te zien welke het beste werkt voor jouw geval.
Mean squared error (regressie)
Mean Squared Error (MSE) is de standaarddoelfunctie voor regressieproblemen. Het meet het gemiddelde van de gekwadrateerde verschillen tussen de voorspellingen van je model en de werkelijke doelwaarden.

MSE-formule
Door de verschillen te kwadrateren worden alle fouten positief en worden grote fouten zwaarder bestraft dan kleine. Een voorspelling die 10 afwijkt, draagt 100 bij aan de som — niet slechts 10. Dat maakt MSE gevoelig voor uitschieters, iets om op te letten bij rommelige real-world data.
import numpy as np
y_true = np.array([3.0, 5.0, 2.5, 7.0])
y_pred = np.array([2.8, 5.2, 2.0, 6.5])
mse = np.mean((y_true - y_pred) ** 2)
print(f"MSE: {mse:.4f}")

MSE-uitvoer
Cross-entropy loss (classificatie)
Cross-entropy loss is de standaarddoelfunctie voor classificatieproblemen. Het meet hoe ver de voorspelde waarschijnlijkheidsverdeling van je model afwijkt van de werkelijke klassenverdeling.

Cross-entropy-verliesfunctie
Als je model een hoge waarschijnlijkheid toekent aan de juiste klasse, is het verlies laag. Als het zelfverzekerd maar fout zit, is het verlies hoog en wordt dat bestraft. Dit duwt het model ertoe de juiste klasse te voorspellen én daar zeker van te zijn.
import numpy as np
# True labels (one-hot encoded)
y_true = np.array([1, 0, 0])
# Model's predicted probabilities
y_pred = np.array([0.7, 0.2, 0.1])
cross_entropy = -np.sum(y_true * np.log(y_pred))
print(f"Cross-Entropy Loss: {cross_entropy:.4f}")

Cross-entropy-uitvoer
Log-likelihood
Log-likelihood is gangbaar in probabilistische en statistische modellen. De functie maximaliseert de kans dat de parameters van je model de geobserveerde data hebben voortgebracht.

Log-likelihood-formule
Je werkt met de log van de likelihood in plaats van de likelihood zelf, omdat dat een product van kansen omzet in een som, wat veel makkelijker te berekenen en optimaliseren is.
In de praktijk minimaliseren de meeste frameworks de negatieve log-likelihood (NLL) in plaats van de log-likelihood te maximaliseren. Het is hetzelfde — alleen omgedraaid zodat gradient descent ermee kan werken.
import numpy as np
from scipy.stats import norm
# Observed data
data = np.array([1.2, 2.3, 1.8, 2.1, 1.9])
# Assumed model parameters
mu, sigma = 2.0, 0.5
# Compute negative log-likelihood
nll = -np.sum(norm.logpdf(data, loc=mu, scale=sigma))
print(f"Negative Log-Likelihood: {nll:.4f}")

Log-likelihood-uitvoer
Training is in de kern gewoon optimalisatie. Elke forward pass berekent de waarde van de doelfunctie. Elke backward pass berekent gradiënten. En elke parameterupdate beweegt het model in de richting die de score verbetert.
Convexe vs. niet-convexe doelfuncties
Niet alle doelfuncties zijn gelijk. Hun vorm bepaalt hoe moeilijk ze te optimaliseren zijn en of je de gevonden oplossing kunt vertrouwen.
Lineaire doelfuncties
Een lineaire doelfunctie geeft een rechtlijnige relatie tussen inputs en output. Als je een input met een vaste hoeveelheid verandert, verandert de output ook met een vaste hoeveelheid.
Lineaire functies worden gebruikt in lineaire programmering, waar zowel de doelstelling als de constraints lineair zijn. Dit maakt ze de makkelijkste klasse doelfuncties om te optimaliseren, omdat solvers betrouwbaar het globale optimum kunnen vinden, zelfs voor grote problemen.
Niet-lineaire doelfuncties
Een niet-lineaire doelfunctie heeft een complexere relatie tussen inputs en output. De meeste real-world problemen — en bijna alle machinelearningmodellen — vallen in deze categorie.
MSE is niet-lineair. Cross-entropy is niet-lineair. Verliesoppervlakken van neurale netwerken zijn niet-lineair. De extra complexiteit laat deze functies complexe relaties in data vastleggen, maar maakt optimalisatie ook lastiger.
Convexe versus niet-convexe functies
Hier wordt het interessant.
Een convexe functie heeft een komvorm. Elk lijnstuk tussen twee punten op de kromme ligt boven of op de kromme. Dit garandeert dat elk lokaal minimum ook het globale minimum is — met andere woorden: als je optimizer een bodem vindt, is het de échte bodem.
Een niet-convexe functie heeft een onregelmatigere vorm — meerdere dalen, plateaus en zadelpunten. Optimizers kunnen vastlopen in een lokaal minimum, een dal dat op de bodem lijkt maar het niet is. Deep neural nets hebben sterk niet-convexe verliesoppervlakken, daarom vereist het trainen ervan zorgvuldige afstemming van learning rates, optimizers en initialisatie.
Convexe problemen worden exact opgelost, en niet-convexe problemen bij benadering. De kwaliteit van je oplossing hangt af van je optimalisatiestrategie.
Voor de visuele types, hier een vergelijking tussen lineaire, niet-lineaire, convexe en niet-convexe doelfuncties:

Vergelijking van typen doelfuncties
Hoe doelfuncties worden geoptimaliseerd
Zodra je een doelfunctie hebt, heb je een manier nodig om haar te minimaliseren of maximaliseren. Daar komen optimalisatie-algoritmen bij kijken.
De meest gangbare aanpak is gradient descent. Het idee is om de gradiënt van de doelfunctie te berekenen ten opzichte van de parameters van je model en dan een kleine stap te zetten in de richting die de waarde verlaagt. Vervolgens herhaal je dit totdat de waarde niet verder verbetert.
De gradiënt is simpelweg de afgeleide van de doelfunctie.
Die vertelt je de helling op je huidige positie en welke richting "bergop" is. Om de functie te minimaliseren, ga je de andere kant op. Om te maximaliseren, ga je met de helling mee.
Dit proces is iteratief: om bij de oplossing te komen, doe je een reeks kleine updates die de parameters steeds dichter bij het optimum brengen. De grootte van elke stap wordt bepaald door de learning rate. Een te grote waarde kan ertoe leiden dat je over het optimum heen schiet, en een te kleine maakt dat trainen langer duurt.
In de praktijk gebruiken de meeste ML-frameworks varianten van gradient descent die sneller en stabieler zijn dan de basisversie:
- Stochastic Gradient Descent (SGD) berekent de gradiënt per stap op één willekeurig voorbeeld in plaats van op de volledige dataset
- Mini-batch gradient descent gebruikt per stap een kleine batch voorbeelden — een middenweg tussen SGD en full-batch
- Adam past de learning rate per parameter aan, wat het makkelijker maakt om te tunen
De doelfunctie moet differentieerbaar zijn, of op z'n minst grotendeels differentieerbaar, om met gradiëntgebaseerde methoden te kunnen werken. Geen afgeleide betekent geen gradiënt, en dus heeft de optimizer niets om te volgen. Dat is iets cruciaals om te onthouden.
Voorbeeld van een doelfunctie
Laten we het concreet maken met een eenvoudig lineair regressieprobleem.
Stel, je voorspelt huizenprijzen op basis van woonoppervlak. Je hebt een dataset met bekende prijzen en je wilt een lijn door de data fitten die de voorspellingsfout minimaliseert. Je doelfunctie is Mean Squared Error (MSE), waarvan je de formule al kent.
De inputs zijn de parameters van je model — de helling en het intercept van de lijn. De output is één getal — de gemiddelde gekwadrateerde fout over alle voorspellingen. In dit geval geldt: lager is beter.
Zo zou een mogelijke Python-implementatie eruit kunnen zien:
import numpy as np
np.random.seed(42)
# Generate some fake housing data
square_footage = np.random.uniform(500, 3000, 100)
true_price = 150 * square_footage + 50000 + np.random.normal(0, 15000, 100)
def predict(x, slope, intercept):
return slope * x + intercept
def mse(y_true, y_pred):
return np.mean((y_true - y_pred) ** 2)
# Try two different parameter sets
slope_a, intercept_a = 150, 50000 # good fit
slope_b, intercept_b = 80, 100000 # bad fit
pred_a = predict(square_footage, slope_a, intercept_a)
pred_b = predict(square_footage, slope_b, intercept_b)
print(f"MSE (good fit): {mse(true_price, pred_a):,.2f}")
print(f"MSE (poor fit): {mse(true_price, pred_b):,.2f}")

MSE: goede versus slechte fit
De eerste parameterset levert een veel lagere MSE op, wat betekent dat hij beter bij de data past. Precies dat gebruikt de optimizer om te beslissen in welke richting hij moet bewegen.
Voor de visuele types, bekijk de volgende afbeelding:

MSE-voorbeeld
Je ziet beide fits tegen de data, en ook het MSE-oppervlak over een reeks hellingswaarden om de doelfunctie zelf te zien.
De linkerplot laat zien hoe de twee parametersets bij de data passen. De rechterplot toont het MSE-oppervlak over hellingswaarden — de doelfunctie als een curve, met een duidelijk minimum dat de optimizer probeert te vinden. Elke stap van gradient descent beweegt langs deze curve naar dat minimum.
Constraints en doelfuncties
Een doelfunctie vertelt wat je moet optimaliseren. Constraints vertellen wat je mag doen.
In de meeste echte problemen kun je niet zomaar maximaal of minimaal gaan. Je werkt binnen grenzen, zoals een budget, een tijdsvenster of een fysieke capaciteit. Deze grenzen heten constraints en ze definiëren de set geldige oplossingen waaruit je optimizer mag kiezen.
Neem een productievoorbeeld.
Stel dat je de winst over twee productlijnen wilt maximaliseren. Zonder constraints is het antwoord: produceer zoveel mogelijk. Maar je hebt 500 machine-uren en 1.000 eenheden grondstof beschikbaar. Dat zijn je constraints. De doelfunctie blijft hetzelfde (maximaliseer de winst), maar de optimizer kan alleen zoeken binnen de regio die deze constraints toelaten.
Als je de constraints verandert, verandert de optimale oplossing ook, zelfs als de doelfunctie dat niet doet.
Deze structuur van een doelfunctie met een set constraints vormt de basis van geconstrueerde optimalisatie. Zo werkt lineaire programmering, zo werkt portefeuille-optimalisatie, en zo worden veel realistische planningsproblemen geformuleerd.
Conclusie
Elk optimalisatieprobleem — of je nu een neuraal netwerk traint, middelen toewijst of een regressiemodel fit — komt neer op één ding: een functie die je probeert te minimaliseren of maximaliseren.
De doelfunctie is die functie. Ze definieert wat "beter" betekent, stuurt elke parameterupdate en bepaalt wat je model daadwerkelijk leert. Als je dit goed kiest, kan je model het probleem oplossen dat je hebt. Maar als je het verkeerd kiest, lost het een totaal ander probleem op — vaak zonder duidelijke foutmelding die je waarschuwt.
De juiste doelfunctie kiezen is een ontwerpkeuze in data science, omdat die alles wat volgt mede bepaalt. Als practitioner mag je gerust experimenteren — er zijn veel doelfuncties om uit te kiezen.
Weet je niet waar je moet beginnen? Onze cursussen Model Validation in Python en Hyperparameter Tuning in Python zijn allebei goede startpunten voor beginnende tot halfgevorderde data scientists.
Veelgestelde vragen
Wat is een doelfunctie?
Een doelfunctie is een wiskundige functie die meet hoe goed een oplossing is. Je voert er een set inputs in, zoals modelparameters en beslissingsvariabelen, en krijgt één getal terug. Het doel is altijd om de inputs te vinden die dat getal zo hoog of zo laag mogelijk maken.
Wat is het verschil tussen een doelfunctie en een verliesfunctie?
Een verliesfunctie is een specifiek type doelfunctie dat in machine learning wordt gebruikt om de voorspellingsfout voor één trainingsvoorbeeld te meten. De doelfunctie is de bredere term — die kan verwijzen naar elke functie die je minimaliseert of maximaliseert, niet alleen naar voorspelfout. In de praktijk worden de twee termen vaak door elkaar gebruikt, maar het onderscheid is belangrijk wanneer je onderzoeksartikelen leest.
Waar worden doelfuncties gebruikt?
Doelfuncties komen voor in elk probleem dat optimalisatie inhoudt — machine learning, lineaire programmering, middelenallocatie, finance, logistiek en meer. In machine learning bepaalt de doelfunctie wat het model tijdens training leert. Buiten ML definieert ze het doel in elk geconstraint of ongeconstraint optimalisatieprobleem.
Waarom is de keuze van de doelfunctie belangrijk in machine learning?
De doelfunctie bepaalt waar je model tijdens training daadwerkelijk op optimaliseert. Als je de verkeerde kiest, minimaliseert je model het verkeerde — en het doet dat ook nog eens goed, waardoor het probleem lastiger te ontdekken is. Gebruik je bijvoorbeeld MSE voor een classificatieprobleem, dan levert dat niet alleen slechte resultaten op, maar ook nog eens zelfverzekerd slechte resultaten — en dat is erger.
Kan een doelfunctie meerdere minima hebben?
Ja — en dit is een van de kernuitdagingen bij het trainen van deep-learningmodellen. Niet-convexe doelfuncties hebben meerdere minima, wat betekent dat een optimizer kan vastlopen in een dal dat niet het globale optimum is. Daarom zijn gewichtsinitialisatie, learning rate-scheduling en de keuze van optimizer zo belangrijk — ze beïnvloeden of je optimizer uiteindelijk een goede oplossing vindt.

