我想知道如何torch.utils.data.DataLoader在 PyTorch 中使用,尤其是在多工人情况下。
我发现一个批次的输出DataLoader总是来自一个工人。我预计 DataLoader 中有一个队列,用于存储来自所有工作人员的数据,而 DataLoader 将它们在队列中打乱以输出随机批处理数据。我认为这是tf.data.DatasetTensorflow 中的方法。我们可以在 PyTorch 中实现类似的功能吗?我想Tfrecord通过使用多个工作人员从大序列化文件(如)加载数据集。在这种情况下,在一批中混合源文件,这意味着混合工作器的源,很重要。
请参考以下代码:
import random
import time
import torch
class MyDataset(torch.utils.data.Dataset):
def __len__(self):
return 50
def __getitem__(self, idx):
info = torch.utils.data.get_worker_info()
time.sleep(random.uniform(0, 1))
print("[{}]:{}".format(info.id, idx))
return idx, info.id
if __name__ == '__main__':
dataset = MyDataset()
dataloader = torch.utils.data.DataLoader(dataset, batch_size=5, shuffle=False, num_workers=2)
for batch in dataloader:
print(batch)
Run Code Online (Sandbox Code Playgroud)
输出:
[0]:0
[1]:5
[0]:1
[1]:6
[0]:2
[0]:3
[1]:7
[0]:4
[tensor([0, 1, 2, 3, 4]), tensor([0, 0, 0, …Run Code Online (Sandbox Code Playgroud) 当 num_workers > 0 时,PyTorch Dataloader 挂起。代码挂起仅与500 MGPU 内存使用有关。
系统信息:NVIDIA-SMI 418.56 Driver Version: 418.56 CUDA Version: 10.1。pytorch1.5 或 pytorch1.6 出现同样的问题,代码在 anaconda envs 中运行。
请注意,当我在终端中将脚本作为 运行时会出现此错误 python main.py,但是当我在 Pycharm 或 VScode 上调试相同的代码时,或者当我在其他机器上运行相同的代码(在终端中)时,一切正常。关于这个原因的任何想法?
这是我ctrl c在终端中输入代码时的跟踪:
File "train.py", line 226, in main
train_domain_adaptation(model, source_loader, target_loader, val_loader,
File "/home/zhangyu/codes/person_seg/IntraDA/ADVENT/advent/domain_adaptation/train_UDA.py", line 326, in train_domain_adaptation
train_advent(model, trainloader, targetloader, val_loader, cfg, group=group, fk_loader=fk_loader)
File "/home/zhangyu/codes/person_seg/IntraDA/ADVENT/advent/domain_adaptation/train_UDA.py", line 114, in train_advent
_, (images_source, labels, src_names, voc_ids, _) = trainloader_iter.__next__()
File "/home/zhangyu/anaconda3/envs/pt16/lib/python3.8/site-packages/torch/utils/data/dataloader.py", line …Run Code Online (Sandbox Code Playgroud) 希望有人可以帮助我解决这个小问题,我现在无法弄清楚。
问题陈述:
为了在我的DataLoader. 这DataLoader是在单独的路径中定义的/loaders。在我的resolvers.js文件中,我可以使用dataSources.userAPI.getAllUsers(). 但是如何在我的服务器端应用程序中的任何其他地方访问它,比如我/loaders文件夹中的fe ?我只是不知道如何访问我的上下文对象,然后将令牌传递给DataLoader,然后从我的 API 加载数据,然后将此数据传递给我的resolvers.js文件。非常感谢每一个帮助,我不知道如何解决这个简单的事情..谢谢!
代码来了:
索引.js
const express = require('express');
const connectDB = require('./config/db');
const path = require('path');
var app = express();
const cors = require('cors')
const axios = require('axios')
// apollo graphql
const { ApolloServer } = require('apollo-server-express');
const DataLoader = require('dataloader')
const { userDataLoader } = require('./loaders/index')
// Connect Database
connectDB();
// gql import
const typeDefs = require('./schema'); …Run Code Online (Sandbox Code Playgroud) 假设我正在使用以下调用:
trainset = torchvision.datasets.ImageFolder(root="imgs/", transform=transform)
trainloader = torch.utils.data.DataLoader(trainset,batch_size=4,shuffle=True,num_workers=1)
Run Code Online (Sandbox Code Playgroud)
据我所知,这将 定义trainset为由文件夹“images”中的所有图像组成,并具有由特定文件夹位置定义的标签。
我的问题是 - 是否有任何直接/简单的方法可以将 定义trainset为该文件夹中图像的子样本?例如,定义trainset为每个子文件夹中 10 张图像的随机样本?
我正在使用线圈 100 数据集,其中包含 100 个对象的图像,每个对象通过将每个图像旋转 5 度,从固定相机拍摄的每个对象有 72 个图像。以下是我正在使用的文件夹结构:
数据/火车/obj1/obj01_0.png, obj01_5.png ... obj01_355.png
。
.
数据/火车/obj85/obj85_0.png, obj85_5.png ... obj85_355.png
。
.
数据/测试/obj86/obj86_0.ong, obj86_5.png ... obj86_355.png
。
.
数据/测试/obj100/obj100_0.ong, obj100_5.png ... obj100_355.png
我使用了 imageloader 和 dataloader 类。训练和测试数据集正确加载,我可以打印类名。
train_path = 'data/train/'
test_path = 'data/test/'
data_transforms = {
transforms.Compose([
transforms.Resize(224, 224),
transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])
}
train_data = torchvision.datasets.ImageFolder(
root=train_path,
transform= data_transforms
)
test_data = torchvision.datasets.ImageFolder(
root = test_path,
transform = data_transforms
)
train_loader = torch.utils.data.DataLoader(
train_data,
batch_size=None,
num_workers=1, …Run Code Online (Sandbox Code Playgroud) 我正在寻找一个优化的解决方案来使用 pytorch 数据加载器加载多个巨大的 .npy 文件。我目前正在使用以下方法,为每个时期的每个文件创建一个新的数据加载器。
我的数据加载器是这样的:
class GetData(torch.utils.data.Dataset):
def __init__(self, data_path, target_path, transform=None):
with open(data_path, 'rb') as train_pkl_file:
data = pickle.load(train_pkl_file)
self.data = torch.from_numpy(data).float()
with open(target_path, 'rb') as target_pkl_file:
targets = pickle.load(target_pkl_file)
self.targets = torch.from_numpy(targets).float()
def __getitem__(self, index):
x = self.data[index]
y = self.targets[index]
return index, x, y
def __len__(self):
num_images = self.data.shape[0]
return num_images
Run Code Online (Sandbox Code Playgroud)
我有一个 npy 文件列表:
list1 = ['d1.npy', 'd2.npy','d3.npy']
list1 = ['s1.npy', 's2.npy','s3.npy']
Run Code Online (Sandbox Code Playgroud)
我创建了一个数据加载器,它给出了文件名
class MyDataset(torch.utils.data.Dataset):
def __init__(self,flist):
self.npy_list1 = flist1
self.npy_list2 = flist2
def __getitem__(self, idx): …Run Code Online (Sandbox Code Playgroud) 我已经多次使用 pytorch 数据加载器的 shuffle 选项。但我想知道这种 shuffle 何时发生以及它是否在迭代期间动态执行。以下面的代码为例:
namesDataset = NamesDataset()
namesTrainLoader = DataLoader(namesDataset, batch_size=16, shuffle=True)
for batch_data in namesTrainLoader:
print(batch_data)
Run Code Online (Sandbox Code Playgroud)
当我们定义“namesTrainLoader”时,是否意味着shuffle结束,接下来的迭代将基于固定的数据顺序?定义了 namesTrainLoader 后,for 循环中会不会有任何随机性?
我试图用一些特殊值替换“batch_data”的一半:
for batch_data in namesTrainLoader:
batch_data[?8] = special_val
pre = model(batch_data)
Run Code Online (Sandbox Code Playgroud)
假设将有无数个 epoch,“模型”最终会看到“namesTrainLoader”中的所有数据吗?还是说“namesTrainLoader”的一半数据实际上丢给了“model”?
我有两个数据加载器,我想合并它们而不重新定义数据集,在我的例子中是 train_dataset 和 val_dataset。
train_loader = DataLoader(train_dataset, batch_size = 512, drop_last=True,shuffle=True)
val_loader = DataLoader(val_dataset, batch_size = 512, drop_last=False)
Run Code Online (Sandbox Code Playgroud)
想要的结果:
train_loader = train_loader + val_loader
Run Code Online (Sandbox Code Playgroud) 我有一个 torch.utils.data.DataLoader。我使用以下代码创建了它们。
transform_train = transforms.Compose([
transforms.RandomCrop(32, padding=4),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
])
trainset = CIFAR100WithIdx(root='.',
train=True,
download=True,
transform=transform_train,
rand_fraction=args.rand_fraction)
train_loader = torch.utils.data.DataLoader(trainset,
batch_size=args.batch_size,
shuffle=True,
num_workers=args.workers)
Run Code Online (Sandbox Code Playgroud)
但是当我运行以下代码时出现错误。
train_loader_2 = []
for i, (inputs, target, index_dataset) in enumerate(train_loader):
train_loader_2.append((inputs, target, index_dataset))
Run Code Online (Sandbox Code Playgroud)
错误是
Traceback (most recent call last):
File "main_superloss.py", line 460, in <module>
main()
File "main_superloss.py", line 456, in main
main_worker(args)
File "main_superloss.py", line 374, in main_worker
train_loader, val_loader = get_train_and_val_loader(args)
File "main_superloss.py", line 120, in get_train_and_val_loader
for …Run Code Online (Sandbox Code Playgroud) PyTorch/Numpy 中存在一个错误,即当与 a DataLoader(即设置num_workers > 1)并行加载批次时,每个工作线程使用相同的 NumPy 随机种子,导致并行批次之间应用的任何随机函数都是相同的。这可以通过将种子生成器传递给worker_init_fn参数来解决,如下所示。
然而,这个问题在多个时期仍然存在。
最小的例子:
import numpy as np
from torch.utils.data import Dataset, DataLoader
class RandomDataset(Dataset):
def __getitem__(self, index):
return np.random.randint(0, 1000, 2)
def __len__(self):
return 4
dataset = RandomDataset()
dataloader = DataLoader(dataset, batch_size=1,
num_workers=2,
worker_init_fn = lambda x: np.random.seed(x))
for epoch in range(3):
print(f'\nEpoch {epoch}')
for batch in dataloader:
print(batch)
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,虽然一个时期内的并行批次现在会产生不同的结果,但跨时期的结果是相同的:
Epoch 0
tensor([[684, 559]])
tensor([[ 37, 235]])
tensor([[629, 192]])
tensor([[908, 72]]) …Run Code Online (Sandbox Code Playgroud) dataloader ×10
pytorch ×9
python ×3
dataset ×2
numpy ×2
apollo ×1
graphql ×1
javascript ×1
python-3.x ×1
shuffle ×1