Custom Dataset using Tifffile python library

DVangelis: <p>Hi to all,<br>
My first message here and brand new to pytorch and AI.<br>
I have trained a model and now I want to load unseen images to my model so I can segmentate them.<br>
To do that I self defined a dataset class ‘Mydataset’ that gets the directory of images and read the files by using the library tifffile and make some transformations to them.<br>
I work with 3d stacks of images that have tif format.<br>
My problem is that ‘Mydataset’ read only the first slice of the 3d stack but not all the slices from the stuck. Normally I would like with the MyUnseen dataset to read all the slices in my stacks normally I  have stacks of 250 slices so in the end my dataset need to have a length of 250. I really appreciate if anyone can help me with this issue thanks in advance.</p>
<p>class MyUnseen(Dataset):</p>
<pre><code>def __init__(self,raw_directory):

    self.raw=raw_directory
    self.data_list=glob(raw_direct)
    self.data_len=len(self.data_list)
    self.images=tifffile.imread(self.raw)

def __getitem__(self,idx):
    images=self.images[idx]

    images=normalize_custom(images) # Apply custom function normalize 

    images_tensor=torchvision.transforms.ToTensor()(images)

    padding=int((512-images_tensor.shape[2])/2)
    images_ten=transforms.Pad(padding)(images_tensor)

    return (images_ten)
def __len__(self):
    return self.data_len</code></pre>

ptrblck: <p>I’m not sure how to interpret your custom <code>Dataset</code> as it seems as if only a single image was read in:</p>
<pre><code class="lang-python">self.images=tifffile.imread(self.raw)
</code></pre>
<p>or is this method able to read multiple images?</p>

DVangelis: <p>Yes tifffile.imread is able to read also 3d stacks of tiffiles . And it returns it in numpy array format.<br>
So out it seems that work out is the below I dont know if it is an easier solution or more logical. I append the images after transformations in a list inside a loop and outside the loop I use torch.stack.<br>
(Actually this solution was found in another post in this forum <img src="https://discuss.pytorch.org/images/emoji/apple/face_with_hand_over_mouth.png?v=12" title=":face_with_hand_over_mouth:" class="emoji" alt=":face_with_hand_over_mouth:" loading="lazy" width="20" height="20">)</p>
<pre><code>def __getitem__(self,idx):
    images=self.images[idx]
    list_of_images=[]
    for i,file in tqdm(enumerate(self.images)):
        images=normalize_custom(file) # Apply custom function normalize 
        images_np=np.expand_dims(images,0)
        
        images_tensor=torch.from_numpy(images_np).float()
        padding=int((512-images_tensor.shape[1])/2)
        images_ten=transforms.Pad(padding)(images_tensor)
        list_of_images.append(images_ten)
    images_stack=torch.stack(list_of_images,axis=0)</code></pre>

ptrblck: <p>Thanks for clarifying.<br>
In your current code it seems you are loading and processing <em>all</em> images in each <code>__getitem__</code> call, which would mean that setting <code>batch_size=1</code> in the <code>DataLoader</code> would give you the entire dataset. Is this what you really want?</p>

DVangelis: <p>My model was trained using DataParallel then I saved the model.module.state_dict() .<br>
In inference part I load the saved model by using ,<br>
DEVICE=torch.device(“cuda:0” if torch.cuda.is_available() else “cpu”)<br>
model_trained=MyModel()<br>
checkpoint_fpath=****</p>
<p>model_trained = model_trained.cuda(0)</p>
<p>model_trained = nn.DataParallel(model_trained)</p>
<p>checkpoint=torch.load(checkpoint_fpath,map_location=torch.device(DEVICE))<br>
model_trained.module.load_state_dict(checkpoint[‘state_dict’])<br>
model_trained.eval()</p>
<p>For making my predictions I load my 3d stack of tif files and I make the necessary transformations from numpy to torch.tensor and I name my images unseen_tensor<br>
Then I use<br>
prediction_tensors=model_trained(unseen_tensor.to(DEVICE))</p>
<p>But I get an RuntimeError Caught RuntimeError in replica 0 ond device 0<br>
RuntimeError: CUDA out of memory…</p>
<p>So I thought If I use a dataset class and dataloader and then use a loop to make my predictions I could overcome this error.<br>
I hope now makes more sense what I am trying to do<br>
Thanks again for your help</p>

ptrblck: <p>Split this line:</p>
<pre><code class="lang-python">prediction_tensors=model_trained(unseen_tensor.to(DEVICE))
</code></pre>
<p>into a loop and iterate the data:</p>
<pre><code class="lang-python">model_trained.eval()
preds = []
with torch.no_grad():
    for input in unseen_tensor: # you can use another logic here to create mini batches etc.
        pred = model(input)
        preds.append(pred.detach().cpu())
preds = torch.stack(preds)
</code></pre>

DVangelis: <p>Thanks that helped a lot. From 10 hours for segmentating my dataset with this method took only 30 minutes. So the predictions are running under cpu right ?  I mean with the pred.detach().cpu() ?</p>

ptrblck: <aside class="quote no-group" data-username="DVangelis" data-post="7" data-topic="150108">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/dvangelis/48/47464_2.png" class="avatar"> DVangelis:</div>
<blockquote>
<p>So the predictions are running under cpu right ? I mean with the pred.detach().cpu() ?</p>
</blockquote>
</aside>
<p>No, the output prediction is detached and moved to the host to avoid storing these tensors on the GPU.</p>

DVangelis: <p>Ok thank you! I will need to have a closer look to the documentation of  detach and host.</p>