python - Pytorch - 自定义数据集超出范围
问题描述
我是 Pytorch 和 DL 的新手,所以我希望这是提出此类问题的正确地方。
我想创建我的第一个数据集,但我的数据集总是超出范围。这个问题应该最容易用代码和输出显示。
class DataframeDataset(torch.utils.data.Dataset):
"""Load Pytorch Dataset from Dataframe
"""
def __init__(self, data_frame, input_key, target_key, transform=None, features=None):
self.data_frame = data_frame
self.input_key = input_key
self.target_key = target_key
self.inputs = self.data_frame[input_key]
self.targets = self.data_frame[target_key]
self.transform = transform
self.features = [input_key, target_key] if features is None else features
self.len = len(self.inputs)
def __len__(self):
return self.len
def __str__(self):
return str(self.info())
def info(self):
info = {
'features': self.features,
'num_rows': len(self)
}
return "Dataset("+ str(info) + ")"
def __getitem__(self, idx):
if torch.is_tensor(idx):
idx = idx.tolist()
data = {
self.input_key: self.inputs[idx],
self.target_key: self.targets[idx]
}
if self.transform:
return self.transform(data)
return data
@staticmethod
def collate_fn(input_key, output_key):
def __call__(batch):
speeches = [data[input_key] for data in batch]
sentences = [data[output_key] for data in batch]
return speeches, sentences
return __call__
有一些mook数据:
data = [("x1", "y2", "A3"), ("x1", "y2", "b3"), ("x1", "y2", "c3"), ("x1", "y2", "d3")]
df = pd.DataFrame(data, columns=['input', 'target', 'random'])
print(df.head())
input target random
0 x1 y2 A3
1 x1 y2 b3
2 x1 y2 c3
3 x1 y2 d3
ds = DataframeDataset(data_frame=df, input_key="input", target_key="target", transform=None)
print("Len:", len(ds))
print("Ds", ds)
print(ds[0])
Len: 4
Ds Dataset({'features': ['input', 'target'], 'num_rows': 4})
{'input': 'x1', 'target': 'y2'}
所以基本功能似乎工作。但是,如果我想用 foreach 循环遍历数据,那么不幸的是循环不知道边界。所以我得到一个键错误,因为火炬访问边界外的指标。
for idx, data in enumerate(ds):
print(idx,"->",data)
0 -> {'input': 'x1', 'target': 'y2'}
1 -> {'input': 'x1', 'target': 'y2'}
2 -> {'input': 'x1', 'target': 'y2'}
3 -> {'input': 'x1', 'target': 'y2'}
Traceback (most recent call last):
File "/home/warmachine/.local/lib/python3.8/site-packages/pandas/core/indexes/range.py", line 351, in get_loc
return self._range.index(new_key)
ValueError: 4 is not in range`
如果我做类似的事情
for idx in range(0, len(ds)):
data = ds[idx]
print(idx, "->", data)
它有效,但我需要能够使用for-each
样式,以便我可以在拥抱脸的训练器中使用这个数据集。
Ty in 高级
解决方案
如果要使用 Foreach 循环,则必须实现 Iterator 函数。以下是 PyTorch 的一个示例:
https://pytorch.org/docs/stable/data.html#torch.utils.data.IterableDataset
稍作修改,对我有用。
class DataframeDataset(torch.utils.data.Dataset):
...
def __iter__(self):
worker_info = torch.utils.data.get_worker_info()
if worker_info is None:
return map(self.__getitem__, range(self.__len__()))
per_worker = int(math.ceil((self.__len__()) / float(worker_info.num_workers)))
worker_id = worker_info.id
iter_start = worker_id * per_worker
iter_end = min(iter_start + per_worker, self.__len__())
return map(self.__getitem__, range(iter_start, iter_end))
推荐阅读
- docker - Amazon 弹性容器服务 - 等效于 ECS 的 Kubernetes 活性/就绪性检查
- django - 参考“django.contrib.auth.urls”自定义特定模板
- c++ - bool 数据类型在 C++ 中是可移植的吗?
- python - 如何在 Pandas DataFrame 中对列表中的项目进行“与”操作
- java - 驱动器名称丢失!在 `*:\Software\JRE\bin\server\jvm.dll' 处缺少 `server' JVM
- ecmascript-6 - 对对象使用 rest 参数
- git - SVN 本地代码库到 Git 迁移?
- c# - 从 C# 执行 Mysql 存储过程查询
- mysql - 如何在 MySQL Docker 映像中使用脚本执行查询?
- node.js - 将 Angular 与 Nodejs 集成