Writing Custom dataloader for Cycle Gans in pytorch

username: CS.Enthu
cooked: <p>I want to implement cycle GANs . I have preprocessed my datasets consisting of two different modality images.After preprocessing , Since I want to send image patches to my generator model, I exctracted the image patches using ‘unfold’ and saved them as .pt files . The size after extracting the patches are torch.Size([7, 4, 4, 64, 64, 64]) , which is a total of 112 patches of size 64 x 64 x64 Now how should I write my own dataset loader for these .pt files which are stored in the memory as tensors? Thanks in advance</p>

username: ptrblck
cooked: <p>If all image patches fit into memory, you could create a large tensor and directly index them.<br>
If that’s not the case, you might create a custom <code>Dataset</code> for each stored file and e.g. lazily load the data in its <code>__getitem__</code>.</p>
<p>Assuming you don’t want to shuffle the dataset, you could also use a modulo operation to check, which file to load and which patch should be loaded via this pseudo code:</p>
<pre><code class="lang-python">def __getitem__(self, index):
    file_idx = index // 112
    patch_index = index % 112
    # check of correct file is already open
    if self.loaded_data_path != self.data_path[file_idx]:
        # load file
    patch = self.loaded_data[patch_index]
    return patch
</code></pre>
<p>Note that shuffling the data (and thus the <code>index</code>) will open and close a lot of files, which might hurt the performance.</p>

username: CS.Enthu
cooked: <p>Thank you .<br>
I have one more basic question.<br>
Now that I have stored my patches. How should I visualize each of the patches?<br>
the patch size is 112, 64, 64, 64</p>
<p>Sorry, since I am a beginner !</p>

username: ptrblck
cooked: <p>You could use a nested loop to iterate each sample (dim0) and each channel (dim1) to visualize the 64x64 patch using <code>matplotlib.pyplot.imshow</code>.</p>

username: CS.Enthu
cooked: <p>Hello,</p>
<p>I extracted the image patches and wrote dataloader for GANs.<br>
But Now I get errors as follows.I dont understand where I am  going wrong with my understanding. I split the data afterwards. Although I know that we do it before dataloader. If that is the case, when I extract the patches , should I split the data after that?</p>
<p>I am trying to implement <a href="https://github.com/eriklindernoren" rel="nofollow noopener">eriklindernoren</a>/ **[PyTorch-GAN] cycle gan implementation. for my own dataset. In all the GANs example and implementation, the datasets are already saved in directories for train and testing. So I am have hard time to understand how should I do it my dataset after preprocessing.</p>
<p>In my dataprocessing file after I extracted the patches<br>
patch_A = extract_patches(torch.tensor(ct_numpy))  &gt;&gt;torch.Size([112, 64, 64, 64])</p>
<p>patch_B =extract_patches(torch.tensor(pet_numpy))  &gt;&gt;torch.Size([112, 64, 64, 64])</p>
<p>In dataloader :</p>
<p>class MyDataset(Dataset) :<br>
def <strong>init</strong>(self , patch_A, patch_B):<br>
‘characterizes a dataset for pytorch’<br>
self.patch_A = patch_A<br>
self.patch_B = patch_B<br>
self.transforms = transforms.ToTensor</p>
<pre><code> def __len__(self):
    'denotes the total number of samples'
    return len(self.patch_B) , len(self.patch_A)

 def __getitem__(self,index):
    'Generates one sample of data'
    #select sample
    x = self.patch_A[0]
    y = self.patch_B[0]
    
    return x,y
</code></pre>
<p>train_A_dataset = torch.utils.data.random_split(patch_A ,(0.7*len(patch_A)))</p>
<p>train_B_dataset =torch.utils.data.random_split(patch_B ,(0.7*len(patch_B)))</p>
<p>test_A_dataset =torch.utils.data.random_split(patch_A ,(len(patch_A)-len(train_A_dataset)))<br>
test_B_dataset =torch.utils.data.random_split(patch_B ,(0.7*len(patch_B))-len(train_B_dataset))</p>
<p>It gives the error:<br>
Traceback (most recent call last):<br>
File “E:/example/DataLoader.py”, line 28, in <br>
train_A_dataset = torch.utils.data.random_split(patch_A ,(0.7*len(patch_A)))<br>
File “C:\Users\Anaconda3\lib\site-packages\torch\utils\data\dataset.py”, line 271, in random_split<br>
if sum(lengths) != len(dataset):<br>
TypeError: ‘float’ object is not iterable</p>

username: ptrblck
cooked: <p>Try to pass both lengths to the <code>random_split</code> method as:</p>
<pre><code class="lang-python">train_A_dataset, test_A_dataset = torch.utils.data.random_split(patch_A ,[0.7*len(patch_A), 0.3*len(patch_A)])
</code></pre>
<p>Also, I assume you would get another error, since you are returning two lengths in your custom <code>Dataset</code> implementation:</p>
<pre><code class="lang-python">def __len__(self):
    'denotes the total number of samples'
    return len(self.patch_B) , len(self.patch_A)
</code></pre>
<p>You should instead return a single length and make sure that both patch tensors can be indexed in this range.</p>

username: CS.Enthu
cooked: <aside class="quote no-group" data-username="ptrblck" data-post="6" data-topic="82007">
<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/ptrblck/48/1823_2.png" class="avatar"> ptrblck:</div>
<blockquote>
<p><code>torch.utils.data.random_split(patch_A ,[0.7*len(patch_A), 0.3*len(patch_A)])</code></p>
</blockquote>
</aside>
<p>It give me the  error</p>
<p>Traceback (most recent call last):<br>
File “E:/example/DataLoader.py”, line 30, in <br>
train_A_dataset , test_A_dataset= torch.utils.data.random_split(patch_A, [0.7<em>len(patch_A), 0.3</em>len(patch_A)])<br>
File “C:\Users\lib\site-packages\torch\utils\data\dataset.py”, line 274, in random_split<br>
indices = randperm(sum(lengths)).tolist()<br>
TypeError: randperm(): argument ‘n’ (position 1) must be int, not float</p>

username: ptrblck
cooked: <p>Try to wrap both values in an <code>int</code> via <code>[int(0.7*len(patch_A)), int(0.3*len(patch_A))]</code></p>

username: CS.Enthu
cooked: <p>Now , its giving the error<br>
valueError: Sum of input lengths does not equal the length of the input dataset!</p>

username: ptrblck
cooked: <p>This issue might be raised, if the integer rounding produces a sum of elements which doesn’t match the original size.<br>
In that case, you could just subtract the first split:</p>
<pre><code class="lang-python">train_A_dataset, test_A_dataset = torch.utils.data.random_split(
    patch_A ,[int(0.7*len(patch_A)), int(len(patch_A) - int(0.7*len(patch_A)))])
</code></pre>
<p>or use <code>floor</code> on one length and <code>ceil</code> on the other:</p>
<pre><code class="lang-python">train_A_dataset, test_A_dataset = torch.utils.data.random_split(
    patch_A ,[math.floor(0.7*len(patch_A)), math.ceil(0.3*len(patch_A))])
</code></pre>

username: CS.Enthu
cooked: <aside class="quote no-group" data-username="ptrblck" data-post="10" data-topic="82007">
<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/ptrblck/48/1823_2.png" class="avatar"> ptrblck:</div>
<blockquote>
<pre><code class="lang-auto">train_A_dataset, test_A_dataset = torch.utils.data.random_split(
    patch_A ,[int(0.7*len(patch_A)), int(len(patch_A) - int(0.7*len(patch_A)))])
</code></pre>
</blockquote>
</aside>
<p>Thank you so much ,it worked. <img src="https://discuss.pytorch.org/images/emoji/apple/smile.png?v=12" title=":smile:" class="emoji" alt=":smile:" loading="lazy" width="20" height="20"></p>