frankkramer-lab / MIScnn

A framework for Medical Image Segmentation with Convolutional Neural Networks and Deep Learning
GNU General Public License v3.0
402 stars 116 forks source link

Error when trying to use 2D nifti data #41

Closed covasquezv closed 3 years ago

covasquezv commented 3 years ago

Hi Dominik, I was using MIScnn to train a U-Net with patches from 3D nifti data and I didn't had any issues related to data. But now I've change the data to 2D slices (also nifti) an during first epoch I had the following error related to loss functions:

Epoch 1/1000
Traceback (most recent call last):
  File "scripts/run_miscnn_2D.py", line 145, in <module>
    callbacks=[cb_lr, cb_es, cb_tb, cb_cl, cb_ckp])
  File "/home/ubuntu/.local/lib/python3.6/site-packages/miscnn/neural_network/model.py", line 201, in evaluate
    max_queue_size=self.batch_queue_size)
  File "/home/ubuntu/.local/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py", line 66, in _method_wrapper
    return method(self, *args, **kwargs)
  File "/home/ubuntu/.local/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py", line 848, in fit
    tmp_logs = train_function(iterator)
  File "/home/ubuntu/.local/lib/python3.6/site-packages/tensorflow/python/eager/def_function.py", line 580, in __call__
    result = self._call(*args, **kwds)
  File "/home/ubuntu/.local/lib/python3.6/site-packages/tensorflow/python/eager/def_function.py", line 627, in _call
    self._initialize(args, kwds, add_initializers_to=initializers)
  File "/home/ubuntu/.local/lib/python3.6/site-packages/tensorflow/python/eager/def_function.py", line 506, in _initialize
    *args, **kwds))
  File "/home/ubuntu/.local/lib/python3.6/site-packages/tensorflow/python/eager/function.py", line 2446, in _get_concrete_function_internal_garbage_collected
    graph_function, _, _ = self._maybe_define_function(args, kwargs)
  File "/home/ubuntu/.local/lib/python3.6/site-packages/tensorflow/python/eager/function.py", line 2777, in _maybe_define_function
    graph_function = self._create_graph_function(args, kwargs)
  File "/home/ubuntu/.local/lib/python3.6/site-packages/tensorflow/python/eager/function.py", line 2667, in _create_graph_function
    capture_by_value=self._capture_by_value),
  File "/home/ubuntu/.local/lib/python3.6/site-packages/tensorflow/python/framework/func_graph.py", line 981, in func_graph_from_py_func
    func_outputs = python_func(*func_args, **func_kwargs)
  File "/home/ubuntu/.local/lib/python3.6/site-packages/tensorflow/python/eager/def_function.py", line 441, in wrapped_fn
    return weak_wrapped_fn().__wrapped__(*args, **kwds)
  File "/home/ubuntu/.local/lib/python3.6/site-packages/tensorflow/python/framework/func_graph.py", line 968, in wrapper
    raise e.ag_error_metadata.to_exception(e)
ValueError: in user code:

    /home/ubuntu/.local/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py:571 train_function  *
        outputs = self.distribute_strategy.run(
    /home/ubuntu/.local/lib/python3.6/site-packages/tensorflow/python/distribute/distribute_lib.py:951 run  **
        return self._extended.call_for_each_replica(fn, args=args, kwargs=kwargs)
    /home/ubuntu/.local/lib/python3.6/site-packages/tensorflow/python/distribute/distribute_lib.py:2290 call_for_each_replica
        return self._call_for_each_replica(fn, args, kwargs)
    /home/ubuntu/.local/lib/python3.6/site-packages/tensorflow/python/distribute/distribute_lib.py:2649 _call_for_each_replica
        return fn(*args, **kwargs)
    /home/ubuntu/.local/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py:533 train_step  **
        y, y_pred, sample_weight, regularization_losses=self.losses)
    /home/ubuntu/.local/lib/python3.6/site-packages/tensorflow/python/keras/engine/compile_utils.py:205 __call__
        loss_value = loss_obj(y_t, y_p, sample_weight=sw)
    /home/ubuntu/.local/lib/python3.6/site-packages/tensorflow/python/keras/losses.py:143 __call__
        losses = self.call(y_true, y_pred)
    /home/ubuntu/.local/lib/python3.6/site-packages/tensorflow/python/keras/losses.py:246 call
        return self.fn(y_true, y_pred, **self._fn_kwargs)
    /home/ubuntu/.local/lib/python3.6/site-packages/miscnn/neural_network/metrics.py:126 tversky_crossentropy
        crossentropy = K.categorical_crossentropy(y_truth, y_pred)
    /home/ubuntu/.local/lib/python3.6/site-packages/tensorflow/python/keras/backend.py:4561 categorical_crossentropy
        target.shape.assert_is_compatible_with(output.shape)
    /home/ubuntu/.local/lib/python3.6/site-packages/tensorflow/python/framework/tensor_shape.py:1117 assert_is_compatible_with
        raise ValueError("Shapes %s and %s are incompatible" % (self, other))

    ValueError: Shapes (None, None, None, None) and (None, None, None, None, 2) are incompatible

I'm thinking is something related to my architecture configuration or the metrics definition, but I don't understand what. Here's my pipeline:

interface = NIFTI_interface(channels=1, classes=2)
# Create Data IO object to load and write samples in the file structure
data_io = Data_IO(interface, input_path="data_2D", delete_batchDir=False)

# Access all available samples in our file structure
sample_list = data_io.get_indiceslist()
sample_list.sort()

# Create and configure the Data Augmentation class
data_aug = Data_Augmentation(cycles=1, scaling=True, rotations=True,
                             elastic_deform=True, mirror=True,
                             brightness=True, contrast=True, gamma=True,
                             gaussian_noise=True)

# Create a clipping Subfunction to the lung window of CTs (-1250 and 250)
sf_clipping = Clipping(min=-1250, max=250)
# Create a pixel value normalization Subfunction for z-score scaling
sf_zscore = Normalization(mode="z-score")

sf_resize = Resize((512, 512))

# Assemble Subfunction classes into a list
sf = [sf_clipping, sf_zscore, sf_resize]

# Create and configure the Preprocessor class
pp = Preprocessor(data_io, data_aug=data_aug, batch_size=8, subfunctions=sf,
                  prepare_subfunctions=True, prepare_batches=False,
                  analysis="fullimage")

# Initialize the Architecture
unet_standard = Architecture(depth=3, activation="softmax",
                             batch_normalization=True)

# Create the Neural Network model
model = Neural_Network(preprocessor=pp, architecture=unet_standard,
                       loss=tversky_crossentropy,
                       metrics=[tversky_loss, dice_soft, dice_crossentropy],
                       batch_queue_size=3, workers=3, learninig_rate=0.001)

# Define Callbacks
cb_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=15,
                          verbose=1, mode='min', min_delta=0.0001, cooldown=1,
                          min_lr=0.00001)
cb_es = EarlyStopping(monitor="val_loss", patience=20, mode="min", restore_best_weights=True)
cb_tb = TensorBoard(log_dir=os.path.join(fold_subdir, "tensorboard"),
                    histogram_freq=0, write_graph=True, write_images=True)
cb_cl = CSVLogger(os.path.join(fold_subdir, "logs.csv"), separator=',',
                  append=True)
cb_ckp = ModelCheckpoint(os.path.join(fold_subdir, "model.hdf5"),
                         save_best_only=True,
                         monitor="val_loss",
                         mode="min")

#-----------------------------------------------------#
#                           Train                            #
#-----------------------------------------------------#
random.shuffle(sample_list)

train_list = sample_list[:2000]
val_list = sample_list[2000:3000]
test_list = sample_list[3000:]

model.evaluate(train_list,
               val_list,
               epochs=1000,
               iterations=250,
               callbacks=[cb_lr, cb_es, cb_tb, cb_cl, cb_ckp])

## Dump model to disk for reproducibility
model.dump(os.path.join(fold_subdir, "model.hdf5"))

Thanks in advance!! Constanza

covasquezv commented 3 years ago

I solved my problem. I just needed to change the interface from: interface = NIFTI_interface(channels=1, classes=2) to interface = NIFTI_interface(channels=1, classes=2, three_dim=False).

Now it works perfectly! I leave it here in case anyone is facing the same issue.