Pytorch和Numpy
pytorch中的张量就类似于numpy中的n维数组。但是pytorch可以通过.cuda()方法使用GPU加速计算。这篇文章主要介绍pytorch的一些基本操作。这里也贴一下Pytorch的网站里面也有torch的函数的参数说明以及例子。
1.首先是导入包。
import torch #导入pytorch包import numpy #导入numpy包
2.torch中常用的创建张量的方法
创建一个未初始化的2×3的矩阵
声明未初始化的矩阵但使用前不包含确定的已知值。当创建一个未初始化的矩阵时无论当时分配的内存中有什么值都会显示为初始值。
a torch.tensor([[1,2,3],[4,5,6]])#创建一个tensor([[1,2,3],[4,5,6]])print(a.size())#获得张量a的形状是一个元组print(a)x torch.empty(2, 3)#多次运行可以看到每次的x都是不一样的因为未初始化print(x.size())#获得张量x的形状是一个元组print(x)#此时的x未初始化size与a相同。y torch.empty(2,3,out a)print(y.size())#获得张量y的形状是一个元组print(y)#运用a参数后此时y和a一样了empty_like torch.empty_like(y) #创建一个size和y一样的未初始化张量。print(empty_like.size())#获得张量empty_like的形状是一个元组print(empty_like)
关于torch.emptytorch.empty_like
torch.empty(*size, outNone, dtypeNone, layouttorch.strided, deviceNone, requires_gradFalse, pin_memoryFalse) → Tensor 返回一个未初始化的张量张量大小由参数size定义。参数说明 size(int…)是一个用于定义输出的张量的形状的整形序列也可以是list或者turple。 out(Tensor可选)要求的值为张量默认为none。也可以令out为一个具体张量aa的shape与参数size相同这样输出的张量就会和a一样。上面的例子可以看出。 dtype(torch.dtype可选): 要求的值的类型是torch.dtype默认值是torch.set_default_tensor_type的值。可以通过这个dtype参数来改变输出的张量的数据类型。 layout(torch.layout可选)torch.layput表示torch.Tensor内存布局的对象。这个参数表示你希望返回的张量的内存布局类型默认为torch.strided。torch.strided代表密集型张量是最常见的内存布局每个strided张量都关联一个torch.Storagetorch.Storage保存着strided张量的数据。 device(torch.device,可选):创建的张量存放的device。 requires_grad(bool可选)要求的值为bool类型默认为False。若为False则反向传播时不会对这个节点求导。 torch.empty_like(input, *, dtypeNone, layoutNone, deviceNone, requires_gradFalse, memory_formattorch.preserve_format) → Tensor 返回一个与input形状一样的使用未初始化值填满的tensor相当于torch.empty(input.size(), dtypeinput.dtype, layoutinput.layout,参数说明 dtype(torch.dtype可选): 要求的值的类型是torch.dtype默认值是torch.set_default_tensor_type的值。可以通过这个dtype参数来改变输出的张量的数据类型。 layout(torch.layout可选)torch.layput表示torch.Tensor内存布局的对象。这个参数表示你希望返回的张量的内存布局类型默认为torch.strided。torch.strided代表密集型张量是最常见的内存布局每个strided张量都关联一个torch.Storagetorch.Storage保存着strided张量的数据。 device(torch.device,可选):创建的张量存放的device。 requires_grad(bool可选)要求的值为bool类型默认为False。若为False则反向传播时不会对这个节点求导。 memory_format(torch.memory_format, 可选): 期望返回张量的保存类型默认为torch.preserve_format。torch.memory类型用于保存torch.Tensor的储存格式。torch.preserve_format是保留输入张量的内存格式用在clone这样的函数中。如果输入张量是分配在稠密不重叠的内存中那么输出张量的stride与输入相同。否则输出的strides使用torch.contiguous_format。
创建一个随机的初始化矩阵
x torch.rand(2,3)print(x)
关于torch.rand:
torch.rand(*size, outNone, dtypeNone, layouttorch.strided, deviceNone, requires_gradFalse) → Tensor 返回服从均匀分布的初始化后的张量张量大小由参数size定义。参数说明 size(int…)是一个用于定义输出的张量的形状的整形序列也可以是list或者turple。 out(Tensor可选)要求的值为张量默认为none。也可以令out为一个具体张量aa的shape与参数size相同这样输出的张量就会和a一样。 dtype(torch.dtype可选): 要求的值的类型是torch.dtype默认值是torch.set_default_tensor_type的值。可以通过这个dtype参数来改变输出的张量的数据类型。 layout(torch.layout可选)torch.layput表示torch.Tensor内存布局的对象。这个参数表示你希望返回的张量的内存布局类型默认为torch.strided。torch.strided代表密集型张量是最常见的内存布局每个strided张量都关联一个torch.Storagetorch.Storage保存着strided张量的数据。 device(torch.device,可选):创建的张量存放的device。 requires_grad(bool可选)要求的值为bool类型默认为False。若为False则反向传播时不会对这个节点求导。
创建一个全是0的矩阵并且令数据类型为torch.long
x torch.zeros(2,3,dtype torch.long)print(x)
关于torch.zeros:
torch.zeros(*size, outNone, dtypeNone, layouttorch.strided, deviceNone, requires_gradFalse) → Tensor 返回一个值全为0的张量张量大小由参数size定义值类型由torch.dtype定义。参数说明 size(int…)是一个用于定义输出的张量的形状的整形序列也可以是list或者turple。 out(Tensor可选)要求的值为张量默认为none。也可以令out为一个具体张量aa的shape与参数size相同这样输出的张量就会和a一样。 dtype(torch.dtype可选): 要求的值的类型是torch.dtype默认值是torch.set_default_tensor_type的值。可以通过这个dtype参数来改变输出的张量的数据类型。 layout(torch.layout可选)torch.layput表示torch.Tensor内存布局的对象。这个参数表示你希望返回的张量的内存布局类型默认为torch.strided。torch.strided代表密集型张量是最常见的内存布局每个strided张量都关联一个torch.Storagetorch.Storage保存着strided张量的数据。 device(torch.device,可选):创建的张量存放的device。 requires_grad(bool可选)要求的值为bool类型默认为False。若为False则反向传播时不会对这个节点求导。
创建一个全是1的张量并在此基础上创建新的张量
在现有张量上创建的张量其属性将重用输入张量的属性除非用户提供新的值。
x x.new_ones(2,3,dtype torch.double)#创建一个全是1的矩阵。print(x)x torch.rand_like(x,dtype torch.float)#重新设定了dtypeprint(x)#可以看到形状一样但数据类型不同了。tensor torch.tensor((),dtype torch.int32)print(tensor)#输出为tensor([], dtypetorch.int32)tensor tensor.new_ones(2,3)print(tensor)#输出为tensor([[1, 1, 1],[1, 1, 1]], dtypetorch.int32)可以看到改变了形状、类型与值。
关于torch.new_ones和torch.rand_like:
new_ones(size, dtypeNone, deviceNone, requires_gradFalse) → Tensor 返回一个值全为1的张量张量的size和dtype与tensor相同。参数说明 size(int…)是一个用于定义输出的张量的形状的整形序列也可以是list或者turple。 dtype(torch.dtype可选): 要求的值的类型是torch.dtype默认值是None。若为None则为与tensor相同的torch.dtype。 device(torch.device,可选):创建的张量存放的device默认与input相同。 requires_grad(bool可选)要求的值为bool类型默认为False。若为False则反向传播时不会对这个节点求导。 torch.randn_like(input, *, dtypeNone, layoutNone, deviceNone, requires_gradFalse, memory_formattorch.preserve_format) -> Tensor 返回一个和input相同size的张量这个张量由均值为0方差为1的标准正态分布填充。参数说明 dtype(torch.dtype可选): 要求的值的类型是torch.dtype默认值是None。若为None则为与input相同的torch.dtype。 layout(torch.layout可选)torch.layput表示torch.Tensor内存布局的对象。这个参数表示你希望返回的张量的内存布局类型默认为input的分布。 device(torch.device, 可选):创建的张量存放的device,默认与input相同。 requires_grad(bool可选)要求的值为bool类型默认为False。若为False则反向传播时不会对这个节点求导。 memory_format(torch.memory_format, 可选): 期望返回张量的保存类型默认为torch.preserve_format。torch.memory类型用于保存torch.Tensor的储存格式。torch.preserve_format是保留输入张量的内存格式用在clone这样的函数中。如果输入张量是分配在稠密不重叠的内存中那么输出张量的stride与输入相同。否则输出的strides使用torch.contiguous_format。
创建一个值全为3.1416的5*3的矩阵
print(torch.full((5, 3), 3.1416)
关于torch.full
torch.full(size, fill_value, *, outNone, dtypeNone, layouttorch.strided, deviceNone, requires_gradFalse, pin_memoryFalse) → Tensor 返回一个未初始化的张量张量大小由参数size定义。参数说明 size(int…)是一个用于定义输出的张量的形状的整形序列也可以是list或者turple。 out(Tensor可选)要求的值为张量默认为none。也可以令out为一个具体张量aa的shape与参数size相同这样输出的张量就会和a一样。上面的例子可以看出。 dtype(torch.dtype可选): 要求的值的类型是torch.dtype默认值是torch.set_default_tensor_type的值。可以通过这个dtype参数来改变输出的张量的数据类型。 layout(torch.layout可选)torch.layput表示torch.Tensor内存布局的对象。这个参数表示你希望返回的张量的内存布局类型默认为torch.strided。torch.strided代表密集型张量是最常见的内存布局每个strided张量都关联一个torch.Storagetorch.Storage保存着strided张量的数据。 device(torch.device,可选):创建的张量存放的device。 requires_grad(bool可选)要求的值为bool类型默认为False。若为False则反向传播时不会对这个节点求导。
创建一个n维单位矩阵
创建一个维度为4对角线位置为1其他位置全为0的二维张量。
eye torch.eye(4)print(eye.size())#获得张量eye的形状是一个元组print(eye)
关于torch.eye:
torch.eye(n, mNone, *, outNone, dtypeNone, layouttorch.strided, deviceNone, requires_gradFalse) → Tensor 返回一个行数为n列数为m对角线上为1而其他位置为0的二维张量。参数说明n(int):要求输入一个整数表示行数。m(int):要求输入一个整数表示列数默认为None。如果为None则m的值为n。 out(Tensor可选)要求的值为张量默认为none。也可以令out为一个具体张量aa的shape与参数size相同这样输出的张量就会和a一样。 dtype(torch.dtype可选): 要求的值的类型是torch.dtype默认值是torch.set_default_tensor_type的值。可以通过这个dtype参数来改变输出的张量的数据类型。 layout(torch.layout可选)torch.layput表示torch.Tensor内存布局的对象。这个参数表示你希望返回的张量的内存布局类型默认为torch.strided。torch.strided代表密集型张量是最常见的内存布局每个strided张量都关联一个torch.Storagetorch.Storage保存着strided张量的数据。 device(torch.device,可选):创建的张量存放的device。 requires_grad(bool可选)要求的值为bool类型默认为False。若为False则反向传播时不会对这个节点求导。
3.基本运算操作
pytorch中的加法运算
首先创建张量
a torch.rand(5,3)b torch.rand(5,3)print(a)print(b)print(a b)print(torch.add(a, b))result torch.empty(5,3)torch.add(a, b, out result)#out参数提供一个输出张量作为加法的结果print(result)#任何改变一个张量的操作都用 _ 进行后固定。例如:‘x.copy_ (y)’, ‘x.t_()’,将改变x。a.add_(b)#加了下划线之后表示做a a b的操作改变了a。print(a)
关于torch.add和torch.add_:
torch.add(input, other, *, alpha 1out None) → Tensor 返回input alpha*other的结果。参数说明input(Tensor):要求输入一个张量。other(Tensor):要求输入一个张量input和other必须是可广播的。 alpha(Number):other的乘数要求输入是数字默认为1。如果input是一个float的type是FloatTensor或者DoubleTensor那么alpha必须是一个实数否则应该是整型数。 out(Tensor,可选): 输出矩阵默认为None。若不为None则结果存储与out提供的张量里。 Tensor.add_(other, *, alpha 1out None) → Tensor torch.add()的in-place版本各参数详解可见torch.add()。做Tensor Tensor other*alpha操作。
pytorch中的减法运算
首先创建张量
a torch.rand(5,3)b torch.rand(5,3)print(a)print(b)print(a - b)print(torch.sub(a, b))result torch.empty(5,3)torch.sub(a, b, out result)#out参数提供一个输出张量作为减法的结果print(result)a.sub_(b)#加了下划线之后表示做a a-b的操作改变了a。print(a)
关于torch.sub和torch.sub_:
torch.sub(input, other, *, alpha 1out None) → Tensor 返回input - alpha*other的结果。支持广播到公共形状、类型提升以及整数、浮点和复杂输入。参数说明input(Tensor):要求输入一个张量。other(Tensor):要求输入一个张量input和other必须是可广播的。 alpha(Number):other的乘数要求输入是数字默认为1。 out(Tensor,可选): 输出矩阵默认为None。若不为None则结果存储与out提供的张量里。 Tensor.sub_(other, *, alpha 1out None) → Tensor torch.sub()的in-place版本各参数详解可见torch.sub()。做Tensor Tensor - other*alpha操作。
pytorch的点乘
a torch.rand(5,3)b torch.rand(5,3)mul1 a*bmul2 torch.mul(a,b)torch.mul(a , b, out mul3)print(mul1. size())print(mul1)print(mul2. size())print(mul2)print(mul3.size())print(mul3)
关于mul
torch.mul(input, other, *, out None) → Tensor 返回input和other的哈达玛积即对应元素相乘。参数说明input(Tensor):要求输入一个张量。other(Tensor or Number):要求输入一个张量或数字若输入的是张量则要求input和other必须是可广播的。输入类型可以是integerfloat或者complex。 out(Tensor,可选): 输出矩阵默认为None。若不为None则结果存储与out提供的张量里。
pytorch的矩阵乘法
对二维Tensor
a torch.rand(5,3)b torch.rand(3,5)mat1 torch.mm(a,b)mat2 torch.matmul(a,b)mat3 abprint(mat1.size(), mat2.size(), mat3.size())print(mat1)print(mat2)print(mat3)
对更高维度的Tensor定义的矩阵乘法仅在最后两个维度上
a torch.rand(5,3,2,4,3)b torch.rand(5,3,2,3,4)mat1 torch.matmul(a,b)print(mat1.size())
torch.matmul中的广播机制以及一些例子
#向量×向量a torch.rand(3)b torch.rand(3)print(torch.matmul(a, b).size())#torch.Size([])#矩阵×向量a torch.rand(3,4)b torch.rand(3)print(torch.matmul(a, b).size())#torch.Size([3])#批处理矩阵x广播向量a torch.rand(10,3,4)b torch.rand(3)print(torch.matmul(a, b).size())#做矩阵乘法时b的size广播成(10,3,)了#torch.Size([10, 3])#批处理矩阵x批处理矩阵a torch.rand(10,3,4)b torch.rand(10,4,5)print(torch.matmul(a, b).size())#torch.Size([10, 3, 5])#批处理矩阵x广播矩阵a torch.rand(10,3,4)b torch.rand(4,5)print(torch.matmul(a, b).size())#做矩阵乘法时b的size广播成(10,4,5)了#torch.Size([10, 3, 5])#批处理矩阵x广播矩阵前面维度为1的情况a torch.rand(10,1,3,4)b torch.rand(6,4,5)print(torch.matmul(a, b).size())#做矩阵乘法时a和b的size广播成(10,6,4,5)了# torch.Size([10, 6, 3, 5])
关于torch.matmul:
torch.matmul( input , other , * , outNone ) → Tensor 返回input和other的矩阵乘积。参数说明input(Tensor):要求输入一个张量。other(Tensor or Number):要求输入一个张量或数字若输入的是张量则要求input和other必须是可广播的。输入类型可以是integerfloat或者complex。 out(Tensor,可选): 输出矩阵默认为None。若不为None则结果存储与out提供的张量里。一维点积的情况不支持out参数。
pytorch的除法
a torch.tensor([0.3810, 1.2774, -0.2972, -0.3719, 0.4637])print(torch.div(a,0.5))#张量除标量a torch.tensor([[-0.3711, -1.9353, -0.4605, -0.2917], [ 0.1815, -1.0111, 0.9805, -1.5923], [ 0.1062, 1.4581, 0.7759, -1.2344], [-0.1830, -0.0313, 1.1908, -1.4757]])b torch.tensor([ 0.8032, 0.2930, -0.8113, -0.2308])print(torch.div(a, b))#张量除张量print(torch.div(a,b,rounding_mode ‘trunc’))#舍入模式为‘trunc’则将结果向零舍入相当于c语言的整数除法print(torch.div(a,b,rounding_mode ‘floor’))#舍入模式为‘floor’则结果向下舍入相当于python中的//运算
关于torch.div:
torch.div(input, other, *, rounding_mode None, out None) → Tensor 返回input的每个元素除以other对应元素的结果形成的张量。支持广播到通用形状、 类型提升以及整数、浮点数和复杂输入。始终将整数类型提升为默认标量类型。参数说明input(Tensor):要求输入一个张量。被除数。other(Tensor or Number):要求输入一个张量或数字若输入的是张量则要求input和other必须是可广播的。输入类型可以是integerfloat或者complex。rounding_mode(str, 可选): 结果的选择类型要求输入字符串默认为None。若为None则不执行舍入相当于python中的/运算符若为‘trunc’则将结果向零舍入相当于c语言的整数除法若为‘floor’则结果向下舍入相当于python中的//运算符。 out(Tensor,可选): 输出矩阵默认为None。若不为None则结果存储与out提供的张量里。
pytorch的Resize
x torch.randn(4,4)print(x.view(16).size())print(x.view(-1,8).size())#大小-1是从其他标注推断出来的
关于Tensor.view
Tensor.view(*shape) → Tensor 返回一个数据与Tensor相同但形状与shape与所给参数一样的张量。参数说明shape(torch.Size 或者int…):要求输入的是torch.size类型或者整形序列。表示输出的张量的形状。
4.其他一些常用操作
幂运算与开方
a torch.full([2, 2], 3)print(a.pow(2))#对应元素的乘方为值的张量print(a.sqrt())#对应元素的开方为值的张量print(a.rsqrt())#对应元素的开方的倒数为值的张量
指数与对数
a torch.full([2, 2], 1)print(torch.exp(a))#e的对应元素次方为值的张量print(torch.log(a))#取对应元素的值的自然对数为值的张量
近似值
a torch.tensor(3.1416)print(a.floor())#向下取整print(a.ceil())#向上取整print(a.trunc())#取整print(a.frac())#取小数print(a.round())#四舍五入
裁剪运算
#对Tensor中的元素进行过滤超过给定上界的元素变为上界低于给定下界的元素变为下界常用于机器学习中的梯度裁剪。a torch.rand(5,3)*10print(a.clamp(8)) #最小是8,小于8的都变成8print(a.clamp(3,8)) # 最小是3,小于3的都变成3;最大是8,大于8的都变成8
5.常用数据缩减操作
求最大最小值
a torch.rand(5,3)*10print(torch.max(a))#返回张量所有值的最大值print(torch.max(a,0))#沿着第0维度求最大值。结果的shape为3print(torch.max(a,1)) #沿着第1维度求最大值。结果的shape为5print(torch.min(a))#返回张量所有值的最小值print(torch.min(a,0))#沿着第0维度求最小值。结果的shape为3print(torch.min(a,1)) #沿着第1维度求最小值。结果的shape为5
求平均值
a torch.rand(5,3)*10print(torch.mean(a))#返回张量所有值的平均值print(torch.mean(a,0))#沿着第0维度求平均值。结果的shape为3print(torch.mean(a,1)) #沿着第1维度求平均值。结果的shape为5
求输入张量的元素的积
a torch.rand(5,3)print(torch.prod(a))#a的所有元素的积print(torch.prod(a,0))#沿着第0维度求积。结果的shape为3print(torch.prod(a,1)) #沿着第1维度求积。结果的shape为5
求输入张量的元素的标准差
a torch.rand(5,3)print(torch.std(a))#a的所有元素的标准差print(torch.std(a,0))#沿着第0维度求标准差。结果的shape为3print(torch.std(a,1)) #沿着第1维度求标准差。结果的shape为5
求输入张量的元素的方差
a torch.rand(5,3)print(torch.var(a))#a的所有元素的方差print(torch.var(a,0))#沿着第0维度求方差。结果的shape为3print(torch.var(a,1)) #沿着第1维度求方差。结果的shape为5
求输入张量的元素的和
a torch.rand(5,3)print(torch.sum(a))#a的所有元素的和print(torch.sum(a,0))#沿着第0维度求和。结果的shape为3print(torch.sum(a,1)) #沿着第1维度求和。结果的shape为5
6.Numpy桥
可以将Torch张量转换为NumPy数组反之亦然。Torch张量和NumPy数组将共享它们的底层内存位置(如果Torch张量在CPU上)改变一个就会改变另一个。
#torch转numpya torch.ones(5)print(a)b a.numpy()print(b)#改变a的值后b的值也会发生变化。a.add_(1)print(a)print(b)#numpy转torcha np.ones(5)b torch.from_numpy(a)np.add(a, 1, outa)# 改变a的值后b的值也会发生变化。print(a)print(b)
7.结语
Numpy是一个很棒的框架但是它不能利用gpu来加速它的数值计算。对于现代的深度神经网络gpu通常提供50倍或更高的加速所以很不幸numpy不足以满足现代的深度学习。
这里我们介绍最基本的PyTorch概念:张量。PyTorch张量在概念上与numpy数组相同:张量是一个n维数组PyTorch提供了许多操作这些张量的函数。在幕后张量可以跟踪计算图和梯度但它们作为科学计算的通用工具也很有用。
与numpy不同的是PyTorch张量可以利用gpu加速其数值计算。要在GPU上运行PyTorch张量你只需要将它转换为一个新的数据类型。
最后我想这篇文章后续还会更新一些我在学习的过程中常用的函数。关于计算图我想另写一篇文章来介绍也打算看看计算图可视化的一些基本操作。
8.参考
https://blog.csdn.net/Dontla/article/details/104675406/
https://blog.csdn.net/lzn025/article/details/114686880
https://blog.csdn.net/qq_32806793/article/details/102948456
https://blog.csdn.net/weicao1990/article/details/93738722?utm_mediumdistribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.controldistribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control
https://blog.csdn.net/sinat_337