dataloader简介

dataset在程序中起到的作用是告诉程序数据在哪,每个索引所对应的数据是什么。相当于一系列的存储单元,每个单元都存储了数据。这里可以类比成一幅扑克牌,一张扑克牌就是一个数据,一幅扑克牌就是一个完整的数据集。

再把神经网络的输入获取类比成手,用手去抓扑克牌,每次抓几张,用一只手去抓取,还是用两只手,这就是 dataloader 要做的事,可以通过参数进行一个设置。

pytorch dataloader 数据小于batchsize怎么处理_python


pytorch dataloader 数据小于batchsize怎么处理_pytorch_02

'''
dataset 引用数据集
batch_size 每次抓取数量
shuffle 是否洗牌 True 洗牌前后不一样 epoch测试两次不一样 反之相反
num_workers 进程数量
drop_last 100牌每次取3张 最后剩一张 是否取出
'''

dataloader的使用

2.1 简单测试

测试代码:

# Kyrie Irving
# !/9462...
import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

# 每张图片都转为ToTensor类型
dataset_transform = torchvision.transforms.Compose([
    torchvision.transforms.ToTensor()
])

test_set  = torchvision.datasets.CIFAR10(root="../dataset", train=False, transform=dataset_transform, download=True)
'''
dataset 引用数据集
batch_size 每次抓取数量
shuffle 是否洗牌 True 洗牌前后不一样 epoch测试两次不一样 反之相反
num_workers 进程数量
drop_last 100牌每次取3张 最后剩一张 是否取出
'''
test_loader = DataLoader(dataset=test_set, batch_size=4, shuffle=False, num_workers=0, drop_last=False)

# 返回数据集第一张图的东西
img, target = test_set[0]
print(img.shape)
print(target)

# return of dataloader
for data in test_loader:
    imgs, targets = data
    print(imgs.shape)
    print(targets)

输出:

pytorch dataloader 数据小于batchsize怎么处理_pytorch_03


可以看到,单个数据读取时,输出是

torch.Size([3, 32, 32])
3

即图片为RGB三通道,像素大小为32*32,tag为3
采用 dataloader(batch_size=4)读取时:

torch.Size([4, 3, 32, 32])
tensor([3, 8, 8, 0])
torch.Size([4, 3, 32, 32])
tensor([6, 6, 1, 6])
torch.Size([4, 3, 32, 32])
tensor([3, 1, 0, 9])

即4张图片,每个图片都为RGB三通道,像素大小为32*32
然后tag也打包在一起了,返回为 tensor([1, 7, 9, 2])形式。
注:Dataloader默认采用的是从数据集中进行随机抓取。

2.2 通过tensorboard显示抓取结果

对 drop_last 以及 shuffle 属性进行测试

# Kyrie Irving
# !/9462...
import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

# 每张图片都转为ToTensor类型
dataset_transform = torchvision.transforms.Compose([
    torchvision.transforms.ToTensor()
])

test_set  = torchvision.datasets.CIFAR10(root="../dataset", train=False, transform=dataset_transform, download=True)
'''
dataset 引用数据集
batch_size 每次抓取数量
shuffle 是否洗牌 True 洗牌前后不一样 epoch测试两次不一样 反之相反
num_workers 进程数量
drop_last 100牌每次取3张 最后剩一张 是否取出
'''
test_loader = DataLoader(dataset=test_set, batch_size=64, shuffle=False, num_workers=0, drop_last=False)

# 返回数据集第一张图的东西
img, target = test_set[0]
print(img.shape)
print(target)


writer = SummaryWriter("../logs/dataloader")
step = 0

for epoch in range(2):
    for data in test_loader:
        imgs, targets = data
        # print(imgs.shape)
        # print(targets)
        writer.add_images("Epoch:{}".format(epoch), imgs, step)
        step = step + 1
writer.close()

(pytorch) E:\CodeCodeCodeCode\AI\Pytorch-study>tensorboard --logdir="logs/dataloader/"
TensorFlow installation not found - running with reduced feature set.
Serving TensorBoard on localhost; to expose to the network, use a proxy or pass --bind_all
TensorBoard 2.7.0 at http://localhost:6006/ (Press CTRL+C to quit)

pytorch dataloader 数据小于batchsize怎么处理_python_04


这里每次抓取64个数据,用 add_images 函数写入到 SummaryWriter实例化对象中,再进行显示:

这里当 DataLoader 的输入 drop_last设置为True时,最后一次抓取的数据若不满64,则会被丢弃。为Flase时则不会,如上图的上半部分所示,最后一次抓取了16个数据,不满64,没有丢弃。

  • shuffle为 False时,两次抓取的顺序不会进行打乱,即两次抓取的结果一样
  • shuffle为 True时,两次抓取的顺序会进行打乱,即两次抓取的结果不一样
    dataloader 返回的 imgs 可以作为神经网络的输入