假设我有两个数据集,其中一个数据集包含100个项目,而第二个数据集包含5000个项目。
现在,我希望在训练过程中,我的模型能从数据集中看到的数据与从数据集中得到的数据一样多。
在Tensorflow中我可以这样做:
dataset = tf.data.experimental.sample_from_datasets(
[dataset_one, dataset_two], weights=[50,1], seed=None
)
在PyTorch中是否有替代方法可以做到这一点?
我认为通过创建自定义数据集来实现这一点不太困难(不起作用的示例)
from torch.utils.data import Dataset
class SampleDataset(Dataset):
def __init__(self, datasets, weights):
self.datasets = datasets
self.weights = weights
def __len__(self):
return sum([len(dataset) for dataset in self.datasets])
def __getitem__(self, idx):
# sample a random number and based on that sample an item
return self.datasets[dataset_idx][sample_idx]
但是,这似乎很普遍。已经有类似的东西了吗?
我认为PyTorch中没有直接的等效项。
但是,有一个名为的函数,该函数torch.utils.data.WeightedRandomSampler
根据概率列表对索引进行采样。您可以将其与torch.data.utils.ConcatDataset
和torch.utils.data.DataLoader
的sampler
选项结合使用。
我将给出一个包含两个数据集的示例:SetA
具有500个元素,SetB
而只有10个元素。
首先,您可以使用以下命令创建所有数据集的串联ConcaDataset
:
ds = ConcatDataset([SetA(), SetB()])
然后,我们需要对其进行采样。问题是,您不能WeightedRandomSampler
[50, 1]
像Tensorflow中那样仅仅给出。解决方法是,创建一个概率列表,其长度与总数据集的大小相同。
此示例的相应概率列表为:
dist = np.array([1/51]*500 + [50/51]*10)
本质上,前500个索引(即“指向”的索引SetA
)被选择的概率为1/51,而随后的10个索引(即中的索引SetB
)被选择的概率为50/51(即由于中的元素较少SetB
,因此进行了采样。这是理想的结果!)
我们可以从该分布创建一个采样器:
WeightedRandomSampler(dist, 10)
其中10是采样元素的数量。我将放置最小数据集的大小,否则您可能会在同一时期多次遍历相同的数据点...
最后,我们只需使用数据集和采样器实例化数据加载器:
dl = DataLoader(ds, sampler=sampler)
总结一下:
ds = ConcatDataset([SetA(), SetB()])
dist = np.array([1/51]*500 + [50/51]*10)
sampler = WeightedRandomSampler(dist, 10)
dl = DataLoader(ds, sampler=sampler)
编辑,以获取任意数量的数据集:
sets = [SetA(), SetB(), SetC()]
ds = ConcatDataset(sets)
dist = np.concatenate([[(len(ds) - len(s))/len(ds)]*len(s) for s in sets])
sampler = WeightedRandomSampler(weights=dist, num_samplesmin([len(s) for s in sets])
dl = DataLoader(ds, sampler=sampler)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句