PyTorch 相关函数详解

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/zimiao552147572/article/details/94490528

人工智能AI:Keras PyTorch 深度学习实战(不定时更新) 


PyTorch中文文档:https://pytorch-cn.readthedocs.io/zh/latest/


1.torch.div()
	1.div_(value):div()的in-place运算形式
	2.torch.div(input, value, out=None)
		1.将input逐元素除以标量值value,并返回结果到输出张量out。 即 out=tensor/value
		  如果输入是FloatTensor or DoubleTensor类型,则参数 value 必须为实数,否则须为整数。
		  译注:似乎并非如此,无关输入类型,value取整数、实数皆可。
		2.参数:
			input (Tensor) – 输入张量
			value (Number) – 除数
			out (Tensor, optional) – 输出张量

		3.例子
				import torch
				a = torch.randn(5)
				a 输出
					-0.6147
					-1.1237
					-0.1604
					-0.6853
					 0.1063
					[torch.FloatTensor of size 5]

				torch.div(a, 0.5)
				输出
					-1.2294
					-2.2474
					-0.3208
					-1.3706
					 0.2126
					[torch.FloatTensor of size 5]

	3.torch.div(input, other, out=None)
		1.两张量input和other逐元素相除,并将结果返回到输出。即 out_i=input_i/other_i
		  两张量形状不须匹配,但元素数量须一致。
	           注意:当形状不匹配时,input的形状作为输出张量的形状。
		2.参数:
			input (Tensor) – 张量(分子)
			other (Tensor) – 张量(分母)
			out (Tensor, optional) – 输出张量
		3.例子:
			import torch
			a = torch.randn(4,4)
			a 输出
				-0.1810  0.4017  0.2863 -0.1013
				 0.6183  2.0696  0.9012 -1.5933
				 0.5679  0.4743 -0.0117 -0.1266
				-0.1213  0.9629  0.2682  1.5968
				[torch.FloatTensor of size 4x4]

			b = torch.randn(8, 2)
			b 输出
				 0.8774  0.7650
				 0.8866  1.4805
				-0.6490  1.1172
				 1.4259 -0.8146
				 1.4633 -0.1228
				 0.4643 -0.6029
				 0.3492  1.5270
				 1.6103 -0.6291
				[torch.FloatTensor of size 8x2]

			torch.div(a, b)
			输出
				-0.2062  0.5251  0.3229 -0.0684
				-0.9528  1.8525  0.6320  1.9559
				 0.3881 -3.8625 -0.0253  0.2099
				-0.3473  0.6306  0.1666 -2.5381
				[torch.FloatTensor of size 4x4]

	4.torch.div(a, b)
		a和b必须是类型一致的,就是如果a是FloatTensor那么b也必须是FloatTensor,可以使用tensor.to(torch.float64)进行转换。
		1.例子
			>>> import torch
			>>> a = torch.randn(4, 4)
			>>> a
			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.randn(4)
			>>> b
			tensor([ 0.8032,  0.2930, -0.8113, -0.2308])
			>>> torch.div(a, b)
			tensor([[-0.4620, -6.6051,  0.5676,  1.2637],
					[ 0.2260, -3.4507, -1.2086,  6.8988],
					[ 0.1322,  4.9764, -0.9564,  5.3480],
					[-0.2278, -0.1068, -1.4678,  6.3936]])

		2.torch.div(a,0.6) 就是a直接除以一个数字。
			>>> import torch
			>>> a = torch.randn(5)
			>>> a
			tensor([ 0.3810,  1.2774, -0.2972, -0.3719,  0.4637])
			>>> torch.div(a, 0.5)
			tensor([ 0.7620,  2.5548, -0.5944, -0.7439,  0.9275])

2.Tensor张量化
	1.torch.FloatTensor 用于生成数据类型为浮点型的Tensor,参数可以是一个列表,也可以是一个维度。
		import torch
		a = torch.FloatTensor(3,4)  # 3行4列
		a
		Out[1]: tensor([[1.0561e-38, 1.0653e-38, 1.0469e-38, 9.5510e-39],
        			       [8.7245e-39, 1.0194e-38, 9.0919e-39, 8.7245e-39],
        			       [1.0194e-38, 1.0561e-38, 1.0286e-38, 1.6956e-43]])
		a = torch.FloatTensor([2,3,4,5])    # 一个列表	

	2.torch.IntTensor 用于生成数据类型为整型的Tensor,参数可以是一个列表,也可以是一个维度。
		a = torch.IntTensor(3,4)    # 3行4列
		a = torch.IntTensor([3,4,5,6])  # 一个列表
		a
		Out[9]: tensor([2., 3., 4., 5.])

3.torch.rand
	torch.rand 用于生成数据类型为浮点型且维度指定的Tensor,与NumPy的numpy.rand相似,随机生成的浮点数据在0-1区间均匀分布
		import torch
		a = torch.rand(2,3)
		Out[1]: tensor([[0.8768, 0.4990, 0.7870],
        			       [0.9143, 0.8974, 0.9184]])

4.torch.randn
	torch.randn 用于生成数据类型为浮点型且维度指定的随机Tensor,与NumPy的numpy.randn相似,随机生成的浮点数的取值满足均值为0,方差为1的正态分布。
		import torch
		a = torch.randn(2,2)
		a
		Out[11]:tensor([[ 0.7445, -0.4259],
        			       [ 0.8912,  1.1891]])

5.torch.range、torch.arange
	1.torch.range 用于生成数据类型为浮点型的且自定义取值范围的Tensor张量,参数有三个:起始值、结束值、步长。
		import torch
		a = torch.range(1,20,1)
		a
		Out[16]: tensor([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12., 13., 14.,15., 16., 17., 18., 19., 20.])

 	2.torch.arange(1,20,1) 用于生成数据类型为整数型的且自定义取值范围的Tensor张量,参数有三个:起始值、结束值、步长。
		import torch
		torch.arange(1,20,1)
		Out[17]:tensor([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19])

6.torch.zeros
	torch.zeros 用于生成数据类型为浮点型且维度指定的Tensor,元素全为0。
		import torch
		a = torch.zeros(3,2)
		a
		Out[23]: tensor([[0., 0.],
                                   [0., 0.],
                                   [0., 0.]])

7.torch的相关计算表达式
	torch.abs(a) 各项参数的绝对值
	torch.add(a,b) 求和
	torch.clamp(a,b,c) 对输入的参数按照自定义范围进行裁剪,参数有3个:裁剪对象、裁剪的上、下界。(将区间里面的东西减掉)
	torch.div(a,b) 求商
	torch.mul(a,b) 求积(不一定是矩阵)
	torch.pow(a,b) 求幂
	torch.mm(a,b) 求积(按矩阵和矩阵之间的规则做)
	torch.mv(a,b) 求积(按矩阵和向量之间的规则做)

 
8.matmul、bmm
	1.matmul、bmm 都可实现 矩阵乘法。
	2.例子
		import torch
		a = torch.rand((2,3,5))
		b = torch.rand((2,2,5))

		a
		Out[6]: 
		tensor([[[0.6171, 0.4499, 0.1373, 0.8756, 0.1020],
				 [0.2728, 0.3179, 0.6932, 0.6209, 0.4951],
				 [0.5625, 0.9915, 0.7839, 0.6911, 0.8923]],

				[[0.1649, 0.5676, 0.9854, 0.9652, 0.5538],
				 [0.1092, 0.1581, 0.5181, 0.2075, 0.3936],
				 [0.7013, 0.8210, 0.4233, 0.5804, 0.7319]]])
				 
		b
		Out[8]: 
		tensor([[[0.6307, 0.2868, 0.1641, 0.7782, 0.5756],
				 [0.4989, 0.2141, 0.5136, 0.7803, 0.4585]],

				[[0.6401, 0.0145, 0.9513, 0.2657, 0.9430],
				 [0.9943, 0.0030, 0.2987, 0.8750, 0.8087]]])
				 
		res1 = torch.matmul(a,b.transpose(1,2))
		res2 = torch.bmm(a,b.transpose(1,2))

		res1.size()
		Out[16]: torch.Size([2, 3, 2])

		res2.size()
		Out[17]: torch.Size([2, 3, 2])

		res1
		Out[14]: 
		tensor([[[1.2810, 1.2048],
				 [1.1452, 1.2717],
				 [1.8193, 1.8440]],

				[[1.8298, 1.7524],
				 [0.9913, 0.7636],
				 [1.7079, 1.9259]]])

		res2
		Out[15]: 
		tensor([[[1.2810, 1.2048],
				 [1.1452, 1.2717],
				 [1.8193, 1.8440]],

				[[1.8298, 1.7524],
				 [0.9913, 0.7636],
				 [1.7079, 1.9259]]])
		 

9.读取图片、保存图片
	1.读取图片
		import numpy
		from PIL import Image
		import os
		#创建一个118x73x3包含随机数字的Ndarray对象,数组中元素的类型为uint8
		data = numpy.empty((118,73 , 3), dtype="uint8")
		#指定读取的文件夹,把该目录下所有图片文件构建为一个列表,读取的图片也是 118x73x3
		imgs = os.listdir("E:\\photo") 
		#统计该文件夹下的图片数量
		num = len(imgs)  

		for i in range(num):
			#目的读取每个图片数据
			img = Image.open("E:\\photo\\"+imgs[i])
			#numpy.array和numpy.asarray都能把结构化数据(如数组)构建为一个Ndarray对象。
			arr = numpy.asarray(img, dtype="uint8")
			img.show()
			#数组数据进行可视化
			img1 = Image.fromarray(arr).convert('RGB') 
			img1.show()
			
			#转置三维数组,把三维数组默认的0,1,2对应的x,y,z轴 转置为 2,1,0对应的z,y,x轴
			convertARR=arr.transpose(2,1,0)
			#取第一层,即取三维数组中一级索引为0的二维数组
			img2=Image.fromarray(convertARR[0])
			img2.show()

	2.使用scipy.misc
		from PIL import Image
		import numpy
		from scipy import misc
		import imageio
		
		image = Image.open("E:\\0_train.jpg")  # 首先在该py文件所在目录下随便放一张图片,使用PIL.Image库的open方法打开
		image_array = numpy.array(image)  # 使用numpy将该图片的二进制数据转换成多维数组形式
		print(image_array)
		# imsave 在scipy 1.0.0中已弃用,将在1.2.0中删除
		# misc.imsave('E:\\out.jpg', image_array)  # 使用misc.imsave方法将数组保存为图片
		imageio.imwrite('E:\\out.jpg', image_array)

	3.使用PIL库
		from PIL import Image
		import numpy

		im = Image.open("E:\\0_train.jpg")  # 打开图片
		# 使用PIL库和numpy 只是为了快速得到一个可以用于保存为图片的数组,即从现有的图片直接转换成数组
		im_array = numpy.array(im)  # 将图片转化为numpy数组
		print(im_array)
		img = Image.fromarray(im_array).convert('RGB')  # 将数组转化回图片
		img.save("E:\\out.jpg")  # 将数组保存为图片

	4.使用matplotlib库
		注意:这种方式生成的图片默认是带坐标轴的,并且四周带有空白。你可以使用 matplotlib.pyplot中相关方法隐藏坐标轴。
		from PIL import Image
		import numpy
		import matplotlib.pyplot as plt

		im = Image.open("E:\\0_train.jpg")  # 打开图片
		im_array = numpy.array(im)  # 将图片转化为numpy数组
		print(im_array)
		#注意:imshow和savefig必须同一步一起执行才能存储带坐标轴的并且四周带有空白的图片,如果这两个方法分开两次执行的话,只会存储一张白色图片
		plt.imshow(im_array)  # 绘制图片,绘制出的图片带坐标
		plt.savefig("E:\\out.jpg")  # 保存图片

	5.使用opencv库
		from PIL import Image
		import numpy
		import cv2

		img = cv2.imread('E:\\0_train.jpg') # 打开图片
		img_array = numpy.array(img) # 将图片转化为numpy数组
		#注意:imshow显示图片的同时必须执行waitKey,才能正常显示图片
		cv2.imshow('img',img) #显示图片
		cv2.waitKey(0)
		cv2.imwrite("E:\\out.jpg", img_array) # 保存图片

10.Conv2d
	1.torch.nn.Conv2d(in_channels,out_channels,kernel_size,stride=1,padding=0,dilation=1,groups=1,bias=True)
	  将两个4维的向量input(样本数据矩阵)和filter(卷积核)做卷积运算,输出卷积后的矩阵 

	2.参数解释:
		1.in_channels:输入维度为 [batch_size, in_channels, in_height, in_width]  
		  out_channels:输出维度为 [batch_size, out_channels, out_height, out_width]  
		 	batch_size:样本的数量
		  	channels:每个样本的channels通道数,RGB图像的channels通道数是3
		  	in_channels:输入的通道数 
		  	out_channels:输出的通道数 
		 	height:每个样本的行数
		  	width:每个样本的列数
		  	in_height:输入的每个样本的行数
		  	in_width:输入的每个样本的列数
		  	out_height:输出的每个样本的行数
		  	out_width:输出的每个样本的列数
		2.kernel_size:卷积核大小为[filter_height, filter_width, in_channels, out_channels] 
			filter_height:卷积核的高,即行数
			filter_width:卷积核的宽,即列数
			in_channels:输入通道数 
			out_channels:输出通道数 
			比如第一层卷积核大小为 5*5,输入通道数是3,输出通道数是64,即这一层输出64个特征 
			比如第二层卷积核大小依然是5*5,输入则是64个通道即上一层的输出,输出通道数是64,即这一层输出64个特征
		3.stride:步长,即卷积核每次移动的步长。
		4.padding:每一维补零的数量。填充模式取值,只能为SAME或VALID。
			  卷积或池化后的节点数计算公式:output_w = int((input_w + 2*padding - filter_w)/strid_w) + 1 
		5.dilation:kernel间距,控制 kernel 点之间的空间距离。带孔卷积(atrous conv) 
		6.groups:控制 inputs 和 outputs 间的关联性(分组). 其中,要求 in_channels 和 out_channels 必须都可以被 groups 整除 

 	3.卷积层原理 
		卷积层是用一个固定大小的矩形区去席卷原始数据,将原始数据分成一个个和卷积核大小相同的小块,然后将这些小块和卷积核相乘输出一个卷积值,
		注意这里是一个单独的值,不再是矩阵了。卷积的本质就是用卷积核的参数来提取原始数据的特征,通过矩阵点乘的运算,提取出和卷积核特征一致的值,
		如果卷积层有多个卷积核,则神经网络会自动学习卷积核的参数值,使得每个卷积核代表一个特征。

	4.conv1d是一维卷积:只对宽度进行卷积。conv2d是二维卷积:对宽度和高度进行卷积。 
  	  conv1d 函数定义:torch.nn.functional.conv1d(input, weight, bias=None, stride=1, padding=0, dilation=1, groups=1)
	  参数说明:
		input:输入的Tensor数据为三维数组,格式为(batch, channels, W),第一维度是样本数量,第二维度是通道数或者记录数,第一维度是宽度。
		weight:卷积核权重,也就是卷积核本身,是一个三维数组,(out_channels, in_channels/groups, kW)。
		        out_channels 是卷积核输出层的神经元个数,也就是这层有多少个卷积核;in_channels是输入通道数;kW是卷积核的宽度。
		bias:位移参数,可选项,一般也不用管 
		stride:滑动窗口,默认为1,指每次卷积对原数据滑动1个单元格 
		padding:是否对输入数据填充0。Padding可以将输入数据的区域改造成是卷积核大小的整数倍,这样对不满足卷积核大小的部分数据就不会忽略了。
		         通过padding参数指定填充区域的高度和宽度,默认0(填充区域为0,不填充)。
		dilation:卷积核之间的空格,默认1 
		groups:将输入数据分组,通常不用管这个参数 

	5.conv1d示例
			import torch
			import torch.nn as nn
			import torch.nn.functional as F
			from torch.autograd import Variable
	 
			print("conv1d sample")

			a=range(16)
			x = Variable(torch.Tensor(a))
			x=x.view(1,1,16)
			print("x variable:", x)

			b=torch.ones(3)
			b[0]=0.1
			b[1]=0.2
			b[2]=0.3
			weights = Variable(b) #torch.randn(1,1,2,2)) #out_channel*in_channel*H*W
			weights=weights.view(1,1,3)
			print ("weights:",weights)

			y=F.conv1d(x, weights, padding=0)
			print ("y:",y)
			
			输出结果为:
			conv1d sample
			x variable: tensor([[[  0.,   1.,   2.,   3.,   4.,   5.,   6.,   7.,   8.,   9.,  10.,  11.,  12.,  13.,  14.,  15.]]])
			weights: tensor([[[ 0.1000,  0.2000,  0.3000]]])
			y: tensor([[[ 0.8000,  1.4000,  2.0000,  2.6000,  3.2000,  3.8000,  4.4000,  5.0000,  5.6000,  6.2000,  6.8000,  7.4000,  8.0000,  8.6000]]])
			
			它是怎么计算的:
				(1)原始数据大小是0-15的一共16个数字,卷积核宽度是3,向量是[0.1, 0.2, 0.3]. 第一个卷积是对 x[0:3] 共3个值 [0,1,2] 进行卷积,
					 公式如下:0x0.1+1x0.2+2x0.3=0.8
				(2)对第二个目标卷积,是 x[1:4 ]共3个值 [1,2,3] 进行卷积,公式如下:1x0.1+2x0.2+3x0.3=1.4
			看到和计算结果完全一致.

			conv1d 示意图如下:conv1d 和 conv2d 的区别就是只对宽度卷积,不对高度卷积. 最后的结果的宽度是原始数据的宽度减去卷积核的宽度再加上1,这里就是14。

猜你喜欢

转载自blog.csdn.net/zimiao552147572/article/details/94490528