在进行使用pytorch进行数据处理的使用,对于其中涉及的函数不是特别了解,导致在使用的时候,需要不断的翻阅资料,去查找某个方法如何使用,对于其产生的结果不是十分了解。以下对于pytorch中我遇到的常用函数进行归纳总结,并不进行完善,以供学习。
dim 这一参数通常指的是维度,其维度设置如下图所示:
图片源于【PyTorch】PyTorch 中的 dim
其中参考实例如下:
import torch
a = torch.Tensor([[[1, 2, 3],[7, 8, 9]],
[[4, 5, 6],[1, 1, 1]]])
print(a.sum(dim = 0))
print(a.sum(dim = 1))
print(a.sum(dim = 2))
#结果
tensor([[ 5., 7., 9.],
[ 8., 9., 10.]])
tensor([[ 8., 10., 12.],
[ 5., 6., 7.]])
tensor([[ 6., 24.],
[15., 3.]])
顾名思义,保持keepdim的维度,具体示例如下图所示:
import torch
a = torch.Tensor([[1, 2, 3],[7, 8, 9],
[4, 5, 6],[1, 1, 1]])
print(a.sum(dim = 0, keepdim = True))
print(a.sum(dim = 0))
#结果
tensor([[13., 16., 19.]])
tensor([13., 16., 19.])
这两个函数在使用的时候,正好相反,torch.cat将张量进行组合, 而torch.chunk将张量进行拆分。
torch.cat是将两个张量(tensor)拼接在一起,cat是concatnate的意思,即拼接,联系在一起。
outputs = torch.cat(inputs, dim=?) → Tensor
示例参考:torch.cat() 函数用法
C = torch.cat( (A,B),0 ) #按维数0拼接(竖着拼)
C = torch.cat( (A,B),1 ) #按维数1拼接(横着拼)
具体使用:
>>> import torch
>>> A=torch.ones(2,3) #2x3的张量(矩阵)
>>> A
tensor([[ 1., 1., 1.],
[ 1., 1., 1.]])
>>> B=2*torch.ones(4,3)#4x3的张量(矩阵)
>>> B
tensor([[ 2., 2., 2.],
[ 2., 2., 2.],
[ 2., 2., 2.],
[ 2., 2., 2.]])
>>> C=torch.cat((A,B),0)#按维数0(行)拼接
>>> C
tensor([[ 1., 1., 1.],
[ 1., 1., 1.],
[ 2., 2., 2.],
[ 2., 2., 2.],
[ 2., 2., 2.],
[ 2., 2., 2.]])
>>> C.size()
torch.Size([6, 3])
>>> D=2*torch.ones(2,4) #2x4的张量(矩阵)
>>> C=torch.cat((A,D),1)#按维数1(列)拼接
>>> C
tensor([[ 1., 1., 1., 2., 2., 2., 2.],
[ 1., 1., 1., 2., 2., 2., 2.]])
>>> C.size()
torch.Size([2, 7])
注意咋使用时合并的维度必须符合要求,如上例所示。
torch.chunk(tensor, chunk_num, dim)与torch.cat()原理相反,它是将tensor按dim(行或列)分割成chunk_num个tensor块,返回的是一个元组。
示例:
c = torch.tensor([[1., 2., 4.],
[4., 5., 7.],
[3., 9., 8.],
[9., 6., 7.]])
#在dim=1这一个维度进行拆分, chunk_num是拆分的块数,当其大于等于dim=1中元
#素的个数n, 则拆成n块,小于则平分。
torch.chunk(c,4,dim = 1)
结果:
(tensor([[1.],
[4.],
[3.],
[9.]]),
tensor([[2.],
[5.],
[9.],
[6.]]),
tensor([[4.],
[7.],
[8.],
[7.]]))
torch.chunk(c,3,dim = 1)
结果:
(tensor([[1.],
[4.],
[3.],
[9.]]),
tensor([[2.],
[5.],
[9.],
[6.]]),
tensor([[4.],
[7.],
[8.],
[7.]]))
torch.chunk(c,2,dim = 1)
结果:
(tensor([[1., 2.],
[4., 5.],
[3., 9.],
[9., 6.]]),
tensor([[4.],
[7.],
[8.],
[7.]]))
先看torch.squeeze() 这个函数主要对数据的维度进行压缩,去掉维数为1的的维度,比如是一行或者一列这种,一个一行三列(1,3)的数去掉第一个维数为一的维度之后就变成(3)行。squeeze(a)就是将a中所有为1的维度删掉。不为1的维度没有影响。a.squeeze(N) 就是去掉a中指定的维数为一的维度。还有一种形式就是b=torch.squeeze(a,N) a中去掉指定的定的维数为一的维度。
再看torch.unsqueeze()这个函数主要是对数据维度进行扩充。给指定位置加上维数为一的维度,比如原本有个三行的数据(3),在0的位置加了一维就变成一行三列(1,3)。a.squeeze(N) 就是在a中指定位置N加上一个维数为1的维度。还有一种形式就是b=torch.squeeze(a,N) a就是在a中指定位置N加上一个维数为1的维度
参考博客:pytorch学习 中 torch.squeeze() 和torch.unsqueeze()的用法
示例:
c = torch.tensor([[[1., 2., 4.],
[4., 5., 7.],
[3., 9., 8.],
[9., 6., 7.]]])
c.shape
#torch.Size([1, 4, 3])
b = c.squeeze(0)
print(b, b.shape)
tensor([[1., 2., 4.],
[4., 5., 7.],
[3., 9., 8.],
[9., 6., 7.]]) torch.Size([4, 3])
示例:
c = torch.tensor([[1., 2., 4.],
[4., 5., 7.],
[3., 9., 8.],
[9., 6., 7.]])
c.shape
#torch.Size([4, 3])
b = c.unsqueeze(1)
print(b, b.shape)
tensor([[[1., 2., 4.]],
[[4., 5., 7.]],
[[3., 9., 8.]],
[[9., 6., 7.]]]) torch.Size([4, 1, 3])
数据处理主要讲解TensorDataset,Dataset的自定义,以及DataLoader,其在使用是先使用Dataset类型的函数,再与DataLoader配合使用从而实现获取batch的处理。TensorDataset处理比较简单的数据,而复杂的数据,则进行Dataset的自定义。
TensorDataset将简单的数据进行绑定,使其相对应的数据何以同时获取。
from torch.utils.data import TensorDataset
import torch
from torch.utils.data import DataLoader
a = torch.tensor([[11, 22, 33], [44, 55, 66], [77, 88, 99], [11, 22, 33], [44, 55, 66], [77, 88, 99], [11, 22, 33], [44, 55, 66], [77, 88, 99], [11, 22, 33], [44, 55, 66], [77, 88, 99]])
b = torch.tensor([0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2])
train_ids = TensorDataset(a, b)
train_loader = DataLoader(dataset=train_ids, batch_size=4, shuffle=True)
for i, data in enumerate(train_loader, 1): # 注意enumerate返回值有两个,一个是序号,一个是数据(包含训练数据和标签)
x_data, label = data
print(' batch:{0} x_data:{1} label: {2}'.format(i, x_data, label))
Dataset主要用于自定义类型,实现不同的复杂类型,其核心点在两个基础的函数
__len__:一般用来返回数据集大小。
__getitem__:实现这个方法后,可以通过下标的方式 dataset[i] 的来取得第 i 个数据。
具体使用方法,如下:
#创建子类
class subDataset(Dataset.Dataset):
#初始化,定义数据内容和标签
def __init__(self, Data, Label):
self.Data = Data
self.Label = Label
#返回数据集大小
def __len__(self):
return len(self.Data)
#得到数据内容和标签
def __getitem__(self, index):
data = torch.Tensor(self.Data[index])
label = torch.Tensor(self.Label[index])
return data, label
对来自Dataset的数据进行shuffle和batch等操作。
loader = Data.DataLoader(
dataset=torch_dataset, # torch TensorDataset format
batch_size=BATCH_SIZE, # mini batch size
shuffle=True, # 要不要打乱数据 (打乱比较好)
num_workers=2, # 多线程来读数据
)
for step, (batch_x, batch_y) in enumerate(loader):
print(batch_x, batch_y)
当我们处理完的数据,需要进行shuffle时,不能采用上述操作DataLoader进行shuffle时,我们可以采用其他的方法进行shuffle,采用random类中的shuffle函数数据进行shuffle。
import torch
from random import shuffle
a = torch.Tensor([1, 2, 3, 4, 5, 6, 7, 8, 9])
print("原始数据:", a)
index = [i for i in range(a.shape[0])]
shuffle(index)
print(index)
print("shuffle之后的数据:",a[index])
参考博客:(pytorch)torch.sum的用法及dim参数的使用
1.torch.sum(input, dtype=None)
2.torch.sum(input, list: dim, bool: keepdim=False, dtype=None) → Tensor
input:输入一个tensor
dim:要求和的维度,可以是一个列表
keepdim:求和之后这个dim的元素个数为1,所以要被去掉,如果要保留这个维度,则应当keepdim=True
import torch
a = torch.ones((2, 3))
a1 = torch.sum(a)
a2 = torch.sum(a, dim=0)
a3 = torch.sum(a, dim=1)
print(a)
print(a1)
print(a2)
print(a3)
参考博客:
mean()函数的参数:dim=0,按列求平均值,返回的形状是(1,列数);dim=1,按行求平均值,返回的形状是(行数,1),默认不设置dim的时候,返回的是所有元素的平均值。
x=torch.arange(12).view(4,3)
'''
注意:在这里使用的时候转一下类型,否则会报RuntimeError: Can only calculate the mean of floating types. Got Long instead.的错误。
查看了一下x元素类型是torch.int64,根据提示添加一句x=x.float()转为tensor.float32就行
'''
x=x.float()
x_mean=torch.mean(x)
x_mean0=torch.mean(x,dim=0,keepdim=True)
x_mean1=torch.mean(x,dim=1,keepdim=True)
print('x:')
print(x)
print('x_mean0:')
print(x_mean0)
print('x_mean1:')
print(x_mean1)
print('x_mean:')
print(x_mean)
x:
tensor([[ 0., 1., 2.],
[ 3., 4., 5.],
[ 6., 7., 8.],
[ 9., 10., 11.]])
x_mean0:
tensor([[4.5000, 5.5000, 6.5000]])
x_mean1:
tensor([[ 1.],
[ 4.],
[ 7.],
[10.]])
x_mean:
tensor(5.5000)
参考博客:np.append()函数用法
函数np.append(arr, values, axis=None)
作用:为原始array添加一些values
参数:
import numpy as np
a=[1,2,3]
b=[4,5]
c=[[6,7],[8,9]]
print(np.append(a,b))
print(np.append(a,c))
#结果
[1 2 3 4 5]
[1 2 3 6 7 8 9]
import numpy as np
a=[1,2,3]
b=[4,5]
c=[[6,7],[8,9]]
d=[[10,11],[12,13]]
print('在一维数组a后添加values,结果如下:{}'.format(np.append(a,b,axis=0)))
print('沿二维数组c的行方向添加values结果如下:'.format(np.append(c,d,axis=0)))
print('沿二维数组c的列方向添加values结果如下:'.format(np.append(c,d,axis=1)))
print('使用了axis,若arr和values的形状不同,则报错:'.format(np.append(a,c,axis=0))
#结果
在一维数组a后添加values,结果如下:
[1 2 3 4 5]
沿二维数组c的行方向添加values结果如下:
[[ 6 7]
[ 8 9]
[10 11]
[12 13]]
沿二维数组c的列方向添加values结果如下:
[[ 6 7 10 11]
[ 8 9 12 13]
import numpy as np
a=[1,2,3]
c=[[6,7],[8,9]]
print(np.append(a,c,axis=0))
#结果
Traceback (most recent call last):
File "F:\eclipse-workspace\test\t1.py", line 4, in <module>
print(np.append(a,c,axis=0))
File "E:\anaconda\anzhuang\lib\site-packages\numpy\lib\function_base.py", line 4694, in append
return concatenate((arr, values), axis=axis)
ValueError: all the input arrays must have same number of dimensions
该方法用于矩阵乘法,mat1 是(n×m) 的张量, mat2是(m×p)的张量, out结果将是(n×p) 的张量。
torch.mm(mat1, mat2, *, out=None) → Tensor
注意:mat1和mat1只能是矩阵matrix, 并且无法只用广播机制
示例:
a = torch.arange(1, 13).reshape( 6, 2).long()
print(a)
b = torch.Tensor([[1],[1]]).long()
print(b)
print(torch.mm(a, b))
#结果:
tensor([[ 1, 2],
[ 3, 4],
[ 5, 6],
[ 7, 8],
[ 9, 10],
[11, 12]])
tensor([[1],
[1]])
tensor([[ 3],
[ 7],
[11],
[15],
[19],
[23]])
该方法支持张量乘法,可以实现广播机制,参考博客:torch.matmul()用法介绍
torch.matmul(input, other, *, out=None) → Tensor
其方法与*在使用时没有区别,可以进行广播。
torch.mul(input, other, *, out=None) → Tensor