Разделение каталога с изображениями на подпапки с использованием Pytorch или Python - PullRequest
1 голос
/ 25 сентября 2019

У меня есть каталог с двумя подкаталогами.Каждый подкаталог имеет кучу изображений.Эти поддиректории также указывают два класса изображений.

Я хочу иметь 3 каталога (поезд, проверка, тест) и в каждом из этих 3 подкаталогов я хочу 2 подкаталога каждого класса соответственно с изображениями.

Я хочу разделить изображения no.of на каталоги train, val, test по случайной выборке.Так что около 60% изображений отправляются на тренировку, 20, val и 20 в тест.

Исходная структура:

Main_folder
 - Good
 - Bad 

Что я хочу:

Main_folder: 
 - Train 
  - Good
  - Bad
 - Val
  - Good 
  - Bad
 - Test 
  - Good 
  - Bad

Я хочу разбить каждый подкаталог на два каталога в нем со случайным назначением изображений (

Ответы [ 4 ]

0 голосов
/ 26 сентября 2019

Есть способ pytorch сделать это (и я бы посоветовал использовать одну библиотеку для такой простой задачи).

Создание набора данных

Есть готовый внутри torchvision, а именно ImageFolder.

Просто используйте его так:

import torchvision

dataset = torchvision.datasets.ImageFolder("./my_data")

Это создаст набор данных, где в папке Good есть 0Метка и Bad имеет метку 1 для каждого изображения в этой папке соответственно.

Разделение на поезд, проверку, тест

Нет необходимости в sklearn для такой простой работы +torch также имеет большую часть функциональности numpy, и я бы предпочел придерживаться одной библиотеки вместо 3 (хотя train_test_split можно использовать дважды подряд, аналогично тому, что предлагал @ ESZ ).

ИМО проще:

def get_subset(indices, start, end):
    return indices[start : start + end]


TRAIN_PCT, VALIDATION_PCT = 0.6, 0.2  # rest will go for test
train_count = int(len(dataset) * TRAIN_PCT)
validation_count = int(len(dataset) * TRAIN_PCT)

indices = torch.randperm(len(dataset))

train_indices = get_subset(indices, 0, train_count)
validation_indices = get_subset(indices, train_count, validation_count)
test_indices = get_subset(indices, train_count + validation_count, len(dataset))

Это создаст индексы для SubsetRandomSampler и torch.utils.data.DataLoader.Итак, аналогично @ ESZ еще раз:

dataloaders = {
    "train": torch.utils.data.DataLoader(
        dataset, sampler=SubsetRandomSampler(train_indices)
    ),
    "validation": torch.utils.data.DataLoader(
        dataset, sampler=SubsetRandomSampler(validation_indices)
    ),
    "test": torch.utils.data.DataLoader(
        dataset, sampler=SubsetRandomSampler(test_indices)
    ),
}

Вы можете указать batch_size и другой аргумент для DataLoader, см. документацию , если вам нужно большеИнформация.

0 голосов
/ 25 сентября 2019

Эта проблема состоит из двух частей:

  1. По заданному списку файлов найдите алгоритм, который случайным образом генерирует подмножества с заданной пропорцией.
  2. Перемешайте действительные файлы на основесгенерированные подмножества.

Two - тривиальный вариант использования пакета os, ответ на который есть в другом месте.Для 1 алгоритм (псевдокод):

for d in [Good, Bad]:
    n['all'] = total images in d
    for c in [Train, Val, Test]:
        if not last_item:
            n[c] = round(n['all'] * proportion[c])
        else:
            n[c] = n['all'] - all other n's

    shuffle list of all images in d
    for c in [Train, Val, Test]:
        take first n[c] images and put them in c
        remove them from d

В этом случае отношение Хорошее / Плохое будет таким же в каждом подмножестве, что и в исходном вводе, что является неплохой идеей.Раскол может быть сделан другими способами, но я не буду вдаваться в это широкое обсуждение.Однако для этого может потребоваться не менее 100 или более изображений - разделение всего лишь 40 изображений на 6 подмножеств не имеет особого смысла, они будут слишком маленькими.

0 голосов
/ 25 сентября 2019

Вы можете использовать train_test_split + SubSetRandomSampler SKLearn из факела следующим образом:

from torch.utils.data.sampler import SubsetRandomSampler
from sklearn.model_selection import train_test_split
from torch.utils.data.sampler import SubsetRandomSampler
valid_size_and_test = 0.4 # then I will keep 0.1 for testing 

## split the dataset into train and rest data
targets = dataset.targets

train_idx, rest_idx = train_test_split(np.arange(len(targets)), test_size= 
                    valid_size_and_test, random_state=42, shuffle=True, stratify=targets)
test_size = int(len(rest_idx) * valid_size_and_test)
valid_idx, test_idx = rest_idx[:test_size], rest_idx[test_size:]

dataloaders = {'trainLoader' : torch.utils.data.DataLoader(dataset,batch_size=32,sampler=SubsetRandomSampler(train_idx)),
               'validLoader' : torch.utils.data.DataLoader(dataset,batch_size=32,sampler=SubsetRandomSampler(valid_idx)),
               'testLoader' :  torch.utils.data.DataLoader(dataset,batch_size=32,sampler=SubsetRandomSampler(test_idx)),
              }
0 голосов
/ 25 сентября 2019

Ну, я не уверен насчет вещей Good-Bad, но я почти уверен, что вы можете использовать функцию разделения теста scipy train.

Подробную информацию можно найти в sklearn.model_selection..train_test_split Я предполагаю, что он создает только два образца наборов изображений, таких как train-test.Тем не менее, вы можете разделить тестовую часть еще раз, чтобы достичь своей цели.Кроме того, насколько я помню, вы также можете установить процент проверки поезда в функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...