예제 #1
0
    def _read_tfrecords(self):
        '''Reads tfrecords with the TFrecordsReader for training and validation.
        
        Returns:
            tf.dataset: Returns an iterable tf dataset.
        '''
        # Read tfrecords
        train_filenames = get_tfrecord_filenames(self.path_to_tfrecords_train)
        val_filenames = get_tfrecord_filenames(self.path_to_tfrecords_val)

        # Load tfrecords into a TFRecordDataset
        train_tfrecorddataset = tf.data.TFRecordDataset(
            filenames=train_filenames)
        val_tfrecorddataset = tf.data.TFRecordDataset(filenames=val_filenames)

        # Decode the data and prepare for training
        log.info('YELLOW', 'Loading Datasets')
        print("Training Datasets: ", train_filenames)
        print("Validation Datasets: ", val_filenames)
        print('Classes:', self.num_classes, 'Channels:', self.channels,
              'Input image size:', self.image_shape_resize)
        train_data_provider = TFRecordsReader3D(train_tfrecorddataset,
                                                np.ceil(self.num_scans / 10),
                                                self.batch_size,
                                                self.num_classes,
                                                self.channels,
                                                self.image_shape_resize,
                                                validating=False)
        val_data_provider = TFRecordsReader3D(val_tfrecorddataset,
                                              np.ceil(self.num_scans / 10),
                                              self.batch_size,
                                              self.num_classes,
                                              self.channels,
                                              self.image_shape_resize,
                                              validating=True)

        train_dataset = train_data_provider.read()
        val_dataset = val_data_provider.read()
        return train_dataset, val_dataset
예제 #2
0
def the_logo():
    ''' print the logo '''
    log.info('MAGENTA', '============================')
    log.info('MAGENTA', '===   BEHOLD CALCULON    ===')
    log.info('MAGENTA', '============================')
예제 #3
0
    def launch_unet2d(self):
        '''Launch the training process.
        '''
        # Read tfrecords
        train_filenames = get_tfrecord_filenames(self.path_to_tfrecords_train)
        val_filenames = get_tfrecord_filenames(self.path_to_tfrecords_val)

        # Load tfrecords into a TFRecordDataset
        train_tfrecorddataset = tf.data.TFRecordDataset(
            filenames=train_filenames)
        val_tfrecorddataset = tf.data.TFRecordDataset(filenames=val_filenames)

        # Decode the data and prepare for training
        log.info('YELLOW', 'Loading Datasets')
        print("Training Datasets: ", train_filenames)
        print("Validation Datasets: ", val_filenames)

        train_data_provider = TFRecordsReader2D(train_tfrecorddataset,
                                                np.ceil(self.num_scans / 10),
                                                0, self.batch_size, 512, 512,
                                                self.image_shape_resize[0],
                                                self.image_shape_resize[1],
                                                self.num_classes)
        val_data_provider = TFRecordsReader2D(val_tfrecorddataset,
                                              np.ceil(self.num_scans / 10), 0,
                                              self.batch_size, 512, 512,
                                              self.image_shape_resize[0],
                                              self.image_shape_resize[1],
                                              self.num_classes)

        train_dataset = train_data_provider.read()
        val_dataset = val_data_provider.read()

        for image, mask in train_dataset.take(1):
            sample_image, sample_mask = image, mask
            print(sample_image.shape)
            print(sample_mask.shape)

        # Load the Unet Model
        Module = Unet2D(learning_rate=self.learning_rate,
                        num_classes=self.num_classes,
                        input_size=[
                            self.image_shape_resize[0],
                            self.image_shape_resize[1], self.channels
                        ])
        model = Module.unet()

        # Create a callback that saves the model's weights
        ckpt_callback = tf.keras.callbacks.ModelCheckpoint(
            filepath=self.ckpt_dir, save_weights_only=True, verbose=1)

        # Clear any logs from previous runs
        shutil.rmtree(self.output_dir + "logs/")

        # Create a callback to tensorboard
        tensorboard_callback = tf.keras.callbacks.TensorBoard(
            log_dir=self.log_dir, histogram_freq=1, profile_batch=0)

        # Creates a file writer for the image prediction log directory.
        file_writer = tf.summary.create_file_writer(self.log_dir + '/img')

        # Start the training and evaluation
        model.fit(x=train_dataset,
                  epochs=self.epochs,
                  steps_per_epoch=self.steps_per_epoch,
                  callbacks=[
                      DisplayCallback(model, val_dataset, file_writer),
                      ckpt_callback, tensorboard_callback
                  ],
                  validation_data=val_dataset,
                  validation_steps=self.val_steps)

        # Save the trained model
        #tf.saved_model.save(model, self.savedmodel_dir)
        model.save(self.savedmodel_dir, save_format='tf')
예제 #4
0
    def save_data(self):
        '''Saves CT scans and segmentation masks to separate training and 
        validation tfrecords files.
        
        Raises:
            ValueError: If separation into training and validation sets has failed.
        '''
        print("Write to train.tfrecords: ", [self.vol_paths[x] for x in self.train_range])
        print("Write to val.tfrecords: ", [self.vol_paths[x] for x in self.val_range])
        for i in [self.path_to_tfrecords_train, self.path_to_tfrecords_val]:
            if not os.path.exists(i):
                os.makedirs(i)

        train_writer = tf.io.TFRecordWriter(self.path_to_tfrecords_train + 'train.tfrecords')
        val_writer = tf.io.TFRecordWriter(self.path_to_tfrecords_val + 'val.tfrecords')

        # Cycle through the CT and segmentation pairs
        for i in range(len(self.vol_paths)):
            print('Writing CT Scan: {}/{}'.format(i+1, len(self.vol_paths)))
            sys.stdout.flush()
            print(self.vol_paths[i], self.seg_paths[i])

            # Read nifti file
            vol_data = read_nifti_file(self.vol_paths[i])
            seg_data = read_nifti_file(self.seg_paths[i])

            # Clip values to -1024 HU and 600 HU
            vol_data = np.clip(vol_data, a_min=-1024, a_max=600)

            # Normalize the data
            vol_data = standardize_volume(vol_data)
            print(np.amax(vol_data), np.amin(vol_data), np.mean(vol_data), np.std(vol_data))

            # Filter out only slices that contain labels
            if self.filter:
                vol_data, seg_data = filter_volume(vol_data, seg_data, self.axis)

            # Get the number of slices
            n_slices = get_n_slices(self.view, vol_data)

            # Cycle through the image slices
            n_images = 0
            for j in range(n_slices):
                vol_slice = get_slice(self.view, vol_data, j)
                seg_slice = get_slice(self.view, seg_data, j)

                # Resize the slice if necessary
                h, w = np.shape(seg_slice)
                if h != self.input_height or w != self.input_width:
                    vol_slice = resize(vol_slice, output_shape=(self.input_height, self.input_width), order=1, mode='constant', anti_aliasing=False, preserve_range=True)
                    seg_slice = resize(seg_slice, output_shape=(self.input_height, self.input_width), order=0, mode='constant', anti_aliasing=False, preserve_range=True)

                # Expand dims and change datatype to string to be saved by TF
                vol_slice = make_tfrecords_ready(vol_slice)
                seg_slice = make_tfrecords_ready(seg_slice)

                # Create a feature
                # Create an example protocol buffer
                example = tf.train.Example(features=tf.train.Features(feature={
                    # Wrap the data as TensorFlow features
                    'data/slice': self._bytes_feature(vol_slice),
                    'data/seg': self._bytes_feature(seg_slice)}))

                # Serialize to string and write to the TFRecords file
                if i in self.train_range:
                    train_writer.write(example.SerializeToString())
                elif i in self.val_range:
                    val_writer.write(example.SerializeToString())
                else:
                    raise ValueError("Not in training or validation range.")
                n_images += 1
            print('Number of slices: {}'.format(n_images))
        train_writer.close()
        val_writer.close()
        sys.stdout.flush()
        log.info('YELLOW', 'Saved as TFRecords')
        return self.path_to_tfrecords_train, self.path_to_tfrecords_val
예제 #5
0
    def save_data(self):
        '''Read CT scans and images
        '''
        print("Write to train.tfrecords: ", [self.vol_paths[x] for x in self.train_range])
        print("Write to val.tfrecords: ", [self.vol_paths[x] for x in self.val_range])
        self.path_to_tfrecords_train = os.path.join(self.path_to_tfrecords_train, 'concat/')
        self.path_to_tfrecords_val = os.path.join(self.path_to_tfrecords_val, 'concat/')
        for i in [self.path_to_tfrecords_train, self.path_to_tfrecords_val]:
            if not os.path.exists(i):
                os.makedirs(i)

        train_writer = tf.io.TFRecordWriter(self.path_to_tfrecords_train + 'concat_train.tfrecords')
        val_writer = tf.io.TFRecordWriter(self.path_to_tfrecords_val + 'concat_val.tfrecords')

        # Cycle through the CT and segmentation pairs
        for i in range(len(self.vol_paths)):
            print('Writing CT Scan: {}/{}'.format(i+1, len(self.vol_paths)))
            sys.stdout.flush()
            print(self.vol_paths[i], self.seg_paths[i])

            # Read nifti file
            vol_data = read_nifti_file(self.vol_paths[i])
            seg_data = read_nifti_file(self.seg_paths[i])
            print('Original shape: ', vol_data.shape, seg_data.shape)

            # Clip values to -1024 HU and 600 HU
            vol_data = np.clip(vol_data, a_min=-1024, a_max=600)

            # Normalize the data
            vol_data = standardize_volume(vol_data)
            print(np.amax(vol_data), np.amin(vol_data), np.mean(vol_data), np.std(vol_data))

            # Resize CT to downsampled shape for prediction
            vol_data_resized = resize(vol_data, self.image_shape_lowres)
            print('Original resized to shape: ', vol_data_resized.shape)
            
            # Predict
            pred = self._predict(vol_data_resized)
            print('Predicted to shape: ', pred.shape)

            # Upsample
            pred_up = resize(pred, [vol_data.shape[0], self.image_shape_highres[1], self.image_shape_highres[2]])
            print('Prediction upsampled to shape: ', pred_up.shape)

            # Downsample the original vol_data and seg_data
            vol_data = resize(vol_data, [vol_data.shape[0], self.image_shape_highres[1], self.image_shape_highres[2]])
            seg_data = resize(seg_data, [seg_data.shape[0], self.image_shape_highres[1], self.image_shape_highres[2]])
            # Insert a new dimension (axis) at position -1
            vol_data = np.expand_dims(vol_data, axis=-1)
            seg_data = np.expand_dims(seg_data, axis=-1)
            print('Original downsampled to :', vol_data.shape, seg_data.shape)

            # Concatenate the upsampled prediction and the downsampled original
            new_vol = self._concatenate(pred_up, vol_data)
            print('Concatenated to shape: ', new_vol.shape)

            # Write new tfrecords
            train_writer, val_writer = self._write_tfrecords(i, new_vol, seg_data, train_writer, val_writer)

        print('Number of training samples: {}, Number of validation samples: {}.'.format(self.n_train, self.n_val))
        train_writer.close()
        val_writer.close()
        sys.stdout.flush()
        log.info('YELLOW', 'Saved as TFRecords')
        return self.path_to_tfrecords_train, self.path_to_tfrecords_val, self.n_train, self.n_val
예제 #6
0
    def save_data(self):
        '''Saves CT scans and segmentation masks to separate training and 
        validation tfrecords files.
        
        Raises:
            ValueError: If separation into training and validation sets has failed.
        '''
        print("Write to train.tfrecords: ", [self.vol_paths[x] for x in self.train_range])
        print("Write to val.tfrecords: ", [self.vol_paths[x] for x in self.val_range])
        for i in [self.path_to_tfrecords_train, self.path_to_tfrecords_val]:
            if not os.path.exists(i):
                os.makedirs(i)

        train_writer = tf.io.TFRecordWriter(self.path_to_tfrecords_train + 'train.tfrecords')
        val_writer = tf.io.TFRecordWriter(self.path_to_tfrecords_val + 'val.tfrecords')

        # Cycle through the CT and segmentation pairs
        for i in range(len(self.vol_paths)):
            print('Writing CT Scan: {}/{}'.format(i+1, len(self.vol_paths)))
            sys.stdout.flush()
            print(self.vol_paths[i], self.seg_paths[i])

            # Read nifti file
            vol_data = read_nifti_file(self.vol_paths[i])
            seg_data = read_nifti_file(self.seg_paths[i])
            print('Original shape: ', vol_data.shape, seg_data.shape)

            # Resize into smaller axial shape, keep original depth dimension
            vol_data = resize(vol_data, [vol_data.shape[0], self.image_shape_resize[1], self.image_shape_resize[2]])
            seg_data = resize(seg_data, [seg_data.shape[0], self.image_shape_resize[1], self.image_shape_resize[2]])
            print('Resized to shape: ', vol_data.shape, seg_data.shape)
            
            # Clip values to -1024 HU and 600 HU
            vol_data = np.clip(vol_data, a_min=-1024, a_max=600)

            # Normalize the data
            vol_data = standardize_volume(vol_data)
            print(np.amax(vol_data), np.amin(vol_data), np.mean(vol_data), np.std(vol_data))
            
            # Calculate number of axial slabs s
            s = math.floor(vol_data.shape[0] / self.image_shape_resize[0])
            print('CT scan will be split into {} slabs of size {}.'.format(s, self.image_shape_resize))
            print(range(s))
            # Split into slabs
            for j in range(s):
                start = self.image_shape_resize[0] * j
                end = self.image_shape_resize[0] * (j + 1)
                print(start, end)

                vol_slab = vol_data[start : end, :, :]
                seg_slab = seg_data[start : end, :, :]

                # Expand dims and change datatype to string to be saved by TF
                vol_slab = make_tfrecords_ready_3d(vol_slab)
                seg_slab = make_tfrecords_ready_3d(seg_slab)
                # Create a feature
                # Create an example protocol buffer
                example = tf.train.Example(features=tf.train.Features(feature={
                    # Wrap the data as TensorFlow features
                    'data/img': self._bytes_feature(vol_slab),
                    'data/seg': self._bytes_feature(seg_slab)}))

                # Serialize to string and write to the TFRecords file
                if i in self.train_range:
                    train_writer.write(example.SerializeToString())
                elif i in self.val_range:
                    val_writer.write(example.SerializeToString())
                else:
                    raise ValueError("Not in training or validation range.")

        train_writer.close()
        val_writer.close()
        sys.stdout.flush()
        log.info('YELLOW', 'Saved as TFRecords')
        return self.path_to_tfrecords_train, self.path_to_tfrecords_val
예제 #7
0
    def save_data(self):
        '''Saves CT scans and segmentation masks to separate training and 
        validation tfrecords files.
        
        Raises:
            ValueError: If separation into training and validation sets has failed.
        '''
        print("Write to train.tfrecords: ", [self.vol_paths[x] for x in self.train_range])
        print("Write to val.tfrecords: ", [self.vol_paths[x] for x in self.val_range])
        for i in [self.path_to_tfrecords_train, self.path_to_tfrecords_val]:
            if not os.path.exists(i):
                os.makedirs(i)

        train_writer = tf.io.TFRecordWriter(self.path_to_tfrecords_train + 'train.tfrecords')
        val_writer = tf.io.TFRecordWriter(self.path_to_tfrecords_val + 'val.tfrecords')

        # Cycle through the CT and segmentation pairs
        for i in range(len(self.vol_paths)):
            print('Writing CT Scan: {}/{}'.format(i+1, len(self.vol_paths)))
            sys.stdout.flush()
            print(self.vol_paths[i], self.seg_paths[i])

            # Read nifti file
            vol_data = read_nifti_file(self.vol_paths[i])
            seg_data = read_nifti_file(self.seg_paths[i])
            print('Original shape: ', vol_data.shape, seg_data.shape)

            # Clip values to -1024 HU and 600 HU
            vol_data = np.clip(vol_data, a_min=-1024, a_max=600)
            # Normalize data between [0,1]
            #vol_data = normalize_volume(vol_data)
            print('Classes: ', np.unique(seg_data))

            # Resize to new shape
            vol_data = resize(vol_data, self.image_shape_resize, mode='constant', order=1, preserve_range=True, anti_aliasing=False) # bi-linear
            seg_data = resize(seg_data, self.image_shape_resize, mode='constant', order=0, preserve_range=True, anti_aliasing=False) # nearest neighbor
            print('Resized to shape: ', vol_data.shape, seg_data.shape)
            # Seg back to integers
            #seg_data = np.round(seg_data)
            print('Classes: ', np.unique(seg_data))
            
            #two_display([vol_data[None,64,:,:], seg_data[None,64,:,:]])
            
            # Standardize the data
            #self.mean, self.std = compute_mean_variance_file(vol_data)
            vol_data = standardize_volume(vol_data)
            print("After Normalizing: Max {}, Min {}, Mean {}, Std {}".format(np.amax(vol_data), np.amin(vol_data), np.mean(vol_data), np.std(vol_data)))

            # Expand dims and change datatype to string to be saved by TF
            vol_data = make_tfrecords_ready_3d(vol_data)
            seg_data = make_tfrecords_ready_3d(seg_data)
            # Create a feature
            # Create an example protocol buffer
            example = tf.train.Example(features=tf.train.Features(feature={
                # Wrap the data as TensorFlow features
                'data/img': self._bytes_feature(vol_data),
                'data/seg': self._bytes_feature(seg_data)}))

            # Serialize to string and write to the TFRecords file
            if i in self.train_range:
                train_writer.write(example.SerializeToString())
            elif i in self.val_range:
                val_writer.write(example.SerializeToString())
            else:
                raise ValueError("Not in training or validation range.")

        train_writer.close()
        val_writer.close()
        sys.stdout.flush()
        log.info('YELLOW', 'Saved as TFRecords')
        return self.path_to_tfrecords_train, self.path_to_tfrecords_val