这里以MNIST数据集的训练样本为例,将其划分为两个新的数据集:详细代码见下一节:
1、np.floor 是向下取整函数
np.floor 返回不大于输入参数的最大整数。 即对于输入值 x ,将返回最大的整数 i ,使得 i <= x。 除此之外,NumPy常见运算四舍五入、取整、条件选取np.around、np.floor、np.ceil、np.where的详细用法如下:
【NumPy】 之常见运算四舍五入、取整、条件选取(np.around、np.floor、np.ceil、np.where)_tz_zs的博客-CSDN博客_numpy 四舍五入
import numpy as np
n = np.array([-1.7, -2.5, -0.2, 0.6, 1.2, 2.7, 11])
floor = np.floor(n)
print(floor) # [ -2. -3. -1. 0. 1. 2. 11.]
2、np.random.shuffle(x) :在原数组上进行,改变自身序列,无返回值 。 np.random.permutation(x) :不在原数组上进行,返回新的数组,不改变自身数组 。
对于一个一维输入来说,对数据的顺序做了随机的排序。对于一个多维的输入,只是在第一维上进行了随机排序。例如一个二维矩阵矩阵来说,只是对行进行随机排序。np.random.shuffle(x)改变自身数组,np.random.permutation(x)不改变自身数组。
arr = np.arange(9).reshape((3, 3))
arr2 = np.arange(10)
print(arr)
print(arr2)
np.random.shuffle(arr)
np.random.shuffle(arr2)
arr3=np.random.permutation(arr2)
print('一维shuffle\n',arr)
print('二维shuffle',arr2)
print('一维permutation',arr3)
输出结果:
[[0 1 2]
[3 4 5]
[6 7 8]]
[0 1 2 3 4 5 6 7 8 9]
一维shuffle
[[6 7 8]
[3 4 5]
[0 1 2]]
二维shuffle [6 7 9 2 5 0 8 3 1 4]
一维permutation [4 0 5 6 8 9 2 1 3 7]
3、np.random.seed()随机数种子
随机数种子是按一定顺序生成随机数的,并不是一次给了一批数,这些数有固定顺序,可以简单认为随机种子给了我们很多数据,当需要生成随机数时,就从这一批数中依次取值。
这是因为开始设置了一个随机种子 “1”,接下来生成的8个数是有固定顺序的,可以把随机种子看成一个很长的 list ,接下来的取随机数操作 np.random.rand(4) ,就是从这个 list 中依次取4个随机数,然后 np.random.rand(4) ,再取4个随机数。之后在生成这7个 ‘随机’ 数之前,又重新定义了一个随机数种子np.random.seed(1) 。定义随机数种子就是定义了一个很长的 list ,这个 list 和之前的 list 是一样的!所以取的7个 ‘随机’ 数,就是这个 list 中的前7个。
import numpy as np
np.random.seed(1) # 先定义一个随机数种子,()中的参数值后下个小节说
print(np.random.rand(4)) # "随机"生成5个数
print(np.random.rand(4)) # 再"随机"生成5个数
np.random.seed(1)
for i in range(7):
print(np.random.random()) # "随机"生成7个数
输出结果:
[4.17022005e-01 7.20324493e-01 1.14374817e-04 3.02332573e-01]
[0.14675589 0.09233859 0.18626021 0.34556073]
0.417022004702574
0.7203244934421581
0.00011437481734488664
0.30233257263183977
0.14675589081711304
0.0923385947687978
0.1862602113776709
(1)随机数种子相当于给我们一个初值,之后按照固定顺序生成随机数。
(2)随机数种子对后面的结果一直有影响,在一个随机数种子后生成的随机数都受这个随机数种子的影响,即生成的随机数都是由这个随机数种子给的初值,按照固定顺序生成的(生成的随机数受离它最近的随机数种子影响,即它之前的随机数种子)。
4、SubsetRandomSampler()方法
(1)SubsetRandomSampler
可以设置子集的随机采样,多用于将数据集分成多个集合,比如训练集和验证集的时候使用,会根据给的列表从数据集中按照下标取元素,无放回地按照给定的索引列表采样样本元素。
from torch.utils.data import SubsetRandomSampler
pseudo_dataset = list(range(10))
subRandomSampler1 = SubsetRandomSampler(pseudo_dataset[:7])
subRandomSampler2 = SubsetRandomSampler(pseudo_dataset[7:])
print("for subset random sampler #1: ")
for data in subRandomSampler1:
print(data, end=" ")
print("\n\nfor subset random sampler #2: ")
for data in subRandomSampler2:
print(data, end=" ")
输出结果:
for subset random sampler #1:
2 1 0 3 4 6 5
for subset random sampler #2:
8 9 7
(2)SequentialSampler
就是一个按照顺序进行采样的采样器,接收一个数据集做参数(实际上任何可迭代对象都可),按照顺序对其进行采样:
pseudo_dataset = list(range(10))
for data in SequentialSampler(pseudo_dataset):
print(data, end=" ")
(3)RandomSampler 即一个随机采样器,返回随机采样的值,第一个参数依然是一个数据集(或可迭代对象)。replacement:bool值,默认是False,设置为True时表示可以重复采样。num_samples:只有在replacement设置为True的时候才能设置此参数,表示要采出样本的个数,默认为数据集的总长度。有时候重复数据被采样,导致有些采不到,所以会设置一个较大的值。
randomSampler2 = RandomSampler(pseudo_dataset, replacement=True, num_samples=20)
(4)WeightedRandomSampler和RandomSampler的参数一致,第一个参数变成了weights,只接收一个一定长度的list作为 weights 参数,表示采样的权重,采样时会根据权重随机从 list(range(len(weights))) 中采样,并不需要传入样本集,而是只在一个根据weights长度创建的数组中采样。weights的所有元素之和不需要为1。
weightedRandomSampler = WeightedRandomSampler(weights, replacement=True, num_samples=20)
(5)以上的四个Sampler在每次迭代都只返回一个索引,而BatchSampler的作用是对上述这类返回一个索引的采样器进行包装,按照设定的batch size返回一组索引,参数有些不同:
batchSampler2 = BatchSampler(pseudo_dataset, batch_size=3, drop_last=True)
sampler:一个Sampler对象(或者一个可迭代对象)
batch_size:batch的大小
drop_last:是否丢弃最后一个可能不足batch size大小的数据
更多的采样规则可参考如下内容:
PyTorch教程-5:详解PyTorch中加载数据的方法--Dataset、Dataloader、Sampler、collate_fn等_超级超级小天才的博客-CSDN博客
5、np.random.choice
从 一维数组 或 int 数字中 ,以概率p随机选取大小为size的数据,replace表示是否重用元素,随机抽取元素,
import numpy as np
print(np.random.choice(5))#从[0, 5)中随机输出一个随机数
print(np.random.choice(5, 3))#在[0, 5)内输出3个数字并组成一维数组(ndarray)
L = [1, 2, 3, 4, 5] # list列表
print(np.random.choice(L, 5, replace=False, p=[0.2, 0.2, 0.2, 0.2,0.2]))#在l列表内输出5个不相同的数字并组成一维数组(ndarray),每个概率一样
A = np.array([[1,2],[3,4],[5,6],[7,2],[4,9]])#从二维数组中抽取
print(A[np.random.choice(A.shape[0],2),:])
输出结果:
4
[3 3 4]
[5 2 3 1 4]
[[4 9]
[1 2]]
numpy.random.choice(a, size=None, replace=True, p=None)
* 从a中随机抽取数字,并组成指定大小(size)的数组。本例用于打乱数据集中的样本。
* replace:True表示可以取相同数字,False表示不可以取相同数字。
* 数组p:与数组a相对应,表示取数组a中每个元素的概率,默认为选取每个元素的概率相同。
关于参数的详细用法参见一下链接:
python,numpy中np.random.choice()的用法详解及其参考代码_ImwaterP的博客-CSDN博客_np.random.choice
6、DataLoader介绍
DataLoader
: 批量加载数据用于后续的训练和测试 。对Dataset
(和Sampler
等)打包,完成最后对数据的读取的执行工作。这个接口的目的是:将自定义的数据读取接口的输出或者PyTorch已有的数据读取接口的输入,按照batch size封装成Tensor,后续只需要再包装成Variable即可作为模型的输入。本例中使用的如下代码部分:
train_data = trainset() #数据集
trainloader = DataLoader(train_data, batch_size=4,shuffle=True) #加载数据集,设定参数
valid_loader = Data.DataLoader(
dataset = train_dataset, #DataSet : 根据 Sampler 提供的索引来检索数据
batch_size = 32,
sampler = valid_sampler, #Sampler : 提供数据集中元素的索引
1、dataset,定义要加载的数据集。 这个就是 PyTorch 已有的数据读取接口或者自定义的数据接口的输出,该输出要么是torch.utils.data.Dataset类的对象,要么是继承自torch.utils.data.Dataset类的自定义类的对象。也可以根据 Sampler
提供的索引来检索数据 。
2、batch_size,定义batch_size大小,也就是一次加载样本的数量,默认是1。
3、shuffle,在每个epoch开始的时候,是否进行数据重排序,默认False.
4、collate_fn,是用来处理不同情况下的输入dataset的封装。
5、batch_sampler,与参数sampler相似,但是一次只返回一个batch索引(indices),其和batch_size、shuffle等参数是互斥的。
6、sampler,定义从数据集中取样本元素的索引 ,如果进行了指定,那么shuffle必须是False。
7、num_workers,定义加载数据使用的进程数,0的话表示数据导入在主进程中进行,其他大于0的数表示通过多个进程来导入数据,可以加快数据导入速度。
8、pin_memory,如果设定为True,那么data loader将会在返回之前,将tensors拷贝到CUDA中的固定内存。
9、timeout,是用来设置数据读取的超时时间的,但超过这个时间还没读取到数据的话就会报错。
10、drop_last , 这个是对最后的未完成的batch来说的,比如你的batch_size设置为64,而一个epoch只有100个样本,如果设置为True,那么训练的时候后面的36个就被扔掉了。如果为False(默认),那么会继续正常执行,只是最后的batch_size会小一点。
深度的理解可以查看: