20.03.2021 Views

Deep-Learning-with-PyTorch

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Updating the dataset for segmentation

383

When you work on your own projects, you’ll need to do that kind of experimentation

for yourself!

We believe the whole-slice training was unstable essentially due to a class-balancing

issue. Since each nodule is so small compared to the whole CT slice, we were right

back in a needle-in-a-haystack situation similar to the one we got out of in the last

chapter, where our positive samples were swamped by the negatives. In this case, we’re

talking about pixels rather than nodules, but the concept is the same. By training on

crops, we’re keeping the number of positive pixels the same and reducing the negative

pixel count by several orders of magnitude.

Because our segmentation model is pixel-to-pixel and takes images of arbitrary

size, we can get away with training and validating on samples with different dimensions.

Validation uses the same convolutions with the same weights, just applied to a

larger set of pixels (and so with fewer border pixels to fill in with edge data).

One caveat to this approach is that since our validation set contains orders of magnitude

more negative pixels, our model will have a huge false positive rate during validation.

There are many more opportunities for our segmentation model to get

tricked! It doesn’t help that we’re going to be pushing for high recall as well. We’ll discuss

that more in section 13.6.3.

13.5.6 Implementing TrainingLuna2dSegmentationDataset

With that out of the way, let’s get back to the code. Here’s the training set’s __getitem__.

It looks just like the one for the validation set, except that we now sample from pos_list

and call getItem_trainingCrop with the candidate info tuple, since we need the series

and the exact center location, not just the slice.

Listing 13.17

dsets.py:320, .__getitem__

def __getitem__(self, ndx):

candidateInfo_tup = self.pos_list[ndx % len(self.pos_list)]

return self.getitem_trainingCrop(candidateInfo_tup)

To implement getItem_trainingCrop, we will use a getCtRawCandidate function

similar to the one we used during classification training. Here, we’re passing in a different

size crop, but the function is unchanged except for now returning an additional

array with a crop of the ct.positive_mask as well.

We limit our pos_a to the center slice that we’re actually segmenting, and then construct

our 64 × 64 random crops of the 96 × 96 we were given by getCtRawCandidate.

Once we have those, we return a tuple with the same items as our validation dataset.

Listing 13.18

dsets.py:324, .getitem_trainingCrop

def getitem_trainingCrop(self, candidateInfo_tup):

ct_a, pos_a, center_irc = getCtRawCandidate(

candidateInfo_tup.series_uid,

candidateInfo_tup.center_xyz,

Gets the candidate with a

bit of extra surrounding

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!