使用Pytorch或Python将包含图像的目录拆分为子文件夹
我有一个目录,其中有两个子目录。每个子目录都有一组图像。这些子目录还指定了两类图像 我想有3个目录(训练,验证,测试),在这3个子目录中的每一个子目录,我想每个类的2个子目录分别与图像 我想通过随机抽样将图像的数量分成train、val和test目录。因此,大约60%的图像用于训练,20,val和测试中的20 初始结构:使用Pytorch或Python将包含图像的目录拆分为子文件夹,python,pytorch,Python,Pytorch,我有一个目录,其中有两个子目录。每个子目录都有一组图像。这些子目录还指定了两类图像 我想有3个目录(训练,验证,测试),在这3个子目录中的每一个子目录,我想每个类的2个子目录分别与图像 我想通过随机抽样将图像的数量分成train、val和test目录。因此,大约60%的图像用于训练,20,val和测试中的20 初始结构: Main_folder - Good - Bad 我想要的是: Main_folder: - Train - Good - Bad - Val -
Main_folder
- Good
- Bad
我想要的是:
Main_folder:
- Train
- Good
- Bad
- Val
- Good
- Bad
- Test
- Good
- Bad
我想通过随机分配图像将每个子目录拆分为其中的两个目录(我不确定哪些是好的,哪些是坏的,但我非常确定您可以使用scipy train test split函数 您可以在中找到详细信息
我猜它只创建了两个图像集示例,如train test。但是,您可以再次划分测试部分以实现您的目标。此外,我记得您还可以在函数中设置train test百分比。此问题有两个部分:
os
包的一个简单用例,在别处得到了回答。对于第1个,算法是(伪代码):
在这种情况下,每个子集中的好/坏比率将与原始输入中的好/坏比率相同,这不是一个坏主意。拆分可以通过其他方式完成,但这是一个广泛的讨论,我在这里不进行讨论。然而,您可能需要至少100个图像或更多的图像才能工作-仅将40个图像拆分为6个子集实际上没有多大用处nse,它们太小了。您可以使用SKLearn的train\u test\u split+海底采样器,如下所示:
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)),
}
有一种
pytorch
方法可以做到这一点(我建议使用单个库来完成如此简单的任务)
创建数据集
在torchvision中有一个预先制作的,即
只需像这样使用它:
import torchvision
dataset = torchvision.datasets.ImageFolder("./my_data")
这将创建一个数据集,其中Good
文件夹中的每个图像分别有0
标签和Bad
标签
分为培训、验证、测试
不需要sklearn
这样一个简单的工作+torch
也有大部分的numpy
功能,我宁愿只使用一个库而不是3个库(尽管train\u test\u split
可以连续使用两次,类似于提议的那样)
这将是:
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))
这将为substrandomsampler
和torch.utils.data.DataLoader
创建索引。
因此,再次类似于:
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\u size
和DataLoader
的其他参数,查看是否需要更多信息。dataset.targets如何?它是一个torchvision.datasets.ImageFolder加载器:dataset=torchvision.datasets.ImageFolder(train\u dir,transform=My\u transforms)
通过调用datasettargets,您将获得给定图像的目标,即该图像所在的文件夹名称。但是,这不会将拆分保存到文件夹中,对吗?不,为什么会这样?啊,好的。从问题的措辞来看,这就是OP想要的。谢谢
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)
),
}