iter()迭代器 in DeepLearning

python中内置str、list、tuple、dict、set、file都是可迭代对象
迭代器使用函数iter()和next(),以下两种方法都可以:

# 不依赖索引的数据类型迭代取值
dic = {'a': 1, 'b': 2, 'c': 3}
iter_dic = iter(dic)
print(next(iter_dic)) # a
print(next(iter_dic)) # b
print(next(iter_dic)) # c

dic = {'a': 1, 'b': 2, 'c': 3}
iter_dic = dic.__iter__()
print(iter_dic.__next__())
print(iter_dic.__next__())
print(iter_dic.__next__())
# print(iter_dic.__next__())  # StopIteration:

顺带一提,要想输出值

dic = {'a': 1, 'b': 2, 'c': 3}
iter_dic = iter(dic.values())
print(next(iter_dic)) # 1
print(next(iter_dic)) # 2
print(next(iter_dic)) # 3

在深度学习中,使用特征0到9,标签0或1(偶数或奇数)作为例子

import torch
from torch.utils.data import DataLoader, Dataset

# 创建一个简单的数据集
class SimpleDataset(Dataset):
    def __init__(self):
        self.data = [torch.tensor([i]) for i in range(10)]  # 示例数据:0到9的张量
        self.labels = [torch.tensor(i % 2) for i in range(10)]  # 示例标签:0或1

    def __len__(self):
        return len(self.data)

    def __getitem__(self, index):
        return self.data[index], self.labels[index]

# 创建数据加载器
dataset = SimpleDataset()
data_loader = DataLoader(dataset, batch_size=2, shuffle=True) # False则不打乱

# 使用 iter() 创建一个迭代器
data_iterator = iter(data_loader)

# 迭代获取数据
for _ in range(len(data_iterator)):  # 迭代5次,获取5个批次的数据
    batch_data, batch_labels = next(data_iterator)
    print(f"Batch data: {batch_data}, Batch labels: {batch_labels}")

'''
Batch data: tensor([[9],[8]]), Batch labels: tensor([1, 0])
Batch data: tensor([[7],[5]]), Batch labels: tensor([1, 1])
Batch data: tensor([[2],[0]]), Batch labels: tensor([0, 0])
Batch data: tensor([[4],[3]]), Batch labels: tensor([0, 1])
Batch data: tensor([[1],[6]]), Batch labels: tensor([1, 0])
'''


for batch in data_loader:
    inputs, labels = batch
    print(f"Batch data: {inputs}, Batch labels: {labels}")


'''
Batch data: tensor([[3],[2]]), Batch labels: tensor([1, 0])
Batch data: tensor([[5],[8]]), Batch labels: tensor([1, 0])
Batch data: tensor([[6],[1]]), Batch labels: tensor([0, 1])
Batch data: tensor([[9],[4]]), Batch labels: tensor([1, 0])
Batch data: tensor([[0],[7]]), Batch labels: tensor([0, 1])
'''

使用 for batch in data_loader: 的方式确实更简洁,同时也能达到相同的效果。使用 iter() 的意义主要体现在以下几个方面:

1. 手动控制迭代

使用 iter()next() 可以让你更精确地控制迭代的过程,尤其是在需要对每个批次进行特定操作时。例如,你可能想要在处理每个批次之间插入一些自定义的逻辑。

2. 在特定条件下中断迭代

当你需要在特定条件下中断迭代时,使用 iter()next() 可以更灵活。例如,你可以在处理某个批次后根据某种条件决定是否继续迭代。

data_iterator = iter(data_loader)
while True:
    try:
        batch_data, batch_labels = next(data_iterator)
        # 进行某种条件判断
        if some_condition(batch_data):
            break
        print(f"Batch data: {batch_data}, Batch labels: {batch_labels}")
    except StopIteration:
        print("End of data.")
        break

3. 多次使用同一个迭代器

在某些情况下,你可能需要在不同的上下文中多次使用同一个迭代器。通过 iter() 创建迭代器后,你可以在需要时多次调用 next()

4. 动态调整批次处理

如果你需要在处理批次时根据某些动态条件调整处理逻辑,使用 iter()next() 可以让你在每次处理后更容易地进行调整。

5. 性能优化

在某些情况下,使用 iter()next() 可以更有效地控制内存使用,尤其是在处理大数据集或者复杂的预处理时。

总结

虽然在许多情况下,使用 for batch in data_loader: 更为简洁和直观,但 iter()next() 提供了更大的灵活性和控制能力,尤其是在需要更复杂的迭代逻辑时。具体使用哪种方式,取决于你对控制流程的需求和具体场景。

posted @ 2024-10-27 20:05  srrdhy  阅读(68)  评论(0)    收藏  举报