rwa*_*ace 5 pytorch pytorch-dataloader
我正在尝试让 PyTorch 与 DataLoader 一起使用,据说这是处理小批量的最简单方法,在某些情况下这是获得最佳性能所必需的。
DataLoader 想要一个数据集作为输入。
大多数关于数据集的文档都假设您正在使用现成的标准数据集(例如 MNIST),或者至少使用图像,并且可以使用现有的机器作为黑匣子。我正在处理自己生成的非图像数据。我当前最好的尝试是,将有关如何执行此操作的文档提炼为最小的测试用例:
import torch
from torch import nn
from torch.utils.data import Dataset, DataLoader
class Dataset1(Dataset):
def __init__(self):
pass
def __len__(self):
return 80
def __getitem__(self, i):
# actual data is blank, just to test the mechanics of Dataset
return [0.0, 0.0, 0.0], 1.0
train_dataloader = DataLoader(Dataset1(), batch_size=8)
for X, y in train_dataloader:
print(f"X: {X}")
print(f"y: {y.shape} {y.dtype} {y}")
break
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.layers = nn.Sequential(
nn.Linear(3, 10),
nn.ReLU(),
nn.Linear(10, 1),
nn.Sigmoid(),
)
def forward(self, x):
return self.layers(x)
device = torch.device("cpu")
model = Net().to(device)
criterion = nn.BCELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
for epoch in range(10):
for X, y in train_dataloader:
X, y = X.to(device), y.to(device)
pred = model(X)
loss = criterion(pred, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
Run Code Online (Sandbox Code Playgroud)
上述程序的输出是:
X: [tensor([0., 0., 0., 0., 0., 0., 0., 0.], dtype=torch.float64), tensor([0., 0., 0., 0., 0., 0., 0., 0.], dtype=torch.float64), tensor([0., 0., 0., 0., 0., 0., 0., 0.], dtype=torch.float64)]
y: torch.Size([8]) torch.float64 tensor([1., 1., 1., 1., 1., 1., 1., 1.], dtype=torch.float64)
Traceback (most recent call last):
File "C:\ml\test_dataloader.py", line 47, in <module>
X, y = X.to(device), y.to(device)
AttributeError: 'list' object has no attribute 'to'
Run Code Online (Sandbox Code Playgroud)
在我能找到的所有示例代码中,X, y = X.to(device), y.to(device)都成功了,因为X确实是一个张量(而它不在我的版本中)。现在我试图找出到底是什么转换X为张量,因为示例代码例如https://pytorch.org/tutorials/beginner/basics/quickstart_tutorial.html不这样做,或者我无法理解如何以及它在哪里。
Dataset 本身是否将事物转换为张量?答案似乎是“有点”。
它已转换为张量,即批次中每个示例的值y的列。y这么多,是有道理的,尽管它使用了 float64 类型,而在机器学习中,我们通常更喜欢 float32。我习惯了Python总是以双精度表示标量的想法,因此从双精度到单精度的转换发生在形成张量时,并且可以通过指定参数来确保这一点dtype。但在这种情况下,数据集似乎隐式地形成了张量。有没有地方或方法可以指定dtype参数?
X不是张量,而是张量的列表。如果它是批次中示例的列表,那么它会具有直观意义,但不是一个包含 8 个元素(每个元素包含 3 个元素)的列表,而是相反。因此 Dataset 已经转置了输入数据,如果它正在形成一个张量来匹配 的形状y,那么这是有意义的,但它不是创建单个 2d 张量,而是创建了一个 1d 张量列表。(并且再次采用双精度。)为什么?有办法改变这种行为吗?
到目前为止发布的答案Does pytorch Dataset.__getitem__ has to return a dict? 说__getitem__可以返回任何东西。好的,但是如何将这些内容转换为训练程序所需的形式呢?
数据集实例仅负责返回数据集的单个元素,该元素可以采用多种形式: dict 、 list 、 int 、 float 、张量等......
但您看到的行为实际上是由 PyTorch 数据加载器处理的,而不是由底层数据集处理的。这种机制称为整理,其实现是由 完成的collate_fn。您实际上可以提供自己的参数作为data.DataLoader. PyTorch 提供了默认的整理功能default_collate,可以处理绝大多数情况。请查看其文档,因为它提供了有关它可以处理的可能用例的见解。
使用此默认整理,返回的批次将采用与数据集中返回的项目相同的类型。因此,您应该返回张量而不是像@dx2-66所解释的列表。
| 归档时间: |
|
| 查看次数: |
1782 次 |
| 最近记录: |