Switch to unified view

a b/scripts/cv_analysis/miscnn_k3.py
1
#==============================================================================#
2
#  Author:       Dominik Müller                                                #
3
#  Copyright:    2020 IT-Infrastructure for Translational Medical Research,    #
4
#                University of Augsburg                                        #
5
#                                                                              #
6
#  This program is free software: you can redistribute it and/or modify        #
7
#  it under the terms of the GNU General Public License as published by        #
8
#  the Free Software Foundation, either version 3 of the License, or           #
9
#  (at your option) any later version.                                         #
10
#                                                                              #
11
#  This program is distributed in the hope that it will be useful,             #
12
#  but WITHOUT ANY WARRANTY; without even the implied warranty of              #
13
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
14
#  GNU General Public License for more details.                                #
15
#                                                                              #
16
#  You should have received a copy of the GNU General Public License           #
17
#  along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
18
#==============================================================================#
19
#-----------------------------------------------------#
20
#                   Library imports                   #
21
#-----------------------------------------------------#
22
import tensorflow as tf
23
from miscnn.data_loading.interfaces import NIFTI_interface
24
from miscnn import Data_IO, Preprocessor, Data_Augmentation, Neural_Network
25
from miscnn.processing.subfunctions import Normalization, Clipping, Resampling
26
from miscnn.neural_network.architecture.unet.standard import Architecture
27
from miscnn.neural_network.metrics import tversky_crossentropy, dice_soft, \
28
                                          dice_crossentropy, tversky_loss
29
from miscnn.evaluation.cross_validation import cross_validation
30
from tensorflow.keras.callbacks import ReduceLROnPlateau, TensorBoard, \
31
                                       EarlyStopping, CSVLogger, ModelCheckpoint
32
from miscnn.evaluation.cross_validation import run_fold, load_disk2fold
33
import argparse
34
import os
35
36
#-----------------------------------------------------#
37
#                      Argparser                      #
38
#-----------------------------------------------------#
39
parser = argparse.ArgumentParser(description="Automated COVID-19 Segmentation")
40
parser.add_argument("-f", "--fold", help="Cross-validation fold. Range: [0:5]",
41
                    required=True, type=int, dest="fold")
42
parser.add_argument("-g", "--gpu", help="GPU ID selection for multi cluster",
43
                    required=False, type=int, dest="gpu", default=0)
44
45
path_eval = "evaluation.cv3"
46
path_preds = "predictions.cv3"
47
48
args = parser.parse_args()
49
fold = args.fold
50
fold_subdir = os.path.join(path_eval, "fold_" + str(fold))
51
52
#-----------------------------------------------------#
53
#      Tensorflow Configuration for GPU Cluster       #
54
#-----------------------------------------------------#
55
os.environ["CUDA_VISIBLE_DEVICES"] = str(int(args.gpu))
56
57
#-----------------------------------------------------#
58
#               Setup of MIScnn Pipeline              #
59
#-----------------------------------------------------#
60
# Initialize Data IO Interface for NIfTI data
61
## We are using 4 classes due to [background, lung_left, lung_right, covid-19]
62
interface = NIFTI_interface(channels=1, classes=4)
63
64
# Create Data IO object to load and write samples in the file structure
65
data_io = Data_IO(interface, input_path="data", output_path=path_preds,
66
                  delete_batchDir=False)
67
68
# Access all available samples in our file structure
69
sample_list = data_io.get_indiceslist()
70
sample_list.sort()
71
72
# Create and configure the Data Augmentation class
73
data_aug = Data_Augmentation(cycles=1, scaling=True, rotations=True,
74
                             elastic_deform=True, mirror=True,
75
                             brightness=True, contrast=True, gamma=True,
76
                             gaussian_noise=True)
77
78
# Create a clipping Subfunction to the lung window of CTs (-1250 and 250)
79
sf_clipping = Clipping(min=-1250, max=250)
80
# Create a pixel value normalization Subfunction to scale between 0-255
81
sf_normalize = Normalization(mode="grayscale")
82
# Create a resampling Subfunction to voxel spacing 1.58 x 1.58 x 2.70
83
sf_resample = Resampling((1.58, 1.58, 2.70))
84
# Create a pixel value normalization Subfunction for z-score scaling
85
sf_zscore = Normalization(mode="z-score")
86
87
# Assemble Subfunction classes into a list
88
sf = [sf_clipping, sf_normalize, sf_resample, sf_zscore]
89
90
# Create and configure the Preprocessor class
91
pp = Preprocessor(data_io, data_aug=data_aug, batch_size=2, subfunctions=sf,
92
                  prepare_subfunctions=True, prepare_batches=False,
93
                  analysis="patchwise-crop", patch_shape=(160, 160, 80),
94
                  use_multiprocessing=True)
95
# Adjust the patch overlap for predictions
96
pp.patchwise_overlap = (80, 80, 30)
97
98
# Initialize the Architecture
99
unet_standard = Architecture(depth=4, activation="softmax",
100
                             batch_normalization=True)
101
102
# Create the Neural Network model
103
model = Neural_Network(preprocessor=pp, architecture=unet_standard,
104
                       loss=tversky_crossentropy,
105
                       metrics=[tversky_loss, dice_soft, dice_crossentropy],
106
                       batch_queue_size=3, workers=3, learninig_rate=0.001)
107
108
# Define Callbacks
109
cb_lr = ReduceLROnPlateau(monitor='loss', factor=0.1, patience=15,
110
                          verbose=1, mode='min', min_delta=0.0001, cooldown=1,
111
                          min_lr=0.00001)
112
cb_es = EarlyStopping(monitor="loss", patience=100)
113
cb_tb = TensorBoard(log_dir=os.path.join(fold_subdir, "tensorboard"),
114
                    histogram_freq=0, write_graph=True, write_images=True)
115
cb_cl = CSVLogger(os.path.join(fold_subdir, "logs.csv"), separator=',',
116
                  append=True)
117
cb_mc = ModelCheckpoint(os.path.join(fold_subdir, "model.best.hdf5"),
118
                        monitor="loss", verbose=1,
119
                        save_best_only=True, mode="min")
120
121
#-----------------------------------------------------#
122
#          Run Pipeline for provided CV Fold          #
123
#-----------------------------------------------------#
124
# Run pipeline for cross-validation fold
125
run_fold(fold, model, epochs=1000, iterations=150, evaluation_path=path_eval,
126
         draw_figures=True, callbacks=[cb_lr, cb_es, cb_tb, cb_cl, cb_mc],
127
         save_models=False)
128
129
# Dump latest model to disk
130
model.dump(os.path.join(fold_subdir, "model.latest.hdf5"))
131
132
#-----------------------------------------------------#
133
#           Inference for provided CV Fold            #
134
#-----------------------------------------------------#
135
# Load best model weights during fitting
136
model.load(os.path.join(fold_subdir, "model.best.hdf5"))
137
138
# Obtain training and validation data set
139
training, validation = load_disk2fold(os.path.join(fold_subdir,
140
                                                   "sample_list.json"))
141
142
# Compute predictions
143
model.predict(validation, return_output=False)