Dit netwerk werd getraind op de 5 eerste trainingsbeelden voor 50 epochs. In elk epoch werden alle beelden 1 keer doorgelopen. De trainingsbeelden werden opgedeeld in een lijst van sneden die dan als input gebruikt werden voor het netwerk. De batch size is 16. Dit betekent dat in elke stap willekeurig 16 sneden gekozen worden en de gewichten dan worden veranderd naargelang de verlies functie op deze 16 sneden. Deze sneden liggen niet per se naast elkaar en kunnen over meerdere volumes gekozen worden.
De verliesfunctie tijdens het trainen was cross entropy. Er werd een Adam optimizer gebruikt met een learning rate van $10^{-4}$. Dit verschilt van het netwerk op github (link) waar een learning rate van $10^{-5}$ gebruikt werd. Op deze manier kon ons netwerk sneller trainen.
De waarden voor enkele standaard metrieken tijdens het trainingsproces werden opgeslagen in een .json bestand. Deze metrieken zijn de accuracy en de verliesfunctie. Tijdens het trainen werden de sneden opgesplitst in sneden gebruikt voor training en sneden gebruikt voor validatie. Enkel deze voor training werden gebruikt om de parameters in het netwerk aan te passen. De validatie set wordt gebruikt om de verliesfunctie en nauwkeurigheid te evalueren. Als de nauwkeurigheid ten opzichte van de trainingsbeelden veel beter is dan deze van de validatie set, dan zou dit betekenen dat het netwerk aan het overfitten is. Dit betekent dat het netwerk de trainingsbeelden van buiten leert, maar daarom niet kan veralgemenen naar nieuwe beelden. Onderstaande plots tonen de accuracy en verliesfunctie voor zowel de testbeelden als de validatiebeelden.
from metrics import plot_metrics
jsonfile = 'trainedUnet2D #1.json'
plot_metrics(jsonfile)
We plotten nu de segmentaties van enkele sneden van testvolume 1. In de eerste afbeelding staat de segmentatie met het netwerk, in de tweede afbeelding de segmentatie van SPM die we als waarheid aannemen en op de derde afbeelding staat een slice van de 3D hersenscan die als input gebruikt werd. Bovendien worden de Dice scores voor elk weefsel gegeven voor de getoonde slice. De berekening van de totale Dice score houdt rekening met grijze stof, witte stof en CSF, maar niet met achtergrond.
import get_predictions
from get_predictions import load_predictions, plot_background, plot_predictions
Volume = 1 #from 1 to 14
modelname = "trainedUnet2D #1.h5"
loadname = "pred#1 - volume {}.npy".format(Volume)
predicting = False
isDiscrete = True
chanNumber = 3
load_predictions(loadname, Volume, predict = predicting)
for i in range(25,166,10):
print("\n Slice {} of volume {} \n".format(i,Volume))
slice_number = i #from 1 to 176
plot_predictions(Volume, slice_number, discrete = isDiscrete, channels = chanNumber, suptitle = False)
print('-'*30)
Voor volume 9 verkrijgen we opvallend slechte Dice scores. Bij nadere inspectie blijkt dat dit te wijten is aan de slechte kwaliteit van de hersenscan die als input gebruikt werd. De resultaten zijn hieronder geplot.
import get_predictions
from get_predictions import load_predictions, plot_background, plot_predictions
Volume = 9 #from 1 to 14
modelname = "trainedUnet2D #1.h5"
loadname = "pred#1 - volume {}.npy".format(Volume)
predicting = False
isDiscrete = True
chanNumber = 3
load_predictions(loadname, Volume, predict = predicting)
for i in range(25,100,5):
print("\n Slice {} of volume {} \n".format(i,Volume))
slice_number = i #from 1 to 176
plot_predictions(Volume, slice_number, discrete = isDiscrete, channels = chanNumber, suptitle = False)
print('-'*30)
Tot slot berekenen we ook de dice scores voor alle testvolumes. In de tabel zie je de dice scores voor elk volume. Onderaan is het gemiddelde genomen over de testbeelden. Zoals hierboven al gezegd was de kwaliteit van de hersenscan van volume 9 eerder slecht, daarom zullen we het ook buiten beschouwing laten bij het berekenen van de Dice scores. Bij volume 3 en 8 ging er iets mis bij het segmenteren van de afbeeldingen met SPM. Daarom werden ook deze volumes buiten beschouwing gelaten.
import numpy as np
from pandas import DataFrame
#volume 3 en 8 hebben een afwijkende ground truth en werden daarom buiten beschouwing gelaten
#volume 9 is hierboven besproken. Dit laten we ook buiten beschouwing.
sampleList = [1,2,4,5,6,7,10,11,12,13,14]
dice_scores = [np.load("diceTry1-volume{}.npy".format(i)) for i in sampleList]
dice_scores = np.array(dice_scores)
dice_mean = dice_scores.mean(axis = 0)
dice_scores = np.row_stack((dice_scores, dice_mean))
df = DataFrame(np.round(dice_scores,2),
index = ['Testbeeld {}'.format(i) for i in sampleList] + ["Gemiddelde"],
columns=['Grijze stof', 'Witte stof', 'CSF',
'Totaal', 'Achtergrond'])
print(df)