我如何在 PyTorch 中为窦实现 __getitem__ 方法

How can i implement the __getitem__ method in PyTorch for the sinus

我从 PyTorch 开始,我正在尝试创建一个预测 x 正弦曲线的网络。我尝试创建这样的数据集:

 class SinusDataset(Dataset):

    def __init__(self, size: int = 1000):
        self.size = size

    def __len__(self):
        return self.size


    def __getitem__(self, idx: int)->Tensor:
        if idx > self.size:
            raise ValueError
        
        return idx, math.sin(idx)

我认为这不是实现它的正确方法。我应该如何实施“__get__”方法?

您可以在 init 上初始化您的输入和标签,并将它们保存在 lists 中。然后,在您的 __getitem__ 函数中,使用提供的 idx 整数从这两个中选择实例。类似于:

class SinusDataset(Dataset):
    def __init__(self, size: int = 1000):
        self.x = torch.linspace(0, 1, size)
        self.y = torch.sin(self.x)

    def __len__(self) -> int:
        return len(self.x)

    def __getitem__(self, idx: int):
        return return self.x[idx][None], self.y[idx][None]

然后你可以通过包装一个 torch.utils.data.DataLoader:

来使用数据集
>>> dl = DataLoader(SinusDataset(100), batch_size=4, shuffle=True)

>>> for x, y in dl:
...     print(x, y)
...     break
tensor([0.2452, 0.6116, 0.0791, 0.6667]) tensor([0.2428, 0.5742, 0.0790, 0.6184])

在这种情况下继承自torch.utils.data.TensorDataset directly. This comes with both __len__ and __getitem__ implemented for you (see source更合适):

class SinusDataset(TensorDataset):
    def __init__(self, size: int = 1000):
        x = torch.linspace(0, 1, 1000)[:,None]
        y = torch.sin(x)[:,None]
        super().__init__(x, y)

这稍微高级一些,但最好的做法是继承最接近的内置 torch.utils.data.Dataset class 而不是自己编写相同的方法。


推理示例:

>>> model = nn.Sequential(nn.Linear(1, 4), 
                          nn.ReLU(), 
                          nn.Linear(4, 1))

>>> x, y = next(iter(dl))
>>> model(x)
tensor([[-0.0640],
        [ 0.1461],
        [-0.0882],
        [ 0.2259]], grad_fn=<AddmmBackward>)