搜索

C++ 函数重载解析策略 - 木三百川 - 博客园


发布时间: 2022-11-24 17:39:04    浏览次数:14 次

torch.utils.data.DataLoader是pytorch提供的数据加载类,初始化函数如下:

torch.utils.data.DataLoader(dataset,batch_size=1, shuffle=False, 
sampler=None,batch_sampler=None, num_workers=0, 
collate_fn=<function default_collate>,pin_memory=False, 
drop_last=False, timeout=0, worker_init_fn=None)

collate_fn(collate,[kəˈleɪt],核对,校勘) 官方解释为:

collate_fn: (callable, optional): merges a list of samples to form a
            mini-batch of Tensor(s).  Used when using batched loading from a
            map-style dataset.

其实,collate_fn可理解为函数句柄、指针...或者其他可调用类(实现__call__函数)。 函数输入为list,list中的元素为欲取出的一系列样本。具体如下:

indices = next(self.sample_iter)
batch = self.collate_fn([dataset[i] for i in indices])

其中self.sampler_iter即采样器,返回下一个batch中样本的序号,indices

通过collate_fn函数,我们可以对这些样本做进一步的处理(任何你想要的处理),原则上,返回值应当是一个有结构的batch。而DataLoader每次迭代的返回值,就是collate_fn的返回值

下面,我们通过例子来一点点加深对collate_fn这个参数用法的理解。
import torch
from torch.utils.data import Dataset, DataLoader, TensorDataset, RandomSampler

class MyDataset(Dataset):
    def __init__(self,data):
        self.data=data
    def __len__(self):#必须重写
        return len(self.data)
    def __getitem__(self,idx):#必须重写
        return self.data[idx]

构造训练数据,

import numpy as np
a=np.random.rand(4,3)#4个数据,每一个数据是一个向量。
print(a)

用我们人工构造的数据a,初始化上面定义的MyDataset类,

#制作dataset
dataset=MyDataset(a)

dataloader=DataLoader(dataset,batch_size=2)

batch_size=2即一个batch里面会有2个数据。我们以第1个batch为例,

  • DataLoader会根据dataset取出前2个数据,然后弄成一个列表,如下:  
batch=[dataset[0],dataset[1]]
batch

  • 然后将上面这个batch作为参数交给collate_fn这个函数进行进一步整理数据,然后得到real_batch,作为返回值。如果你不指定这个函数是什么,那么会调用pytorch内部的collate_fn。  也就是说,我们如果自己要指定这个函数,collate_fn应该定义成下面这个样子。
def my_collate(batch):#batch上面说过,是dataloader传进来的。
	***#你自己定义怎么整理数据。下面会说。
	real_batch=***
	return real_batch

那么pytorch内部默认的collate_fn函数长什么样呢?我们先观察下面的例子:  

上面这个返回的结果就是real_batch。也就是collate_fn函数的返回值!也就是说collate_fn将batch变成了上面的real_batch。

我们重新写一遍:

batch:
[array([0.9507272 , 0.75916088, 0.07283543]),
 array([0.25041074, 0.6060306 , 0.56210781])]
real_batch:
tensor([[0.9507, 0.7592, 0.0728],
        [0.2504, 0.6060, 0.5621]], dtype=torch.float64) 

将batch变成上述real_batch很容易呀,我们也会!我们下面就来自己写一个collate_fn实现这个功能。  

def my_collate(batch):
    real_batch=np.array(batch)
    real_batch=torch.from_numpy(real_batch)
    return real_batch
dataloader2 = DataLoader(dataset,batch_size=2,collate_fn=my_collate)

这不就和默认的collate_fn的输出结果一样了嘛!

通常,我们并不需要使用这个函数,因为pytorch内部有一个默认的。但是,如果你的数据不规整,使用默认的会报错。例如下面的数据。 假设我们还是4个输入,但是维度不固定的。之前我们是每一个数据的维度都为3。  

b=[[1,2],[3,4,5],[1],[3,4,9]]
dataset=MyDataset(b)
dataloader=DataLoader(dataset,batch_size=2)
it=iter(dataloader)
nex=next(it)
nex

使用默认的collate_fn,直接报错,要求相同维度。

 这个时候,我们可以使用自己的collate_fn,避免报错。

不过话说回来,我个人感受是:  在这里避免报错好像也没有什么用,因为大多数的神经网络都是定长输入的,而且很多的操作也要求相同维度才能相加或相乘,所以:这里不报错,后面还是报错。如果后面解决这个问题的方法是:在不足维度上进行补0操作,那么我们为什么不在建立dataset之前先补好呢?所以,collate_fn这个东西的应用场景还是有限的。不过,明白其原理总是好事。  

  

免责声明 C++ 函数重载解析策略 - 木三百川 - 博客园,资源类别:文本, 浏览次数:14 次, 文件大小:-- , 由本站蜘蛛搜索收录2022-11-24 05:39:04。此页面由程序自动采集,只作交流和学习使用,本站不储存任何资源文件,如有侵权内容请联系我们举报删除, 感谢您对本站的支持。 原文链接:https://www.cnblogs.com/young520/p/16808445.html