【问题标题】:Why override Dataset instead of directly pass in input and labels, pytorch为什么要覆盖Dataset而不是直接传入输入和标签,pytorch
【发布时间】:2020-04-01 19:00:36
【问题描述】:

对不起,如果我在这里说错了——pytorch 的新手。

据我所知,获取训练数据和通过网络传递的主要方法有两种。一种是覆盖 Dataset,另一种是正确准备数据,然后对其进行迭代,如下例所示:pytorch classification example

类似

rnn(input, hidden, output)
for i in range(input.size()[0]):
    output, hidden = rnn(input[i], hidden)

另一种方法是做类似的事情

for epoch in range(epochs):
    for data, target in trainloader:
        computer model etc

在这个方法中,trainloader 来自于做类似的事情

trainloader = DataLoader(my_data)

在覆盖 getitemlen

之后

我的问题是,这些方法之间有什么区别,为什么要使用其中一种方法?此外,在我看来,覆盖 Dataset 不适用于可以说输入层大小为 100 个节点且输出为 10 个节点的东西,因为当您返回 getitem 时,它需要一对(数据,标签)。这似乎是我可能不太了解如何很好地使用 Dataset 的情况,但这就是我首先要问的原因。我想我读到了一些关于 collat​​e 函数的内容,这可能对这种情况有所帮助?

【问题讨论】:

    标签: python-3.x pytorch


    【解决方案1】:

    PyTorch 中的Dataset 类和Dataloader 类帮助我们将自己的训练数据输入网络。数据集类用于提供访问数据集中所有训练或测试样本的接口。为了实现这一点,您必须至少实现两个方法,__getitem____len__,以便每个训练样本都可以通过其索引访问。在类的初始化部分,我们加载数据集(作为浮点类型)并将它们转换为浮点炬张量。 __getitem__ 将返回特征和目标值。

    这些方法有什么区别?

    在 PyTorch 中,您可以准备数据以便 PyTorch DataLoader 可以使用它并获得一个可迭代对象,或者您可以重载默认 DataLoader 以执行一些自定义操作,例如,如果您想对文本/图像进行一些预处理,从视频剪辑等中堆叠帧。

    我们的 DataLoader 的行为类似于迭代器,因此我们可以循环遍历它并每次获取不同的小批量。

    基本示例

    from torch.utils.data import DataLoader
    
    train_loader = DataLoader(dataset=train_data, batch_size=16, shuffle=True)
    valid_loader = DataLoader(dataset=valid_data, batch_size=16, shuffle=True)
    
    # To retrieve a sample mini-batch, one can simply run the command below — 
    # it will return a list containing two tensors:
    # one for the features, another one for the labels.
    
    next(iter(train_loader))
    next(iter(valid_loader))
    

    自定义示例

    import torch
    from torch.utils.data import Dataset, Dataloader
    
    class SampleData(Dataset):
    def __init__(self, data):
            self.data = torch.FloatTensor(data.values.astype('float'))
    
        def __len__(self):
            return len(self.data)
    
        def __getitem__(self, index):
            target = self.data[index][-1]
            data_val = self.data[index] [:-1]
            return data_val,target
    
    train_dataset = SampleData(train_data)
    valid_dataset = SampleData(valid_data)
    
    
    device = "cuda" if torch.cuda.is_available() else "cpu"
    kwargs = {'num_workers': 1, 'pin_memory': True} if device=='cuda' else {}
    train_loader = DataLoader(train_dataset, batch_size=train_batch_size, shuffle=True, **kwargs)
    test_loader = DataLoader(valid_dataset, batch_size=test_batch_size, shuffle=False, **kwargs)
    
    

    你为什么要使用一个而不是另一个?

    这完全取决于您的用例和您想要的控制量。 PyTorch 为您提供了所有的权力,您将决定您想要多少。假设你正在解决一个简单的图像分类问题,那么,

    您可以简单地将所有图像放在一个根文件夹中,每个子文件夹包含属于特定类别的样本,并用类别名称标记文件夹。在训练时,我们只需要指定根文件夹的路径,PyTorch DataLoader 就会自动从每个文件夹中挑选图像并训练模型。

    但另一方面,如果您在大型视频文件中对视频剪辑或视频序列进行分类,通常称为视频标记,那么您需要编写自定义 DataLoader 以从视频中加载帧,将其堆叠并提供输入数据加载器。

    使用可以在下面找到一些有用的链接以供进一步参考:

    https://pytorch.org/docs/stable/data.html

    https://stanford.edu/~shervine/blog/pytorch-how-to-generate-data-parallel

    https://pytorch.org/tutorials/beginner/data_loading_tutorial.html

    【讨论】:

    • 您将如何准备数据以便数据加载器可以使用它?那是什么格式?
    • 这个link会回答你所有的问题。
    猜你喜欢
    • 1970-01-01
    • 2021-04-22
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    • 2011-05-22
    • 2019-04-02
    • 1970-01-01
    相关资源
    最近更新 更多