How to split the datasets in folder wise in pytorch?

sampa: <p>There are 46 benign (B) patients and 44 malignant (M) patients. Each patient has 4 images. I want to take 60% patient as train, 20% as valid and 20% for test. The split should always have been done patient-level, meaning images of the same patient should either belong to the train or test set but not be shared among them.<br>
So Train – B: 28 patients + M: 26 patients<br>
Valid- B: 9 patients  + M: 9 patients<br>
Test- B: 9 patients + M: 9 patients</p>
<p>How to split the datasets in folder wise in pytorch?</p>

ptrblck: <p>I would recommend to perform the splitting before creating the <code>Datasets</code> in PyTorch, e.g. with <a href="https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GroupShuffleSplit.html"><code>sklearn.model_selection.GroupShuffleSplit</code></a>.</p>

sampa: <p><a class="mention" href="/u/ptrblck">@ptrblck</a> Thanks for reply.<br>
Can you please tell me how to use it in my code?<br>
In my case, dataset is splitting in image wise not folder wise.</p>
<pre><code class="lang-auto">master= datasets.ImageFolder(data_dir,transform=train_transforms)

valid_size = 0.2
test_size = 0.2
num_train = len(master)
indices = list(range(num_train))
np.random.shuffle(indices)
valid_split = int(np.floor((valid_size) * num_train))
test_split = int(np.floor((valid_size+test_size) * num_train))
valid_idx, test_idx, train_idx = indices[:valid_split], indices[valid_split:test_split], indices[test_split:]

num_workers = 0
train_loader = torch.utils.data.DataLoader(train_idx, batch_size=64,
     num_workers=num_workers)
valid_loader = torch.utils.data.DataLoader(valid_idx, batch_size=64, 
     num_workers=num_workers)
test_loader = torch.utils.data.DataLoader(test_idx, batch_size=64, 
     num_workers=num_workers, shuffle=False)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
</code></pre>

talhaanwarch: <p><a class="mention" href="/u/ptrblck">@ptrblck</a> can you please check the code. Is it correct?</p>
<blockquote>
<p>dataset=torchvision.datasets.ImageFolder(‘images/’)<br>
kfold = LeaveOneGroupOut()<br>
for fold,(train_idx,val_idx) in enumerate(kfold.split(dataset,groups=dataset.targets)):<br>
train_subsampler = torch.utils.data.SubsetRandomSampler(train_idx)<br>
val_subsampler = torch.utils.data.SubsetRandomSampler(val_idx)</p>
</blockquote>

ptrblck: <p><code>LeaveOneGoupOut</code> uses the <code>groups</code> argument for the splitting as described in the docs:</p>
<blockquote>
<p>groups: array-like of shape (n_samples,)<br>
Group labels for the samples used while splitting the dataset into train/test set. This ‘groups’ parameter must always be specified to calculate the number of splits, though the other parameters can be omitted.</p>
</blockquote>
<p>This <code>groups</code> argument is often used as an additional attribute of the dataset, e.g. in case you are dealing with different patients in a medical dataset and would like to avoid mixing samples from one patient into the training and validation dataset.<br>
In your use case you are using the <code>dataset.targets</code> as the <code>groups</code> argument, so I would assume that you explicitly want to keep some targets only in the training dataset and others in the validation data (which would be uncommon).</p>

talhaanwarch: <p>yes, i agree. in my scenario, label is my folder name and let suppose i have 10 folder, mean 10 labels, i want 9 labels/folders in training and 1 in test. I think OP asked the same that he want to split based on folders.</p>