What should I output when defining an image-to-value dataset?

username: SouthTorch
cooked: <p>This is the first time I define my own dataset<br>
I want to define a dataset, each entry of which is one image associated with a value.<br>
When I define the dataset, should I define the self.samples as an array of:<br>
one string containing the image disk path, and one floating value<br>
or<br>
the real image RGB value matrix and one floating value<br>
?<br>
When you call the dataset use the following syntax:</p>
<pre><code class="lang-auto">train_data=torchvision.datasets.MYDATA('../mydata', train=True, download=True,
                   transform=torchvision.transforms.Compose([
                       torchvision.transforms.Resize((h_image, w_image)),
                       torchvision.transforms.ToTensor()
                   ]))
</code></pre>
<p>or</p>
<pre><code class="lang-auto">train_data=MYDATA('../mydata', train=True, download=True,
                   transform=torchvision.transforms.Compose([
                       torchvision.transforms.Resize((h_image, w_image)),
                       torchvision.transforms.ToTensor()
                   ]))
</code></pre>
<p>What conditions do you need to meet to use the transforms utilities? like: rotate and flip?<br>
Hope I described my question clearly.<br>
Thanks.</p>

username: ptrblck
cooked: <p>I would recommend to stick to the first approach of storing the paths only and lazily load the samples in the <code>__getitem__</code> method as it will save memory.<br>
You would then have to initialize your dataset using its <code>__init__</code> method so the second call looks more correct although you would have to make sure all arguments are really expected (e.g. the <code>download</code> argument might not be needed).</p>

username: SouthTorch
cooked: <p>Thanks.</p>
<p>So, you are suggesting the following?:<br>
Define Data:</p>
<pre><code class="lang-auto">class MYDATA(Dataset):
    def __init__(self, root='folder_path', parm1, parm2, parm3, parm4, train=True, data_augmentation=False)
        super(MYDATA, self).__init__()
        if parm1:
            ...
        if parm2:
            ...
        if parm3:
            ...
        if parm4:
            ...
        if train:
            ...
        else:
            ...
        #after a bunch of no_matter_what operations
        self.samples = [(path, value), ...]

    def __len__():
        return len(self.samples)

    def __getitem__(self, idx):
        image = PIL.Image.open(self.samples[idx][0])
        imagearray = numpy.asarray(image)
        return (imagearray, sefl.samples[idx][1])
</code></pre>
<p>Get Data:</p>
<pre><code class="lang-auto">train_data=MYDATA('../mydata', train=True, parm1=parm1,
                   transform=torchvision.transforms.Compose([
                       torchvision.transforms.Resize((h_image, w_image)),
                       torchvision.transforms.ToTensor()
                   ]))
</code></pre>
<p>What I understood now is:<br>
1, I can prepare my data in <strong>init</strong>() according to some conditions, for example: parm1, parm2, …</p>
<p>What don’t understand is:<br>
1, When is the <strong>getitem</strong>() called, because it is never been called explicitly in the Get Data code<br>
2, I never define any behavior of transforms in MYDATA class, can I still use the torchvision.transforms tools?<br>
3, If I want to do data_augmentation, for example, add some rotated and flipped copy of the same image, and associated them with the same value, should I do it explicitly in the <strong>init</strong>()?<br>
4, Can torchvision.transforms handle the data_augmentation operation for me? or it can only change (rotate, flip) and replace the original data entry instead of adding some new entries?<br>
5, If I defined all things in MYDATA class <strong>init</strong>(), including data augmentation, and defined the converting image path to array in <strong>getitem</strong>(), do I still need to use those torchvision.transforms calls? What the torchvision.transforms.ToTensor() did exactly?</p>
<p>I think that is all questions I can think of right now. (It is alot, ^_^)</p>
<p>Thank you very much!</p>

username: ptrblck
cooked: <ol>
<li>The <code>__getitem__</code> function is called then the <code>Dataset</code> is indexed either directly:</li>
</ol>
<pre><code class="lang-python">x, y = dataset[index]
</code></pre>
<p>or from the <code>DataLoader</code> by e.g. iterating it:</p>
<pre><code class="lang-python">for data, target in loader:
    ...
</code></pre>
<p>Internally the <code>DataLoader</code> will use the <code>sampler</code> to create indices and index the internal <code>Dataset</code> with it.</p>
<ol start="2">
<li>Yes, you should pass the transformations as an object to the <code>Dataset.__init__</code> method and use it in the <code>__gettitem__</code>. Usually something like this is used:</li>
</ol>
<pre><code class="lang-python">def __init__(self, transform=None):
    self.data = ...
    self.transform = transform
    ...

def __getitem__(self, index):
    x = self.data[index]
    if self.transform:
        x = self.transform(x)
    ...
    return x, y
</code></pre>
<ol start="3">
<li>
<p>This would be a valid approach, but usually data augmentation is done on-the-fly and a single sample is returned in the <code>__getitem__</code> method.</p>
</li>
<li>
<p>Yes, <code>torchvision.transforms</code> provide also transformations for rotation etc.</p>
</li>
<li>
<p>Yes, you need to call the transformations in the <code>__getitem__</code>.</p>
</li>
</ol>

username: SouthTorch
cooked: <p>Thanks! <img src="https://discuss.pytorch.org/images/emoji/apple/grinning.png?v=12" title=":grinning:" class="emoji" alt=":grinning:" loading="lazy" width="20" height="20"> <img src="https://discuss.pytorch.org/images/emoji/apple/grinning.png?v=12" title=":grinning:" class="emoji" alt=":grinning:" loading="lazy" width="20" height="20"> <img src="https://discuss.pytorch.org/images/emoji/apple/grinning.png?v=12" title=":grinning:" class="emoji" alt=":grinning:" loading="lazy" width="20" height="20"> <img src="https://discuss.pytorch.org/images/emoji/apple/grinning.png?v=12" title=":grinning:" class="emoji" alt=":grinning:" loading="lazy" width="20" height="20"> <img src="https://discuss.pytorch.org/images/emoji/apple/grinning.png?v=12" title=":grinning:" class="emoji" alt=":grinning:" loading="lazy" width="20" height="20"> <img src="https://discuss.pytorch.org/images/emoji/apple/grinning.png?v=12" title=":grinning:" class="emoji" alt=":grinning:" loading="lazy" width="20" height="20"> <img src="https://discuss.pytorch.org/images/emoji/apple/grinning.png?v=12" title=":grinning:" class="emoji" alt=":grinning:" loading="lazy" width="20" height="20"> <img src="https://discuss.pytorch.org/images/emoji/apple/grinning.png?v=12" title=":grinning:" class="emoji" alt=":grinning:" loading="lazy" width="20" height="20"></p>

username: SouthTorch
cooked: <p>If I want to use <code>data.to(device)</code> later to move the data into GPU, do I need to write anything in MYDATA class? Thanks.</p>

username: ptrblck
cooked: <p>No, the common approach is to move the data to the GPU in the <code>DataLoader</code> loop.</p>