Closed dannyhow12 closed 2 years ago
Hey @dannyhow12,
mhm, looks like the class annotations in aggregated_MAJ_seg.nii.gz
are not ongoing from 0 to num_classes-1.
Tensorflow.keras and also MIScnn requires that the class annotations are from 0 to num_classes-1 (0, 1, 2, 3, ...), because MIScnn utilizes this function for preprocessing: https://www.tensorflow.org/api_docs/python/tf/keras/utils/to_categorical
If you define classes=3, each pixel in the provided segmentation file should be annotated with a class via [0,1,2]. The exception says that he found a pixel with the class annotation 3 which shouldn't exist with 3 classes (due to counting start from zero).
Could you iterate over the annotation files and print out the values via e.g. numpy.unique() to check if they are all from 0 to n-1?
Maybe, the annotation looks like that [1,2,3] instead of [0,1,2]?
Then, you have to either preprocess the annotation files with the standard NIfTI IO interface or just write the class fix code as Subfunction or custom IO interface.
Cheers, Dominik
Hi,
May I ask more specifically on what do you mean by writing the class fix code as Subfunction or custom IO interface?
Hello @dannyhow12,
sure! A similar issue is this one: #93
So, the issue is that classes need to be annotated as consecutive values in tensorflow like e.g. [0, 1] for binary segmentation. However, annotations of datasets can sometime be in a non-consecutive fashion.
The standard example is a grayscale mask with [0, 255] for binary segmentation.
So, what we have to do is to replace all 255 annotations to 1, in order to have the consecutive order.
How can we do it this?
You have three options:
Here is an example of a Subfunction to fix a [0,255] annotation to a [0,1] annotation:
The subfunction simply replace the annotation class 255 to 1, which results into a consecutive annotation matrix.
class ChangeValues(Abstract_Subfunction):
#---------------------------------------------#
# Initialization #
#---------------------------------------------#
def __init__(self, val_to_change, change_in):
self.val_to_change = val_to_change
self.change_in = change_in
#---------------------------------------------#
# Preprocessing #
#---------------------------------------------#
def preprocessing(self, sample, training=True):
seg_temp = sample.seg_data
if(sample.seg_data is not None):
sample.seg_data = np.where(seg_temp == self.val_to_change, self.change_in, seg_temp)
#---------------------------------------------#
# Postprocessing #
#---------------------------------------------#
def postprocessing(self, sample, prediction, activation_output=False):
if prediction is not None:
prediction = np.where(prediction == self.change_in, self.val_to_change, prediction)
return prediction
You just have to identify with numpy.unique(), now, how the exact class annotation in your dataset look like and then bring it into a consecutive order with e.g. such subfunction.
Hope I was able to help.
Cheers, Dominik
Hello @muellerdo
After reviewing the dataset, I totally missed out on the point that the difference between the KiTS19 and KiTS21 dataset is that there is an extra class of cyst, resulting in some of the CT images with a intensity range from 0 - 3, which are:
Thus, I removed the dataset from it and now it is working. Thank you for pointing out Dominik and stay safe!
Regards, Danny
Hi and good day everyone, I encounter the following issue when I tried to train the model from scratch. Pasted below are some error codes displayed.
In order to solve this, I changed num_classes in preprocessor.py to 3 and 1 respectively, where both attempts seem to return the same error as with the original one of num_classes = sample.classes
Here are some notation 1) I am working on the KITS21 dataset, where the imaging.nii.gz and aggregated_MAJ_seg.nii.gz are used. 2) I am using Google Colab to work on this project, but I doubt that the problem is originating from Google Colab as I have successfully cloned this repo to Google Colab.
Thank you