Numpy 相关函数详解

1.transpose
	1.transpose函数:起到矩阵的转置效果
	2.什么是矩阵的转置:
    		1.补充文章:矩阵、向量 https://blog.csdn.net/zimiao552147572/article/details/90734447
    		2.简单地说:就是矩阵的行列转换,即行和列之间发生调换,那么同时行元素的索引也会和列元素的索引发生调换。
    		3.比如:矩阵A的第一行[1 2 0] 进行转置 转换之后成为了 矩阵的第一列,矩阵A的第二行[3 5 9] 进行转置 转换之后成为了 矩阵的第二列。
	3.下面介绍 transpose(二维矩阵):对行x列的二维矩阵进行转置
		1.arange(4)从0开始遍历4个数。reshape((2,2)) 生成一个 行x列(shape维度)为2x2的矩阵x,即二维张量(可看作二维数组)。
		2.例子:
			x = np.arange(4).reshape((2,2)) 
			print(x)
			[[0 1]   
			 [2 3]]

		2.transpose(矩阵x):矩阵x发生转置,矩阵x的行和列之间发生调换,那么同时行元素的索引也会和列元素的索引发生调换 
			1.可以看出转置之前矩阵x的第一行[0 1]就变成第一列,而原来的第一列[0 2]也变成第一行。
			2.此时的行元素的索引值也和列元素的索引值发生了调换。比如说:把二维矩阵x(二维张量x)看作是二维数组,
		  	  那么矩阵发生转置之前的元素值1的索引值可以写作是二维数组[0][1],而矩阵发生转置之后,元素值1的索引值可以写作是二维数组[1][0]。
			3.例子:
				x = np.arange(4).reshape((2,2))
				x = np.transpose(x) 
				print(x)
				[[0 2]
			 	 [1 3]]

	4.下面介绍 transpose(三维矩阵):对x轴、y轴、z轴的三维矩阵进行转置
		1.arange(12)从0开始遍历12个数。reshape((2,2,3)) 生成一个x轴、y轴、z轴为2x2x3的三维矩阵
		2.例子:
			x = np.arange(12).reshape((2,2,3))
			print(x)
			[[[ 0  1  2]
			  [ 3  4  5]]
			 [[ 6  7  8]
			  [ 9 10 11]]]

		2.transpose(三维矩阵x,(0,1,2)) 
			1.(0,1,2) 表示 x轴、y轴、z轴。(1,0,2) 表示 y轴、x轴、z轴。(2,0,1) 表示 z轴、x轴、y轴。以此类推。
			2.我们三维矩阵看作是三维数组,(0,1,2) 相当于表示 三维数组的(一维索引,二维索引,三维索引),
			  那么可以把 x轴、y轴、z轴分别看作是 一维索引、二维索引、三维索引。
			3.我们看一个元素 在三维矩阵x中的 x轴、y轴、z轴 的索引位置时,可以看成是这一个元素在三维数组中的一维索引、二维索引、三维索引的位置,
			  写成是 三维数组[三维索引][二维索引][一维索引]。
			4.例子:下面元素值7在三维矩阵x中的 x轴、y轴、z轴 的索引位置 从 三维矩阵x[1][0][1] 变成 三维矩阵x[0][1][1] 
				x = np.arange(12).reshape((2,2,3))
				x = np.transpose(x,(1,0,2)) 
				print(x)
				[[[ 0  1  2]
				  [ 6  7  8]]
				 [[ 3  4  5]
				  [ 9 10 11]]]

	5.mxnet中使用concat()、flatten()、transpose()
		>>> from mxnet import nd
		>>> a = nd.zeros((2, 3, 4, 5)) #格式为(批量⼤小,通道数,⾼,宽)
		>>> a.shape
		(2, 3, 4, 5)
		>>> b = nd.zeros((2, 6, 7, 8)) #格式为(批量⼤小,通道数,⾼,宽)
		>>> b.shape
		(2, 6, 7, 8)
		#可以看到,除了a和b两者之间除了批量⼤小相同之外,其他维度⼤小均不⼀样。
		#可以将a和b两者都变形成统⼀的格式,比如flatten压缩/降维,flatten()可以把“批量⼤小,通道数,⾼,宽”压缩为“批量⼤小,通道数 x ⾼ x 宽”,
		#然后再进行两者concat连结,从而让后续计算更简单。
		>>> a = a.transpose((0, 2, 3, 1))
		>>> b = b.transpose((0, 2, 3, 1))
		>>> a.shape
		(2, 4, 5, 3)
		>>> b.shape
		(2, 7, 8, 6)
		>>> a = a.flatten() #把“批量⼤小,通道数,⾼,宽”压缩为“批量⼤小,通道数 x ⾼ x 宽” 
		>>> b = b.flatten()
		>>> a.shape
		(2, 60)
		>>> b.shape
		(2, 336)
		#dim=0:表示按行方向连结。dim=1:表示按列方向连结。
		>>> c = nd.concat(*[a,b], dim=1)
		>>> c.shape
		(2, 396)
 
		>>> outputs = nd.zeros((2, 3, 4))
		>>> outputs.shape
		(2, 3, 4)
		>>> outputs[0].shape
		(3, 4)
		>>> outputs[-1].shape
		(3, 4)
		#默认dim=1:表示按列方向连结
		>>> encoding = nd.concat(outputs[0], outputs[-1])
		>>> encoding.shape
		(3, 8)
		#dim=1:表示按列方向连结
		>>> encoding = nd.concat(outputs[0], outputs[-1], dim=1)
		>>> encoding.shape
		(3, 8)
		#dim=0:表示按行方向连结。
		>>> encoding = nd.concat(outputs[0], outputs[-1], dim=0)
		>>> encoding.shape
		(6, 4)

	6.numpy.concatenate((a1, a2, ...), axis=0, out=None) 沿现有轴连接一系列数组 
		(a1, a2, ...):多个数组组成的序列。数组必须具有相同的形状,除了与轴对应的尺寸(默认为第一个轴)。
		axis轴:整数,可选。阵列将沿其连接的轴。如果axis为None,则在使用前将数组展平。默认值为0。
		out输出:ndarray,可选。如果提供,则为放置结果的目的地。形状必须正确,并且与未指定out参数的串联连接的形状匹配。
		返回值:ndarray

			当要串联的一个或多个数组为MaskedArray时,此函数将返回MaskedArray对象而不是ndarray,但不会保留输入掩码。
			如果需要使用MaskedArray作为输入,请改用MaskedArray模块中的ma.concatenate函数。

			>>> a = np.array([[1, 2], [3, 4]])
			>>> b = np.array([[5, 6]])
			>>> np.concatenate((a, b), axis=0)
			array([[1, 2],
			       [3, 4],
			       [5, 6]])
			>>> np.concatenate((a, b.T), axis=1)
			array([[1, 2, 5],
			       [3, 4, 6]])
			>>> np.concatenate((a, b), axis=None)
			array([1, 2, 3, 4, 5, 6])

			此函数将不会保留MaskedArray输入的掩码。

			>>> a[1] = np.ma.masked
			>>> b = np.arange(2, 5)
			>>> a
			masked_array(data=[0, --, 2],
				   mask=[False,  True, False],
				   fill_value=999999)
			>>> b
			array([2, 3, 4])
			>>> np.concatenate([a, b])
			masked_array(data=[0, 1, 2, 2, 3, 4],
				   mask=False,
				   fill_value=999999)
			>>> np.ma.concatenate([a, b])
			masked_array(data=[0, --, 2, 2, 3, 4],
				   mask=[False,  True, False, False, False, False],
				   fill_value=999999)

	7.转置T、transpose、swapaxes 的区别
		1.转置T 适用于一维数组、二维数组的转置

		2.对于高维数组,transpose需要用到一个用axis轴编号组成的元组,才能进行转置。比如一个三维的数组,对维度进行axis轴编号就是0、1、2。

		3.swapaxes接受两个轴编号,进行两个轴之间的对换

2.clip
	1.clip(矩阵/数组,最小值,最大值) 
		即把矩阵/数组中的所有元素值控制在最小值和最大值的范围之内,包含最小值和最大值。
		比如说把 小于最小值的元素值 替换为 最小值,把 大于最大值的元素值 替换为 最大值。
	2.例子1:
		import numpy as np
		x=np.array([1,2,3,5,6,7,8,9])
		np.clip(x,3,8)

		Out[88]:
		array([3, 3, 3, 5, 6, 7, 8, 8])
	3.例子2:
		x=np.array([[1,2,3,5,6,7,8,9],[1,2,3,5,6,7,8,9]])
		np.clip(x,3,8)

		Out[90]:
		array([[3, 3, 3, 5, 6, 7, 8, 8],
		       [3, 3, 3, 5, 6, 7, 8, 8]])

3.axis
	0,1,2 分别表示 x轴、y轴、z轴。而x轴、y轴、z轴分别看作是 三维数组的 一维索引、二维索引、三维索引。
	axis=0:代表要计算的目标是在 x轴上的元素,也即三维数组中的 一维索引上的元素
	axis=1:代表要计算的目标是在 y轴上的元素,也即三维数组中的 二维索引上的元素
	axis=2:代表要计算的目标是在 z轴上的元素,也即三维数组中的 三维索引上的元素

	1.首先定义一个 2x3x4 的三维数组a 
		a = [[[1,2 ,3 ,4 ],
		      [5,6 ,7 ,8 ],
		      [9,10,11,12]],
		     [[13,14,15,16],
		      [17,18,19,20],
		      [21,22,23,24]]]	
	  打印a,输出如下:[[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], [[13, 14, 15, 16], [17, 18, 19, 20], [21, 22, 23, 24]]]

	2.用numpy中的sum函数对a求和,参数为axis=0,表示对x轴上的元素进行求和,即对三维数组中的一维索引上的元素(即两个二维数组)进行求和运算
		sum_0 = np.sum(a,axis = 0)
		print(sum_0)
	  输出结果是一个3x4的数组,如下:
		[[14 16 18 20]
 		 [22 24 26 28]
 		 [30 32 34 36]] 

	3.再用sum函数对a求和,参数为axis=1,表示对y轴上的元素进行求和,即对三维数组中的二维索引上的元素进行求和运算
		sum_1 = np.sum(a,axis = 1)
		print(sum_1)
	  输出结果是一个2x4的数组,如下:
		[[15 18 21 24]
 		 [51 54 57 60]] 
	
	4.最后用sum函数对a求和,参数为axis=2,表示对z轴上的元素进行求和,即对三维数组中的三维索引上的元素进行求和运算
		sum_2 = np.sum(a,axis = 2)
		print(sum_2)
	  输出结果是一个2x3的数组,如下:
		[[10 26 42]
 		 [58 74 90]] 

	5.例子:mean 求平均数
				>>> import numpy as np
				>>> x = nd.arange(24)
				>>> x
					[ 0.  1.  2.  3.  4.  5.  6.  7.  8.  9. 10. 11. 12. 13. 14. 15. 16. 17.
					 18. 19. 20. 21. 22. 23.]
					<NDArray 24 @cpu(0)>
					
				>>> x.shape
					(24,)
				>>> X = x.reshape((2,3,4))
				>>> X.shape
					(2, 3, 4)
					
				>>> X
					[[[ 0.  1.  2.  3.]
					  [ 4.  5.  6.  7.]
					  [ 8.  9. 10. 11.]]

					 [[12. 13. 14. 15.]
					  [16. 17. 18. 19.]
					  [20. 21. 22. 23.]]]
					<NDArray 2x3x4 @cpu(0)>
					
				>>> X.mean(axis=0,keepdims=True)
					[[[ 6.  7.  8.  9.]
					  [10. 11. 12. 13.]
					  [14. 15. 16. 17.]]]
					<NDArray 1x3x4 @cpu(0)>
					
				>>> X.mean(axis=(0,1),keepdims=True)
					[[[10. 11. 12. 13.]]]
					<NDArray 1x1x4 @cpu(0)>
					
				>>> X.mean(axis=(0,2),keepdims=True)
					[[[ 7.5]
					  [11.5]
					  [15.5]]]
					<NDArray 1x3x1 @cpu(0)>
					
				>>> X.mean(axis=(0,1,2),keepdims=True)
					[[[11.5]]]
					<NDArray 1x1x1 @cpu(0)>
					
				>>> X.mean(keepdims=True)
					[[[11.5]]]
					<NDArray 1x1x1 @cpu(0)>
					
				>>> X.mean()
					[11.5]
					<NDArray 1 @cpu(0)>
 

4.reshape、resize 
	rand(行数,列数)、reshape(行数,列数)、resize(行数,列数):均表示输出的二维数组有多少行和多少列
	ones(元素数量)、reshape(元素数量,)、resize(元素数量,):均表示输出的一维数组中有多少个元素,没有行和列的概念

	1.reshape的参数
		import numpy as np
		x = np.random.rand(2, 3) # rand(行数,列数)输出的二维数组有多少行和多少列
		x
		Out[8]: 
		array([[0.87142079, 0.36339385, 0.78354857],
		       [0.37868941, 0.81610695, 0.85866942]])
			   
		x.reshape((3, 2)) # 参数可以是tuple类型。reshape((3, 2))代表3行和2列
		Out[10]: 
		array([[0.87142079, 0.36339385],
		       [0.78354857, 0.37868941],
		       [0.81610695, 0.85866942]])

		x.reshape(3, 2) # reshape((3, 2))代表3行和2列
		Out[9]: 
		array([[0.87142079, 0.36339385],
		       [0.78354857, 0.37868941],
		       [0.81610695, 0.85866942]])

	2.reshape可以实现维度的提升
		import numpy as np
		x = np.ones(3) #输出一个一维数组
		x
		Out[45]: array([1., 1., 1.])

		x.reshape(3, 1) #reshape(3, 1)代表二维数组的3行和1列,即列向量
		Out[46]: 
		array([[1.],
		       [1.],
		       [1.]])
			   
		x.reshape(1, 3) #reshape(1, 3)代表二维数组的1行和3列
		Out[47]: array([[1., 1., 1.]])
 
		x = x.reshape(3, 1) #把二维数组赋值给x
		x
		Out[49]: 
		array([[1.],
		       [1.],
		       [1.]])

		x.reshape(3,) #reshape(3,)类似于resize(3,),均表示一维数组,没有行和列的概念
		Out[50]: array([1., 1., 1.])

	3.reshape 与 resize 的共同点和区别
		1.resize(行数,列数) 和 reshape(行数,列数) 功能相似,都能把原数组的维度修改为指定的行数和列数
		2.reshape:自动打印返回值,并且不会自动对原数组的变量进行赋值修改
		  resize:不会自动打印返回值,但是会自动对原数组的变量进行赋值修改
		3.例子1:
			import numpy as np
			x = np.random.randn(2,3) # rand(行数,列数)输出的二维数组有多少行和多少列
			x
			Out[56]: 
			array([[-1.55098162, -0.56536057,  1.15585853],
			       [ 1.42571645,  0.53458812, -1.08388166]])
				   
			x.reshape(3, 2) # reshape(3, 2)代表3行和2列
			Out[57]: 
			array([[-1.55098162, -0.56536057],
			       [ 1.15585853,  1.42571645],
			       [ 0.53458812, -1.08388166]])

			x #原二维数组仍为2行3列,并没有被reshape(3, 2)自动修改为3行2列
			Out[58]: 
			array([[-1.55098162, -0.56536057,  1.15585853],
			       [ 1.42571645,  0.53458812, -1.08388166]])
				   
			x.resize((3, 2)) #resize(3, 2)和resize((3, 2))作用相同
			x
			Out[60]: 
			array([[-1.55098162, -0.56536057],
			       [ 1.15585853,  1.42571645],
			       [ 0.53458812, -1.08388166]])
				   
		4.例子2:
			import numpy as np
			x = np.ones(3)
			x
			Out[70]: array([1., 1., 1.])

			x = x.reshape(3, 1)
			x
			Out[72]: 
			array([[1.],
			       [1.],
			       [1.]])

			x.resize(3,) #resize(3,)类似于reshape(3,),均表示一维数组,没有行和列的概念
			x
			Out[74]: array([1., 1., 1.])

	4.reshape((-1,)) 等同于 reshape((-1)) 等同于 reshape(-1) 表示把维度仅压缩为一行
		>>> import numpy as np
		>>> x = np.arange(8).reshape((2,4))
		>>> x
			array([[0, 1, 2, 3],
				   [4, 5, 6, 7]])
		>>> x.shape
			(2, 4)
		>>> x.T
			array([[0, 4],
				   [1, 5],
				   [2, 6],
				   [3, 7]])
		#-1在这里应该可以理解为一个正整数通配符,它代替任何整数。
		#reshape((-1,)) 等同于 reshape((-1)) 等同于 reshape(-1) 实际表示一行
		>>> x.T.reshape((-1,))
			array([0, 4, 1, 5, 2, 6, 3, 7])


5.view
	1.view(i,j) 表示将原矩阵转化为i行j列的数组 
		如果i或j其中一个参数为-1的话,代表为-1的参数i或j将由另外一个参数来自动推断出来。
		比如Tensor张量a的元素个数是6个,如果使用view(1,-1)的话,代表可以根据Tensor张量a中的元素个数推断出-1代表6。
		如果参数i和j都并不是-1的话,那么参数i和j的乘积就必须和Tensor张量a的元素个数一致,否则就会出现错误。
 
	2.例子1:比如说 不管原数组是 [[[1,2,3],[4,5,6]]] 还是 [1,2,3,4,5,6],因为它们排成一维向量都是6个元素,所以只要view的参数一致,得到的结果都是一样的。
		import torch
		a = torch.Tensor([[[1,2,3],[4,5,6]]])
		a
		Out[6]: 
		tensor([[[1., 2., 3.],
			[4., 5., 6.]]])
				 
		b = torch.Tensor([1,2,3,4,5,6])
		b
		Out[8]: tensor([1., 2., 3., 4., 5., 6.])

		print(a.view(1,6))
		输出 tensor([[1., 2., 3., 4., 5., 6.]]) #结果是 1行6列的二维数组 
		print(b.view(1,6))
		输出 tensor([[1., 2., 3., 4., 5., 6.]]) #结果是 1行6列的二维数组 

	3.例子2:
		import torch
		a = torch.Tensor([[[1,2,3],[4,5,6]]])
		print(a.view(3,2)) #结果是 3行2列的二维数组 
		输出 tensor([[1., 2.],
        			    [3., 4.],
        			    [5., 6.]])

	4.view(-1,1):i为-1表示不限制行数,j为1表示输出1列,并且由列数自动推断出行数。参数i和j的乘积就必须和Tensor张量a的元素个数一致。
		import torch
		a = torch.randn(3,4)
		print(a) #结果是 3行4列的二维数组 
		输出 tensor([[-0.8146, -0.6592,  1.5100,  0.7615],
			    [ 1.3021,  1.8362, -0.3590,  0.3028],
			    [ 0.0848,  0.7700,  1.0572,  0.6383]])
		 
		b = a.view(-1,1)
		print(b) #结果是 12行1列的二维数组 
		输出 tensor([[-0.8146],
			    [-0.6592],
			    [ 1.5100],
			    [ 0.7615],
			    [ 1.3021],
			    [ 1.8362],
			    [-0.3590],
			    [ 0.3028],
			    [ 0.0848],
			    [ 0.7700],
			    [ 1.0572],
			    [ 0.6383]])

	5.view(1,-1):i为1表示输出1行,j为-1表示不限制列数,并且由行数自动推断出列数。参数i和j的乘积就必须和Tensor张量a的元素个数一致。
		import torch
		a = torch.randn(3,4)
		b = a.view(1,-1)
		print(b)
		输出 tensor([[-1.0434,  1.5415,  0.2021,  1.6665, -0.6832,  0.0834, -0.6546, -0.4237,-0.7604, -1.3496, -0.1711,  0.5373]])


	6.view(-1,2):i为-1表示不限制行数,j为2表示输出2列,并且由列数自动推断出行数。参数i和j的乘积就必须和Tensor张量a的元素个数一致。
		import torch
		a = torch.randn(3,4)
		b = a.view(-1,2)
		print(b)
		输出 tensor([[-0.8146, -0.6592],
        			    [ 1.5100,  0.7615],
        			    [ 1.3021,  1.8362],
        			    [-0.3590,  0.3028],
        			    [ 0.0848,  0.7700],
        			    [ 1.0572,  0.6383]])

	7.view(x.size(0), -1):x.size(0)表示二维数组的行数,x.size(1)表示二维数组的列数
		import torch
		x = torch.randn(3,4)
		x.size(0)
		Out[24]: 3
		x.size(1)
		Out[25]: 4
 		x = x.view(x.size(0), -1) 
		x
		Out[23]: tensor([[-0.0037, -0.1160,  0.6181, -0.2527],
        			        [-0.1866,  0.5236, -0.0461,  0.7004],
        			        [-0.0307,  0.3054, -1.0550,  0.3580]])

	8.view(i,j,k) 表示i,j,k分别代表1、2、3。1 表示一级索引或者x轴。2 表示二级索引或者y轴。3 表示三级索引或者z轴。
		1.比如img图片的size大小是(28,28,3),默认就是(1,2,3),可以利用img.view(3,1,2) 改变维度 得到一个size大小为(3,28,28)的tensor张量
		2.例子
			import torch
			import numpy 
			a = numpy.array([[[1,2,3],[4,5,6]]]) #三维数组
			b = torch.tensor(a) #张量化
			print(b.size())  #输出 torch.Size([1, 2, 3])
			print(b) #输出三维数组 tensor([[[1, 2, 3],[4, 5, 6]]], dtype=torch.int32)

			c = b.view(1,3,2)
			print(c.size())  #输出 torch.Size([1, 3, 2])
			print(c) #tensor([[[1, 2],[3, 4],[5, 6]]], dtype=torch.int32)

			c = b.view(2,3,1)
			print(c.size())  #输出 torch.Size([2, 3, 1])
			print(c)  #输出 tensor([[[1],[2],[3]],[[4],[5],[6]]], dtype=torch.int32)

			c = b.view(2,1,3)
			print(c.size())  #输出 torch.Size([2, 1, 3])
			print(c)  #输出 tensor([[[1, 2, 3]],[[4, 5, 6]]], dtype=torch.int32)

			c = b.view(3,2,1)
			print(c.size())  #输出 torch.Size([3, 2, 1])
			print(c) #输出 tensor([[[1],[2]],[[3],[4]],[[5],[6]]], dtype=torch.int32)

			c = b.view(3,1,2)
			print(c.size())  #输出 torch.Size([3, 1, 2])
			print(c) #输出 tensor([[[1, 2]],[[3, 4]],[[5, 6]]], dtype=torch.int32)

6.permute
	1.permute将tensor张量的维度进行换位。
	2.permute(i,j,k) 表示i,j,k分别代表0、1、2。0 表示一级索引或者x轴。1 表示二级索引或者y轴。2 表示三级索引或者z轴。
	2.比如img图片的size大小是(28,28,3),可以利用img.permute(2,0,1) 改变维度 得到一个size大小为(3,28,28)的tensor张量
	3.例子
		import torch
		import numpy 
		a = numpy.array([[[1,2,3],[4,5,6]]]) #三维数组
		b = torch.tensor(a) #张量化
		print(b.size())  #输出 torch.Size([1, 2, 3])
		print(b) #输出三维数组 tensor([[[1, 2, 3],[4, 5, 6]]], dtype=torch.int32)

		c = b.permute(0,2,1)
		print(c.size())     #输出 torch.Size([1, 3, 2])
		print(c) #输出 tensor([[[1, 4],[2, 5],[3, 6]]], dtype=torch.int32)
		 
		c = b.permute(2,0,1)
		print(c.size())     #输出 torch.Size([3, 1, 2])
		print(c) #输出三维数组 tensor([[[1, 4]],[[2, 5]],[[3, 6]]], dtype=torch.int32)
		 
		c = b.permute(2,1,0)
		print(c.size())     #输出 torch.Size([3, 2, 1])
		print(c)  #输出 tensor([[[1],[4]],[[2],[5]],[[3],[6]]], dtype=torch.int32)

		c = b.permute(1,0,2)
		print(c.size())     #输出 torch.Size([2, 1, 3])
		print(c) #输出 tensor([[[1, 2, 3]],[[4, 5, 6]]], dtype=torch.int32)

		c = b.permute(1,2,0)
		print(c.size())     #输出 torch.Size([2, 3, 1])
		print(c) #输出 tensor([[[1],[2],[3]],[[4],[5],[6]]], dtype=torch.int32)


7.max 
	max(a):用于从一维数据获取最大值。
	max(a,0):用于输出每列的最大值,同时输出该最大值所在的行号,从0开始。
	max(a,1):用于输出每行的最大值,同时输出该最大值所在的列号,从0开始。

		import torch 
		a=torch.randn(3)
		print(a)
		输出 tensor([-0.9081,  0.1852, -0.7775])
		print(torch.max(a)) #用于从一维数据获取最大值
		输出 tensor(0.1852)
		 
		b=torch.randn(3,4)
		print(b)
		输出 tensor([[ 1.4490, -0.3634,  0.1282, -0.2618],
			    [ 0.2759, -1.4153, -1.5801, -0.5629],
			    [ 0.2637,  0.6782, -0.1007, -0.2930]])

		print(torch.max(b,0)) #用于输出每列的最大值,同时输出该最大值所在的行号,从0开始
		输出 torch.return_types.max(values=tensor([ 1.4490,  0.6782,  0.1282, -0.2618]),indices=tensor([0, 2, 0, 0]))

		print(torch.max(b,1))#用于输出每行的最大值,同时输出该最大值所在的列号,从0开始
		输出 torch.return_types.max(values=tensor([1.4490, 0.2759, 0.6782]),indices=tensor([0, 0, 1]))

		print(torch.max(b,0)[0]) #输出每列的最大值
		输出 tensor([ 1.4490,  0.6782,  0.1282, -0.2618])

		print(torch.max(b,0)[1]) #输出该最大值所在的行号,从0开始
		输出 tensor([0, 2, 0, 0])

		print(torch.max(b,1)[0]) #输出每行的最大值 
		输出 tensor([1.4490, 0.2759, 0.6782])

		print(torch.max(b,1)[1]) #输出该最大值所在的列号,从0开始
		输出 tensor([0, 0, 1])

8.squeeze 
	1.squeeze(i):压缩矩阵,可理解为降维。压缩第i维,如果这第i维上的元素数量是1,则这第i维便可以压缩,即删除这一个维度,从三维数组变成二维数组。
		     但如果这第i维上的元素数量不为1的话,则不能压缩。i 表示为第几维度,从0开始计算,可以为0、1、2。
		     i为0表示三维数组中的第0维度(一级索引或者x轴),i为1表示第1维度(二级索引或者y轴),i为2表示第2维度(三级索引或者z轴)。
	2.rand(i,j,k):输出一个三维数组,i 表示一级索引或者x轴上有i个元素,j 表示二级索引或者y轴上有j个元素,k 表示三级索引或者z轴上有k个元素。
	3.例子
		import torch 
		a=torch.randn(1,3,4) #输出一个三维数组
		print(a.size()) #输出 torch.Size([1, 3, 4])
		print(a)
		#输出 tensor([[[ 0.3040,  1.1628, -0.2419, -0.9400],
			      [-0.3151,  1.3175, -1.0425,  0.6103],
			      [ 1.1924, -3.1194,  0.4040, -0.1440]]])
			 
		b=a.squeeze(0)	#压缩了第0维(第一级索引),因为该第0维(第一级索引)上的元素数量为1
		print(b.size())  #输出 torch.Size([3, 4])
		print(b)
		#输出 tensor([[ 0.3040,  1.1628, -0.2419, -0.9400],
			     [-0.3151,  1.3175, -1.0425,  0.6103],
			     [ 1.1924, -3.1194,  0.4040, -0.1440]])
			
		c=a.squeeze(1) 	#无法压缩第1维(第二级索引),因为该第1维(第二级索引)上的元素数量不为1
		print(c.size())  #输出 torch.Size([1, 3, 4])
		print(c)
		#输出 tensor([[[ 0.3040,  1.1628, -0.2419, -0.9400],
			      [-0.3151,  1.3175, -1.0425,  0.6103],
			      [ 1.1924, -3.1194,  0.4040, -0.1440]]])

9.unsqueeze 
	1.unsqueeze(i):表示增加第i维,同时将第i维上的元素数量设置为1。i 表示为第几维度,从0开始计算,可以为0、1、2。
		       i为0表示三维数组中的第0维度(一级索引或者x轴),i为1表示第1维度(二级索引或者y轴),i为2表示第2维度(三级索引或者z轴)。
	2.例子
		import torch 
		a=torch.randn(1,3,4) #输出一个三维数组
		print(a.size()) #输出 torch.Size([1, 3, 4])
		print(a)
		#输出 tensor([[[ 0.3040,  1.1628, -0.2419, -0.9400],
			      [-0.3151,  1.3175, -1.0425,  0.6103],
			      [ 1.1924, -3.1194,  0.4040, -0.1440]]])
			 
		b=a.squeeze(0)	#压缩了第0维(第一级索引),因为该第0维(第一级索引)上的元素数量为1
		print(b.size())  #输出 torch.Size([3, 4])
		print(b)
		#输出 tensor([[ 0.3040,  1.1628, -0.2419, -0.9400],
			     [-0.3151,  1.3175, -1.0425,  0.6103],
			     [ 1.1924, -3.1194,  0.4040, -0.1440]])
			
			
		c = b.unsqueeze(0) #增加第0维(一级索引),同时将第0维(一级索引)上的元素数量设置为1
		print(c.size()) #输出 torch.Size([1, 3, 4])
		print(c) 
		#输出 tensor([[[ 0.6359,  0.2509,  0.9233, -0.3784],
                                 [-0.2942, -0.4025,  1.1986,  0.6625],
                                 [ 1.1088,  2.0117,  1.1473, -1.2321]]])
 
		c = b.unsqueeze(1)  #增加第1维(二级索引),同时将第1维(二级索引)上的元素数量设置为1
		print(c.size()) #输出 torch.Size([3, 1, 4])
		print(c)
		#输出 tensor([[[ 0.6359,  0.2509,  0.9233, -0.3784]],
			     [[-0.2942, -0.4025,  1.1986,  0.6625]],
			     [[ 1.1088,  2.0117,  1.1473, -1.2321]]])
 
10.transpose

	1.参数:
		a:输入数组 
	  	axis:int类型的列表,这个参数是可选的。默认情况下,反转的输入数组的维度,当给定这个参数时,按照这个参数所定的值进行数组变换。 
		返回值:p:ndarray 返回转置过后的原数组的视图

	2.对于一维数组而言,transpose是不起作用的 。
	  例子:
		import numpy
		t = numpy.arange(4)  
		t
		Out[21]: array([0, 1, 2, 3])
		t.transpose()
		Out[22]: array([0, 1, 2, 3])

	3.二维数组分别有x轴和y轴,x轴对应的下标为0,y轴对应的下标为1,即二维数组默认顺序是(0,1)。
	  transpose(1,0):表示将二维数组的x轴和y轴互换,也即是对二维数组的转置操作,即矩阵转置。
	  transpose()对于二维数组的转置默认是transpose(1,0),因此对于二维数组执行transpose转置操作,调用transpose()和调用transpose(1,0)的两者效果一致。
	  transpose(1,0)不但会把数组维度从3x4互换为4x3,对应x轴和y轴上的元素也会跟着互换。
	  例子:
		import numpy
		two = numpy.arange(12).reshape(3,4)
		two
		Out[38]: 
		array([[ 0,  1,  2,  3],
		       [ 4,  5,  6,  7],
		       [ 8,  9, 10, 11]])
			   
		two.transpose()
		Out[39]: 
		array([[ 0,  4,  8],
		       [ 1,  5,  9],
		       [ 2,  6, 10],
		       [ 3,  7, 11]])
			   
		two.transpose(1,0)
		Out[40]: 
		array([[ 0,  4,  8],
		       [ 1,  5,  9],
		       [ 2,  6, 10],
		       [ 3,  7, 11]])
	

	4.三维数组分别有x轴和y轴和z轴,x轴对应的下标为0,y轴对应的下标为1,z轴对应的下标为2,即三维数组默认顺序是(0,1,2)。
	  transpose(2,1,0):表示将三维数组的x轴和z轴互换,y轴不变,也即是对三维数组的转置操作,即矩阵转置。
	  transpose()对于三维数组的转置默认是transpose(2,1,0),因此对于三维数组执行transpose转置操作,调用transpose()和调用transpose(2,1,0)的两者效果一致。
	  transpose(2,1,0)不但会把数组维度从2x3x3互换为3x3x2,对应x轴和z轴上的元素也会跟着互换。
	  例子
		import numpy
		three = numpy.arange(18).reshape(2,3,3)

		three
		Out[30]: 
		array([[[ 0,  1,  2],
            	        [ 3,  4,  5],
            	        [ 6,  7,  8]],
            	       [[ 9, 10, 11],
            	        [12, 13, 14],
            	        [15, 16, 17]]])

		three[0] #获取三维数组中一级索引为0的二维数组
		Out[73]:array([[0, 1, 2],
       			      [3, 4, 5],
       			      [6, 7, 8]])

		three.transpose()
		Out[31]: 
		array([[[ 0,  9],
            	        [ 3, 12],
            	        [ 6, 15]],
		       [[ 1, 10],
            	        [ 4, 13],
            	        [ 7, 16]],
		       [[ 2, 11],
            	        [ 5, 14],
            	        [ 8, 17]]])

		three = three.transpose(2,1,0)
		Out[32]: 
		array([[[ 0,  9],
            	        [ 3, 12],
            	        [ 6, 15]],
		       [[ 1, 10],
            	        [ 4, 13],
            	        [ 7, 16]],
		       [[ 2, 11],
            	        [ 5, 14],
            	        [ 8, 17]]])

		three[0] #获取三维数组中一级索引为0的二维数组
		Out[74]:array([[ 0,  9],
       			      [ 3, 12],
       			      [ 6, 15]])
 
11.数组中冒号的使用
	1.数组中冒号有三个用法:
		1.默认选择全部行或全部列;
		2.[开始行:结束行]:指定范围,左开右闭,包含开始行/开始列,但不包含结束行/结束列。
		3.[start:end:step] start:起始位置 end:结束位置 step:步长

	2.第一种用法 例子:默认选择全部行或全部列
		import numpy
		arr = numpy.arange(6).reshape(2,3) #2x3维度的二维数组
		arr
		Out[55]: array([[0, 1, 2],
			       [3, 4, 5]])
			   
		arr[:,0] #取所有行中的第一列
		Out[54]: array([0, 3])

		arr[:,1] #取所有行中的第二列
		Out[56]: array([1, 4])

		arr[0,:] #取第一行中的所有列
		Out[57]: array([0, 1, 2])

		arr[1,:] #取第二行中的所有列
		Out[58]: array([3, 4, 5])

		import numpy
		arr = numpy.arange(18).reshape(2,3,3)
		arr
		Out[60]: array([[[ 0,  1,  2],
		                 [ 3,  4,  5],
		                 [ 6,  7,  8]],
		                [[ 9, 10, 11],
		                 [12, 13, 14],
		                 [15, 16, 17]]])
				
		arr[0,:,:] #取三维数组中一级索引为0的整个二维数组
		Out[61]:array([[0, 1, 2],
		               [3, 4, 5],
		               [6, 7, 8]])

		arr[1,:,:] #取三维数组中一级索引为1的整个二维数组
		Out[62]:array([[ 9, 10, 11],
			      [12, 13, 14],
			      [15, 16, 17]])
		 
		arr[:,:,0] #取三维数组中任何三级索引为0的元素,为原高度X原宽度的二维数组
		Out[63]:array([[ 0,  3,  6],
			      [ 9, 12, 15]])

		arr[:,:,1] #取三维数组中任何三级索引为1的元素,为原高度X原宽度的二维数组
		Out[64]:array([[ 1,  4,  7],
			      [10, 13, 16]])

	3.第二种用法 例子:[开始行:结束行]:指定范围,左开右闭,包含开始行/开始列,但不包含结束行/结束列
		import numpy
		arr = numpy.arange(12).reshape(3,4) # 3x4维度的二维数组
		arr
		Out[68]: array([[ 0,  1,  2,  3],
			       [ 4,  5,  6,  7],
			       [ 8,  9, 10, 11]])
 
		arr[:,0:1] #取全部行中的第一列,但不包含第二列
		Out[69]: array([[0],
			       [4],
			       [8]])

		arr[:,0:2] #取全部行中的第一到第二列,但不包含第三列
		Out[70]:array([[0, 1],
			      [4, 5],
			      [8, 9]])

		arr[1:2,:] #取第二行中的所有列,但不包含第三行
		Out[71]: array([[4, 5, 6, 7]])

		arr[1:3,:] #取第二到第三行中的所有列,但不包含第三行
		Out[72]:array([[ 4,  5,  6,  7],
			      [ 8,  9, 10, 11]])

	4.第三种用法 例子:[start:end:step] start:起始位置 end:结束位置 step:步长
		>>> range(100)[20:30:2]
		[20, 22, 24, 26, 28]
 
12.zeros、ones、empty
	1.zeros():可以创建任意维度和元素个数的数组,数组内所有元素均为 0
	2.ones():可以创建任意维度和元素个数的数组,数组内所有元素均为 1
	3.empty():可以创建任意维度和元素个数的数组,数组内所有元素均为 随机数
	4.例子
			import numpy
			a = numpy.zeros(5)
			a
			Out[7]: array([0., 0., 0., 0., 0.])

			a = numpy.zeros(5,"int")
			a
			Out[15]: array([0, 0, 0, 0, 0])
			 
			a = numpy.zeros(5,"uint8")
			a
			Out[18]: array([0, 0, 0, 0, 0], dtype=uint8)

			a = numpy.zeros(5,"double")
			a
			Out[21]: array([0., 0., 0., 0., 0.])
			 
			a = numpy.ones(3)
			a
			Out[23]: array([1., 1., 1.])

			a = numpy.empty(4)
			a
			Out[56]: array([8.14220397e-312, 4.94065646e-324, 0.00000000e+000, 0.00000000e+000])
			 
			a = numpy.empty(6,"uint8")
			a
			Out[41]: array([ 88,   0,   0, 114,  13,  17], dtype=uint8)

			a = numpy.zeros([3,3])
			a
			Out[65]: 
			array([[0., 0., 0.],
			       [0., 0., 0.],
			       [0., 0., 0.]])
				   
			a = numpy.ones([4,4])
			a
			Out[70]: 
			array([[1., 1., 1., 1.],
			       [1., 1., 1., 1.],
			       [1., 1., 1., 1.],
			       [1., 1., 1., 1.]])

			a = numpy.empty([6,6],"uint8")
			a
			Out[63]: 
			array([[ 48, 240, 122, 180, 127,   1],
			       [  0,   0, 128, 248,  62, 107],
			       [  0,   0,   0,   0,   5,   0],
			       [  0,   0,   0,   0,   0,   0],
			       [255, 255, 255, 255, 255, 255],
			       [255, 255,   0,   0,   0,   0]], dtype=uint8)

13.array、asarray
	1.numpy.array和numpy.asarray都能把结构化数据(如数组)构建为一个Ndarray对象。
	2.当array和asarray读取的数据源为结构化数据(如数组data=[[1,1],[1,1]])时,array和asarray都会拷贝一份数据源作为Ndarray对象输出。
	3.当array和asarray读取的数据源为Numpy对象(Numpy函数创建的数组对象,如ones()、zeros())时,asarray拷贝一份Numpy对象数据作仍然为Ndarray对象输出。
	  而asarray不会拷贝Numpy对象数据,其输出Ndarray对象仍指向Numpy对象数据源本身。

	import numpy
	data=[[1,1,1],[1,1,1],[1,1,1]] 
	arr1=numpy.array(data) 
	arr2=numpy.asarray(data) 

	data[1][1]=2 
	data
	Out[8]: [[1, 1, 1], [1, 2, 1], [1, 1, 1]]

	arr1
	Out[9]: 
	array([[1, 1, 1],
	       [1, 1, 1],
	       [1, 1, 1]])

	arr2
	Out[10]: 
	array([[1, 1, 1],
	       [1, 1, 1],
	       [1, 1, 1]])
 
	import numpy
	arr1=numpy.ones((3,3)) 
	arr2=numpy.array(arr1) 
	arr3=numpy.asarray(arr1) 
	arr1[1]=2 

	arr1
	Out[16]: 
	array([[1., 1., 1.],
	       [2., 2., 2.],
	       [1., 1., 1.]])

	arr2
	Out[17]: 
	array([[1., 1., 1.],
	       [1., 1., 1.],
	       [1., 1., 1.]])

	arr3
	Out[18]: 
	array([[1., 1., 1.],
	       [2., 2., 2.],
	       [1., 1., 1.]])

14.NumPy Ndarray对象
	1.NumPy 最重要的一个特点是其 N 维数组对象 ndarray,它是一系列同类型数据的集合,以 0 下标为开始进行集合中元素的索引。
	  ndarray 对象是用于存放同类型元素的多维数组。ndarray 中的每个元素在内存中都有相同存储大小的区域。
	2.ndarray 内部由以下内容组成:
		1.一个指向数据(内存或内存映射文件中的一块数据)的指针。
		2.数据类型或 dtype,描述在数组中的固定大小值的格子。
		3.一个表示数组形状(shape)的元组,表示各维度大小的元组。
		4.一个跨度元组(stride),其中的整数指的是为了前进到当前维度下一个元素需要"跨过"的字节数。

	3.跨度可以是负数,这样会使数组在内存中后向移动,切片中 obj[::-1] 或 obj[:,::-1] 就是如此。
	4.创建一个 ndarray 只需调用 NumPy 的 array 函数即可:numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
	  参数说明:
		名称	描述
		object	数组或嵌套的数列
		dtype	数组元素的数据类型,可选
		copy	对象是否需要复制,可选
		order	创建数组的样式,C为行方向,F为列方向,A为任意方向(默认)
		subok	默认返回一个与基类类型一致的数组
		ndmin	指定生成数组的最小维度
	  ndarray 对象由计算机内存的连续一维部分组成,并结合索引模式,将每个元素映射到内存块中的一个位置。
	  内存块以行顺序(C样式)或列顺序(FORTRAN或MatLab风格,即前述的F样式)来保存元素。
	  ndarray类型,表示一个N维数组对象,其有一个shape(表维度大小)和dtype(说明数组数据类型的对象),使用zeros和ones函数可以创建数据全0或全1的数组。
	  numpy.ones(shape, dtype=None, order='C'):其中,shape表数组形状(m*n),dtype表类型,order表是以C还是fortran形式存放数据。
 
	5.例子
		实例 1
		import numpy as np 
		a = np.array([1,2,3])  
		print (a)
		输出结果如下:[1, 2, 3]
	 
		实例 2
		# 多于一个维度  
		import numpy as np 
		a = np.array([[1,  2],  [3,  4]])  
		print (a)
		输出结果如下:[[1, 2] 
			      [3, 4]]

		实例 3
		# 最小维度  
		import numpy as np 
		a = np.array([1,2,3,4,5], ndmin =  2)  
		print (a)
		输出如下:[[1, 2, 3, 4, 5]]
		
		实例 4
		# dtype 参数  
		import numpy as np 
		a = np.array([1,  2,  3], dtype = complex)  
		print (a)
		输出结果如下:[ 1.+0.j,  2.+0.j,  3.+0.j]

15.max 与 maximum
	1.numpy.max(a, axis=None, out=None, keepdims=False) 
		求序列的最值,最少接收一个参数。
		axis值默认为axis=0,axis=0 表示求列方向的最大值,axis=1 表示求行方向的最大值。

	2.numpy.maximum:(X, Y, out=None) 
		X序列中的逐个元素和Y比较取其最大值,最少接收两个参数。
		接收的的X、Y两个参数,也可以大小一致。当第二个参数Y是一个单独的值时,实际用到了维度的 broadcast广播机制。

 	3.例子
		import numpy as np 
		np.max([-2, -1, 0, 1, 2])
		输出 2
		np.maximum([-2, -1, 0, 1, 2], 0)
		输出 array([0, 0, 0, 1, 2])

16.numpy.random.uniform
	1.numpy.random.uniform(low, high, size)
		从一个均匀分布[low, high)中随机采样,注意定义域是左闭右开,即包含low,不包含high。
		参数介绍:
    			low 	采样下界,float类型,参数默认值为0 
    			high	采样上界,float类型,参数默认值为1 
    			size	输出样本数目,为int或元组(tuple)类型,例如,size=(m,n,k), 则输出m*n*k个样本,缺省时输出1个值 
 		返回值:ndarray类型,其形状和参数size中描述一致。
		例子:numpy.random.uniform(0,1,1200) 产生1200个[0, 1)的数

	2.ndarray类型,表示一个N维数组对象,其有一个shape(表维度大小)和dtype(说明数组数据类型的对象),使用zeros和ones函数可以创建数据全0或全1的数组。
	  numpy.ones(shape, dtype=None, order='C'):其中,shape表数组形状(m*n),dtype表类型,order表是以C还是fortran形式存放数据。
 
	3.类似uniform,还有以下随机数产生函数:
		numpy.random.randint(low, high=None, size=None, dtype='l')	产生随机整数 
		numpy.random.random_integers(low, high=None, size=None)	在闭区间上产生随机整数 
		numpy.random.random_sample(size=None)			在[0.0, 1.0)上随机采样 
		numpy.random.random(size=None)		和random_sample一样,是random_sample的别名 
		numpy.random.rand(d0,d1, ..., dn)		产生d0 - d1 - ... - dn形状的在[0,1)上均匀分布的float型数 
		numpy.random.randn(d0,d1,...,dn)		产生d0 - d1 - ... - dn形状的标准正态分布的float型数 
 
	4.numpy.random.randint(low, high=None, size=None, dtype='l')
		1.函数的作用是,返回一个随机整型数,范围从低(包括)到高(不包括),即[low, high)。
		  如果没有写参数high的值,则返回[0,low)的值。
		2.参数如下:
			1.low: int
				生成的数值最低要大于等于low。
				(hign = None时,生成的数值要在[0, low)区间内)
			2.high: int (可选)
				如果使用这个值,则生成的数值在[low, high)区间。
			3.size: int or tuple of ints(可选)
				输出随机数的尺寸,比如size = (m * n* k)则输出同规模即m * n* k个随机数。默认是None的,仅仅返回满足要求的单一随机数。
			4.dtype: dtype(可选):
				想要输出的格式。如int64、int等等
		3.输出:
			out: int or ndarray of ints
			返回一个随机数或随机数数组
		4.random.randint 例子
			>>> import numpy as np
			>>> np.random.randint(0, high=2, size=(2,3))
			array([[1, 1, 0],
			       [0, 1, 1]])
			>>> np.random.randint(0, high=2, size=(2,3))
			array([[0, 0, 1],
			       [0, 0, 1]])
			>>> np.random.randint(0, high=2, size=(2,3))
			array([[1, 1, 1],
			       [1, 0, 0]])
				   
			>>> np.random.randint(2, size=10)
			array([1, 0, 0, 0, 1, 1, 0, 0, 1, 0])
			>>> np.random.randint(1, size=10)
			array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

			>>> np.random.randint(5, size=(2, 4))
			array([[4, 0, 2, 1],
			       [3, 2, 2, 0]])

			>>>np.random.randint(2, high=10, size=(2,3))
			array([[6, 8, 7],
			       [2, 5, 2]])


17.numpy.clip(a, a_min, a_max, a=None)
	这个方法会给出一个区间,在区间之外的数字将被剪除到区间的边缘,例如给定一个区间[0,1],则小于0的将变成0,大于1则变成1。
		import numpy	
		a = numpy.arange(10)
		print(a) # [0 1 2 3 4 5 6 7 8 9]
		#限制在 1~8 之间	
		numpy.clip(a, 1, 8) # array([1, 1, 2, 3, 4, 5, 6, 7, 8, 8])
		#限制在 3~6 之间
		numpy.clip(a, 3, 6, out=a) # array([3, 3, 3, 3, 4, 5, 6, 6, 6, 6])
		# a的最小值限制在数组中对应索引位置上的值,最大值限制为 8
		numpy.clip(a, [3,4,1,1,1,4,4,4,4,4], 8) # array([3, 4, 2, 3, 4, 5, 6, 7, 8, 8])
		# a的最小值限制在数组中对应索引位置上的值,最大值限制为 5
		numpy.clip(a, [3,4,5,6,6,4,4,9,4,4], 5) # array([3, 4, 5, 6, 6, 5, 5, 9, 5, 5])

18.numpy.fabs(x)
	求解x的绝对值  
		import numpy
		numpy.fabs(-1) # 1.0
		numpy.fabs([-1.2, 1.2]) # array([1.2, 1.2])

19.math.pow(x,y)
	运算结果为x**y,即x的y次方。
		import math
		math.pow(100, 2) # 10000.0
		math.pow(100, -2) # 0.0001
		math.pow(3, 0) # 1.0


20.meshgrid
	import numpy as np
	>>> x = np.array([1,2,3])
	>>> y = np.array([4,5])
	#meshgrid生产一个list列表,里面是每个array数组,每个array数组的维度大小是由传入meshgrid函数的x和y的维度构成
	#第一个参数的数组大小是3,第二个参数的数组大小是2,那么meshgrid函数输出的结果list列表中的每个array的维度便是2X3
	#结果list列表中的第一个array的元素构成是array数组x的元素向下复制,第二个array的元素构成是array数组y的元素向右复制
	>>> z = np.meshgrid(x,y) 
	>>> z 
	[array([[1, 2, 3], 
	        [1, 2, 3]]), 
	 array([[4, 4, 4], 
	        [5, 5, 5]])]
 
	>>> x = np.array([1,2])
	>>> y = np.array([4,5,6])
	#第一个参数的数组大小是2,第二个参数的数组大小是3,那么meshgrid函数输出的结果list列表中的每个array的维度便是3X2
	>>> z = np.meshgrid(x,y)
	#结果list列表中的第一个array的元素构成是array数组x的元素向下复制,第二个array的元素构成是array数组y的元素向右复制
	>>> z
	[array([[1, 2],
	        [1, 2],
	        [1, 2]]), 
	 array([[4, 4],
	        [5, 5],
	        [6, 6]])]

	>>> a, b = np.meshgrid(x,y)
	>>> a
	array([[1, 2],
	       [1, 2],
	       [1, 2]])
	>>> b
	array([[4, 4],
	       [5, 5],
	       [6, 6]])
	>>> a.shape
	(3, 2)
	>>> b.shape
	(3, 2)
 
21.mgrid
	>>> import numpy as np
	#第一维度的范围值为-5到5,第一维度的维度大小为5
	>>> pp=np.mgrid[-5:5:5j]
	>>> pp
	array([-5. , -2.5,  0. ,  2.5,  5. ])
	>>> pp.shape
	(5,)
	#第一维度的维度大小为2,由两个矩阵组成。第二维度的范围值为-1到1,维度大小为2。第三维度的范围值为-2到2,维度大小为3。
	>>> pp = np.mgrid[-1:1:2j, -2:2:3j]
	#第一维度中的第一个矩阵中的元素为向右复制,第一维度中的第二个矩阵中的元素为向下复制
	>>> pp
	array([[[-1., -1., -1.],
	        [ 1.,  1.,  1.]],

	       [[-2.,  0.,  2.],
	        [-2.,  0.,  2.]]])
	>>> pp.shape
	(2, 2, 3)
	
	>>> x,y = np.mgrid[-1:1:2j, -2:2:3j]
	>>> x
	array([[-1., -1., -1.],
	       [ 1.,  1.,  1.]])
	>>> y
	array([[-2.,  0.,  2.],
	       [-2.,  0.,  2.]])
	>>> x.shape
	(2, 3)
	>>> y.shape
	(2, 3)
	
	#第一维度的维度大小为3,由三个矩阵组成。第二维度的范围值为-1到1,维度大小为2。
	#第三维度的范围值为-2到2,维度大小为3。第四维度的范围值为-3到3,维度大小为5。
	>>> pp = np.mgrid[-1:1:2j, -2:2:3j, -3:3:5j]
	#第一维度中的第一个矩阵中的元素为向下复制,第一维度中的第二个矩阵中的元素为向右复制,第一维度中的第三个矩阵中的元素为向下复制
	>>> pp
	array([[[[-1. , -1. , -1. , -1. , -1. ],
	         [-1. , -1. , -1. , -1. , -1. ],
	         [-1. , -1. , -1. , -1. , -1. ]],

	        [[ 1. ,  1. ,  1. ,  1. ,  1. ],
	         [ 1. ,  1. ,  1. ,  1. ,  1. ],
	         [ 1. ,  1. ,  1. ,  1. ,  1. ]]],


	       [[[-2. , -2. , -2. , -2. , -2. ],
	         [ 0. ,  0. ,  0. ,  0. ,  0. ],
	         [ 2. ,  2. ,  2. ,  2. ,  2. ]],

	        [[-2. , -2. , -2. , -2. , -2. ],
	         [ 0. ,  0. ,  0. ,  0. ,  0. ],
	         [ 2. ,  2. ,  2. ,  2. ,  2. ]]],


	       [[[-3. , -1.5,  0. ,  1.5,  3. ],
	         [-3. , -1.5,  0. ,  1.5,  3. ],
	         [-3. , -1.5,  0. ,  1.5,  3. ]],

	        [[-3. , -1.5,  0. ,  1.5,  3. ],
	         [-3. , -1.5,  0. ,  1.5,  3. ],
	         [-3. , -1.5,  0. ,  1.5,  3. ]]]])
			 
	>>> pp.shape
	(3, 2, 3, 5)
 

22.contour(矩阵的等高线图)
	1.contour函数链接:https://ww2.mathworks.cn/help/matlab/ref/contour.html
	2.contour(X,Y,Z) 指定 Z 中各值的 x 和 y 坐标。
	3.函数的等高线
		创建矩阵 X 和 Y,用于在 x-y 平面中定义一个网格。将矩阵 Z 定义为该网格上方的高度。然后绘制 Z 的等高线。
			x = linspace(-2*pi,2*pi);
			y = linspace(0,4*pi);
			[X,Y] = meshgrid(x,y);
			Z = sin(X)+cos(Y);
			contour(X,Y,Z)

	4.例子:动手学 深度学习 电子书PDF的 P262页 优化算法

23.std标准差(均方差)、平均方差、方差、mean均值
	data.std(axis=0)
		std 标准差(均方差):https://ww2.mathworks.cn/help/matlab/ref/std.html?searchHighlight=std&s_tid=doc_srchtitle
			1.标准差(Standard Deviation) ,中文环境中又常称均方差,是离均差平方的算术平均数的平方根,用σ表示。
		  	  算术平均数的重要特性之一是离均差平方和为最小,样本各观测值与平均数之差的平方和为最小,即离均差平方和为最小。
		  	  在概率统计中最常使用作为统计分布程度上的测量。
		  	  标准差(Standard Deviation),在概率统计中最常使用作为统计分布程度(statistical dispersion)上的测量。
		  	  测量到分布程度的结果,原则上具有两种性质:一个总量的标准差或一个随机变量的标准差,及一个子集合样品数的标准差之间,有所差别。
			2.方差与标准差的区别:
				  标准差是方差的算术平方根(平方根)。标准差能反映一个数据集的离散程度。
		  		  标准差定义为方差的算术平方根,反映组内个体间的离散程度。
				  方差是在概率论和统计方差衡量随机变量或一组数据时离散程度的度量。
				概率论中方差用来度量随机变量和其数学期望(即均值)之间的偏离程度。
				统计中的方差(样本方差)是每个样本值与全体样本值的平均数之差的平方值的平均数。
				在许多实际问题中,研究方差即偏离程度有着重要意义。
				标准差能反映一个数据集的离散程度。平均数相同的两组数据,标准差未必相同。
				方差是衡量源数据和期望值相差的度量值。
			3.平均方差
				样本中各数据与样本平均数的差的平方和的平均数叫做样本方差;样本方差的算术平方根叫做样本标准差。
				样本方差和样本标准差都是衡量一个样本波动大小的量,样本方差或样本标准差越大,样本数据的波动就越大。

  	data.mean(axis=0)
		mean 数组的均值:https://ww2.mathworks.cn/help/matlab/ref/mean.html?searchHighlight=mean&s_tid=doc_srchtitle

24.ogrid
	ogrid函数作为产生numpy数组与numpy的arange函数功能有点类似,不同的是:
		1.arange函数产生的是一维数组,而ogrid函数可产生的是一维数组/二维数组
		2.arange函数产生的是一个数组,而ogrid函数产生的是一个数组/二个数组
		3.ogrid函数产生的一个数组时,数组是以横向产生的。
		4.ogrid函数产生的两个数组时,第一个数组是以纵向产生的,即数组第二维的大小始终为1。
		  第二个数组是以横向产生的,即数组第一维的大小始终为1。

	创建两个数组
		1.ogrid[开始位置:结束位置:步长, 开始位置:结束位置:步长] 
		  不设置步长,默认为1。
		2.ogrid[开始位置:结束位置:复数步长, 开始位置:结束位置:复数步长]
		  复数步长的设置是通过数字+j进行设置的。复数步长表示的是结果输出指定个数字,每个数字之间相等分割整个从开始位置到结束位置的区间范围。
		  比如0:10:6j,表示结果输出6个数字,每个数字之间相等分割从0到1的区间范围,结果为0、2、4、6、8、10。
		  
	>>> from numpy import ogrid
	>>> x = ogrid[-1:1:5j]
	>>> x
	array([-1. , -0.5,  0. ,  0.5,  1. ])
	>>> x.shape
	(5,)
	>>> x,y = ogrid[0:10:6j,0:10:4j]
	>>> x,y
	(array([[ 0.],
		   [ 2.],
		   [ 4.],
		   [ 6.],
		   [ 8.],
		   [10.]]), 
	 array([[ 0. , 3.33333333, 6.66666667, 10. ]]))
	>>> x.shape
	(6, 1)
	>>> y.shape
	(1, 4)
	 
	>>> x,y = ogrid[0:5,0:5]
	>>> x,y
	[array([[0],
			[1],
			[2],
			[3],
			[4]]),
	 array([[0, 1, 2, 3, 4]])]
	>>> x.shape
	(5, 1)
	>>> y.shape
	(1, 5)
	>>> x,y = ogrid[:5,:5]
	>>> x,y
	[array([[0],
			[1],
			[2],
			[3],
			[4]]),
	 array([[0, 1, 2, 3, 4]])]		
	>>> x.shape
	(5, 1)
	>>> y.shape
	(1, 5)
	>>> x,y = ogrid[0:4:1,0:4:2]
	>>> x,y
	[array([[0],
		   [1],
		   [2],
		   [3]]), 
	 array([[0, 2]])]
	>>> x.shape
	(4, 1)
	>>> y.shape
	(1, 2)	

25.stack()
	1.主要的参数有两个,第一个参数为arrays,也就是用来作为堆叠的数组,第二个参数为axis也就是指定依照哪个维度上进行堆叠。
	2.例子
		>>> import numpy as np
		#利用列表生成式生成一个拥有10*3*4个元素的列表
		>>> arrays = [np.random.randn(3, 4) for _ in range(10)]
		>>> len(arrays)
		10
		>>> arrays[0].shape
		(3, 4)

		#列表中每个元素的维度为3*4,共有10个元素。在axis=0的第0维度进行堆叠后的shape为10*3*4
		>>> np.stack(arrays, axis=0).shape
		(10, 3, 4)
		#在axis=1的第1维度进行堆叠后的shape为3*10*4
		>>> np.stack(arrays, axis=1).shape
		(3, 10, 4)
		#在axis=2的第2维度进行堆叠后的shape为3*4*10
		>>> np.stack(arrays, axis=2).shape
		(3, 4, 10)

		>>> a = np.array([1, 2, 3])
		>>> b = np.array([2, 3, 4])
		#默认为axis=0,也就是在第0维度进行堆叠后的shape为(2, 3)
		>>> np.stack((a, b)) 
		array([[1, 2, 3],
			   [2, 3, 4]])
		#在axis=-1最后一维后进行堆叠后的shape为(3, 2)
		>>> np.stack((a, b), axis=-1)
		array([[1, 2],
			   [2, 3],
			   [3, 4]])

		>>> a = np.array([[1, 2, 3],[2,3,4]])
		>>> b = np.array([[4, 5, 6],[7,8,9]])
		#默认为axis=0
		>>> np.stack((a, b)).shape
		(2, 2, 3)
		>>> np.stack((a, b))
		array([[[1, 2, 3],
				[2, 3, 4]],
			   [[4, 5, 6],
				[7, 8, 9]]])
		>>> np.stack((a, b), axis=1).shape
		(2, 2, 3)
		>>> np.stack((a, b), axis=1)
		array([[[1, 2, 3],
				[4, 5, 6]],
			   [[2, 3, 4],
				[7, 8, 9]]])
		>>> np.stack((a, b), axis=2).shape
		(2, 3, 2)
		>>> np.stack((a, b), axis=2)
		array([[[1, 4],
				[2, 5],
				[3, 6]],
			   [[2, 7],
				[3, 8],
				[4, 9]]])
26.numpy.prod
	1.numpy.prod(a, axis=None, dtype=None, out=None, keepdims=<no value>, initial=<no value>, where=<no value>) 
	  返回给定轴上数组元素的乘积。
	2.参数:
		a:array_like 输入数据。
		axis=None:无或整数或整数元组,可选。
			  用于执行产品的一个或多个轴。默认值axis = None将计算输入数组中所有元素的乘积。如果轴为负,则从最后一个到第一个轴计数。
 			  如果axis是int的元组,那么将在元组中指定的所有轴上执行乘积运算,而不是像以前那样是单个轴或所有轴。
		dtype=None:可选。返回数组的类型,以及与元素相乘的累加器的类型。
			   默认情况下使用的数据类型是,除非a的整数数据类型精度低于默认平台整数。
			   在这种情况下,如果a有符号,则使用平台整数;如果a无符号,则使用与平台整数精度相同的无符号整数。
		out=None:ndarray,可选
			 放置结果的替代输出数组。它必须具有与预期输出相同的形状,但是如有必要,将强制转换输出值的类型。
		keepdims=<no value>:bool布尔,可选
				   如果将其设置为True,则缩小的轴将保留为尺寸1的尺寸。使用此选项,结果将针对输入数组正确广播。
				   如果传递了默认值,则keepdims不会传递给的prod子类的方法 ndarray,但是任何非默认值都将传递。
				   如果子类的方法未实现keepdims,则将引发任何异常。
		initial=<no value>:scalar标量,可选。此产品的起始值。 
		where=<no value>: bool布尔的array_like,可选。产品中要包含的元素。
	3.返回值:	
		product_along_axis:ndarray,请参见dtype上面的参数。
		形状为a但删除指定轴的数组。返回对out的引用(如果已指定)。

	4.例子:
		使用整数类型时,算术是模块化的,并且在溢出时不会引发错误。这意味着,在32位平台上:
		>>> x = np.array([536870910, 536870910, 536870910, 536870910])
		>>> np.prod(x)
		16 #可能有所不同
 		
		空数组的乘积是中性元素1
		>>> np.prod([]) 
		1.0

		默认情况下,计算所有元素的乘积:
		>>> np.prod([1.,2.])
		2.0

		即使输入数组是二维的:
		>>> np.prod([[1.,2.],[3.,4.]])
		24.0

		但是我们也可以指定要乘以的轴:
		>>> np.prod([[1.,2.],[3.,4.]], axis=1)
		array([  2.,  12.])

		或选择要包括的特定元素:
		>>> np.prod([1., np.nan, 3.], where=[True, False, True])
		3.0

		如果x的类型是无符号的,则输出类型是无符号的平台整数:
		>>> x = np.array([1, 2, 3], dtype=np.uint8)
		>>> np.prod(x).dtype == np.uint
		True

		如果x为带符号整数类型,则输出类型为默认平台整数:
		>>> x = np.array([1, 2, 3], dtype=np.int8)
		>>> np.prod(x).dtype == int
		True

		您还可以使用除以下以外的其他值来启动产品:
		>>> np.prod([1, 2], initial=5)
		10

27.numpy.shape
	1.numpy.shape(a) 返回数组的形状。
	2.参数 a:array_like 输入数组。
	3.返回值 shape:ints整数形元组tuple。形状元组的元素给出了相应数组维度的长度。
	4.例子
		>>> import numpy as np
		>>> np.eye(3)
		array([[1., 0., 0.],
		       [0., 1., 0.],
		       [0., 0., 1.]])
		>>> np.shape(np.eye(3))
		(3, 3)
		>>> np.shape([[1, 2]])
		(1, 2)
		>>> np.shape([0])
		(1,)
		>>> np.shape(0)
		()
 
		>>> a = np.array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')])
		>>> np.shape(a)
		(2,)
		>>> a.shape
		(2,)    

28.numpy.linspace
	1.numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0)
	  返回指定间隔内的等间隔数字。返回在间隔[ start,stop ] 内计算的num个均匀间隔的样本。间隔的端点可以选择排除。  
	2.参数:
		start:array_like。返回序列的起始点/初始值。
		stop:array_like。序列的结束点。除非endpoint被设置为False,否则stop为序列的终点值。
		      当endpoint=False,返回序列包含num+1个均匀间隔样本的最后一个样本以外的所有样本。
		      [start, stop]均匀分割为包含num+1个样本的序列,最后一个样本即为endpoint,舍弃不取,即为返回的序列,其中样本总数仍然为num),
		      故stop是被排除在外的。值得注意的是,当endpoint=False时,返回序列的步长会发生变化。
		num:int,可选。产生的样本总数。默认值为50。必须为非负值。
		endpoint:bool,可选。若为True,则stop为最后一个样本。否则,返回序列不包含stop。默认值为True。
		retstep:bool,可选。若为True,返回(samples, step),step为样本间的步长。
		dtype:dtype,可选。返回序列的数据类型。如果dtype未给定,那么从其他输入参数推断其类型。
		axis:int,可选。结果中的轴用于存储样本。仅当start或stop类似于数组时才相关。默认情况下为0,样本将沿着在开始处插入的新轴。使用-1获得一个轴的末端。
	3.返回值:
		samples:ndarray。包含num个等间隔样本的闭区间[start, stop]或者左闭右开区间[start, stop)(区间右端的开闭基于endpoint为True或者False)。
		step:float,可选。仅当retstep设置为True时返回,样本的步长。
	4.例子:
		>>> np.linspace(2.0, 3.0, num=5)
		array([2.  , 2.25, 2.5 , 2.75, 3.  ])
		>>> np.linspace(2.0, 3.0, num=5, endpoint=False)
		array([2. ,  2.2,  2.4,  2.6,  2.8])
		>>> np.linspace(2.0, 3.0, num=5, retstep=True)
		(array([2.  ,  2.25,  2.5 ,  2.75,  3.  ]), 0.25)

		>>> N = 8
		>>> y = np.zeros(N)
		>>> x1 = np.linspace(0, 10, N, endpoint=True)
		>>> x2 = np.linspace(0, 10, N, endpoint=False)
		>>> plt.plot(x1, y, 'o')
		[<matplotlib.lines.Line2D object at 0x...>]
		>>> plt.plot(x2, y + 0.5, 'o')
		[<matplotlib.lines.Line2D object at 0x...>]
		>>> plt.ylim([-0.5, 1])
		(-0.5, 1)
		>>> plt.show()

29.numpy.tile
	1.numpy.tile(A, reps) 通过reps次数地重复A来构造一个数组。
	  如果reps有长度d,则结果的尺寸为max(d, A.ndim)。
	  如果为A.ndim < d,则通过添加新轴将A提升为d维。因此,将形状(3,)array 提升为(1,3)以进行2-D复制,或者将形状(1, 1, 3) 提升为3-D复制。
	  如果这不是所需的行为,请在调用此函数之前手动将A提升为d维。 
 	  如果为A.ndim > d,则通过在其前面加1来将代表提升为A .ndim。因此对于A的形状(2,3,4,5)的,一个代表的(2,2)被视为(1,1,2,2)。
	  注意:尽管tile可以用于广播,但强烈建议使用numpy的广播操作和功能。
	2.参数:
		A:array_like。输入数组。
		reps:array_like。A沿每个轴的重复次数
	3.返回值
		c:ndarray。平铺输出数组。
	4.例子:
		>>> a = np.array([0, 1, 2])
		>>> np.tile(a, 2)
		array([0, 1, 2, 0, 1, 2])
		>>> np.tile(a, (2, 2))
		array([[0, 1, 2, 0, 1, 2],
		       [0, 1, 2, 0, 1, 2]])
		>>> np.tile(a, (2, 1, 2))
		array([[[0, 1, 2, 0, 1, 2]],
		       [[0, 1, 2, 0, 1, 2]]])
		>>> b = np.array([[1, 2], [3, 4]])
		>>> np.tile(b, 2)
		array([[1, 2, 1, 2],
		       [3, 4, 3, 4]])
		>>> np.tile(b, (2, 1))
		array([[1, 2],
		       [3, 4],
		       [1, 2],
		       [3, 4]])
		>>> c = np.array([1,2,3,4])
		>>> np.tile(c,(4,1))
		array([[1, 2, 3, 4],
		       [1, 2, 3, 4],
		       [1, 2, 3, 4],
		       [1, 2, 3, 4]])

30.np.argsort
		对数组中的元素值按照从小到大(升序)或从大到小(降序)的方式返回其元素索引值
		
		>>> import numpy as np
		>>> x = np.array([3,1,2])
		#对数组中的元素值按照从小到大(升序)的方式返回其元素索引值 
		>>> np.argsort(x) 
		array([1, 2, 0], dtype=int64))
		#对数组中的元素值按照从大到小(降序)的方式返回其元素索引值 
		>>> np.argsort(-x) 
		array([0, 2, 1], dtype=int64)
		#根据从小到大(升序)方式返回的元素索引值对数组进行从小到大(升序)排序
		>>> x[np.argsort(x)]
		array([1, 2, 3])
		>>> x[np.argsort(-x)]
		array([3, 2, 1])
		>>> x = np.array([2,1,3,5,4])
		#翻转数组中元素的排列顺序,即从尾到头重新排列数组元素
		>>> x[::-1]
		array([4, 5, 3, 1, 2])
		#按列排序 array([[0, 0],[1, 1]], dtype=int64)
		np.argsort([[3,1],[4,2]],axis=0) 
		#按行排序 array([[1, 0], [1, 0]], dtype=int64)
		np.argsort([[3,1],[4,2]],axis=1) 

 


ndarray中指定位置的元素的获取和赋值

>>> import numpy as np
>>> results = np.zeros((3, 4))
>>> results
array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])
>>> results[1,[1,2]] = 1
>>> results
array([[0., 0., 0., 0.],
       [0., 1., 1., 0.],
       [0., 0., 0., 0.]])
>>> results[1,[1,2]]
array([1., 1.])

numpy.expand_dims

a为三维数组:[[[1,2,3],[4,5,6]]]
numpy.expand_dims(a, axis=0):表示把三维数组当作一个元素,在三维数组的外面再加一个维度
numpy.expand_dims(a, axis=1):表示在三维数组中 把第一维里面的每个元素增加一个维度
numpy.expand_dims(a, axis=2):表示在三维数组中 把第二维里面的每个元素增加一个维度
numpy.expand_dims(a, axis=3):表示在三维数组中 把第三维里面的每个元素增加一个维度
注意:三维数组的维度数只有3,因此不能使用axis=4这样的指向不存在的维度。


numpy.argmax

numpy.argmax:返回指定轴/指定行列上的最大值的索引值
a=[[1,2,3],[2,1,4],[3,6,1]]
numpy.argmax(a, axis=0):表示获取行上元素最大值的索引值
numpy.argmax(a, axis=1):表示获取列上元素最大值的索引值


numpy.ndarray.flatten

ndarray.flatten(order='C')
	1.返回折叠成一维的数组副本,可把多维数组压缩/降维为仅有一维的数组
	2.参数:可选顺序选项分别有{'C','F','A','K'}
		默认值为“C”。“C”表示按行展平/降维。
		“F”表示按列展平/降维。
		“A”表示如果输入的array在内存中是连续的,则按列展平/降维,否则按行展平/降维。
		“k”表示按元素在内存中出现的顺序将输入的array压平。
	3.返回:ndarray值的类型,输入数组的副本,被展平/降维/压缩为一个维度
	4.flatten是numpy.ndarray.flatten的一个函数,即返回一个一维数组。
	  flatten只能适用于numpy对象,即array或者mat,普通的list列表不适用。
 	  a.flatten():a是个数组,a.flatten()就是把a降到一维,默认是按行的方向降维。

1.flatten()可以把比如二维array/三维array/任意多维的array都仅压缩为只有一维的array,而普通的list列表则不适用flatten()
	>>> import numpy as np
	>>> a = np.array([[1,2], [3,4]])
	>>> a
	array([[1, 2],
                [3, 4]])
	>>> a.shape
	(2, 2)
	>>> a = a.flatten()
	>>> a
	array([1, 2, 3, 4])
	>>> a.shape
	(4,)
	>>> a = np.array([[[1,2],[3,4]],[[5,6],[7,8]]])
	>>> a
	array([[[1, 2],
        	        [3, 4]],
        	       [[5, 6],
        	        [7, 8]]])
	>>> a.shape
	(2, 2, 2)
	>>> a = a.flatten()
	>>> a
	array([1, 2, 3, 4, 5, 6, 7, 8])
	>>> a.shape
	(8,)
	>>> a = np.array([[1,2], [3,4]])
	>>> a = a.flatten('F')
	>>> a
	array([1, 3, 2, 4])
	>>> from numpy import *
	>>> a=array([[1,2],[3,4],[5,6]])
	>>> a
	array([[1, 2],
    	       [3, 4],
    	       [5, 6]])
	>>> a.flatten() #默认按行的方向降维
	array([1, 2, 3, 4, 5, 6])
	>>> a.flatten('F') #按列降维
	array([1, 3, 5, 2, 4, 6]) 
	>>> a.flatten('A') #按行降维
	array([1, 2, 3, 4, 5, 6])

2.flatten()把 二维的 matrix矩阵 中的第二维中的所有元素都压缩到一起仅作为一维,但整个matrix矩阵仍保持为二维的形状。
  矩阵.A 和 矩阵.getA() 相同效果,都为把矩阵转换为array,并且array形状和矩阵形状依旧一致。
  注意:matrix矩阵只能定义为二维,即使定义为一维 mat([1,2]) 也会自动转换为二维的 matrix([[1, 2]]),也无法定义为更多维,否则报错matrix must be 2-dimensional。
	>>> from numpy import *
	>>> a=mat([[1,2,3],[4,5,6]])
	>>> a
	matrix([[1, 2, 3],
        	        [4, 5, 6]])
	>>> a.shape
	(2, 3)
	>>> a = a.flatten()
	>>> a
	matrix([[1, 2, 3, 4, 5, 6]])
	>>> a.shape
	(1, 6)
 	>>> a=mat([[1,2,3],[4,5,6]])
 	>>> a=a.A #等同于 a=a.getA()
	>>> a
	array([[1, 2, 3],
       	       [4, 5, 6]])
 	 
3.mxnet中使用concat()、flatten()、transpose()
	>>> from mxnet import nd
	>>> a = nd.zeros((2, 3, 4, 5)) #格式为(批量⼤小,通道数,⾼,宽)
	>>> a.shape
	(2, 3, 4, 5)
	>>> b = nd.zeros((2, 6, 7, 8)) #格式为(批量⼤小,通道数,⾼,宽)
	>>> b.shape
	(2, 6, 7, 8)
	#可以看到,除了a和b两者之间除了批量⼤小相同之外,其他维度⼤小均不⼀样。
	#可以将a和b两者都变形成统⼀的格式,比如flatten压缩/降维,flatten()可以把“批量⼤小,通道数,⾼,宽”压缩为“批量⼤小,通道数 x ⾼ x 宽”,
	#然后再进行两者concat连结,从而让后续计算更简单。
	>>> a = a.transpose((0, 2, 3, 1))
	>>> b = b.transpose((0, 2, 3, 1))
	>>> a.shape
	(2, 4, 5, 3)
	>>> b.shape
	(2, 7, 8, 6)
	>>> a = a.flatten() #把“批量⼤小,通道数,⾼,宽”压缩为“批量⼤小,通道数 x ⾼ x 宽” 
	>>> b = b.flatten()
	>>> a.shape
	(2, 60)
	>>> b.shape
	(2, 336)
	#dim=0:表示按行方向连结。dim=1:表示按列方向连结。
	>>> c = nd.concat(*[a,b], dim=1)
	>>> c.shape
	(2, 396)

	>>> outputs = nd.zeros((2, 3, 4))
	>>> outputs.shape
	(2, 3, 4)
	>>> outputs[0].shape
	(3, 4)
	>>> outputs[-1].shape
	(3, 4)
	#默认dim=1:表示按列方向连结
	>>> encoding = nd.concat(outputs[0], outputs[-1])
	>>> encoding.shape
	(3, 8)
	#dim=1:表示按列方向连结
	>>> encoding = nd.concat(outputs[0], outputs[-1], dim=1)
	>>> encoding.shape
	(3, 8)
	#dim=0:表示按行方向连结。
	>>> encoding = nd.concat(outputs[0], outputs[-1], dim=0)
	>>> encoding.shape
	(6, 4)

numpy普通数组/numpy图像数组 中冒号的使用

1.numpy普通数组中冒号的使用
	1.数组中冒号有三个用法:
		1.默认选择全部行或全部列;
		2.[开始行:结束行]:指定范围,左开右闭,包含开始行/开始列,但不包含结束行/结束列。
		3.[start:end:step] start:起始位置 end:结束位置 step:步长

	2.第一种用法 例子:默认选择全部行或全部列
		import numpy
		arr = numpy.arange(6).reshape(2,3) #2x3维度的二维数组
		arr
		Out[55]: array([[0, 1, 2],
			       [3, 4, 5]])
			   
		arr[:,0] #取所有行中的第一列
		Out[54]: array([0, 3])

		arr[:,1] #取所有行中的第二列
		Out[56]: array([1, 4])

		arr[0,:] #取第一行中的所有列
		Out[57]: array([0, 1, 2])

		arr[1,:] #取第二行中的所有列
		Out[58]: array([3, 4, 5])

		import numpy
		arr = numpy.arange(18).reshape(2,3,3)
		arr
		Out[60]: array([[[ 0,  1,  2],
		                 [ 3,  4,  5],
		                 [ 6,  7,  8]],
		                [[ 9, 10, 11],
		                 [12, 13, 14],
		                 [15, 16, 17]]])
				
		arr[0,:,:] #取三维数组中一级索引为0的整个二维数组
		Out[61]:array([[0, 1, 2],
		               [3, 4, 5],
		               [6, 7, 8]])

		arr[1,:,:] #取三维数组中一级索引为1的整个二维数组
		Out[62]:array([[ 9, 10, 11],
			      [12, 13, 14],
			      [15, 16, 17]])
		 
		arr[:,:,0] #取三维数组中任何三级索引为0的元素,为原高度X原宽度的二维数组
		Out[63]:array([[ 0,  3,  6],
			      [ 9, 12, 15]])

		arr[:,:,1] #取三维数组中任何三级索引为1的元素,为原高度X原宽度的二维数组
		Out[64]:array([[ 1,  4,  7],
			      [10, 13, 16]])

	3.第二种用法 例子:[开始行:结束行]:指定范围,左开右闭,包含开始行/开始列,但不包含结束行/结束列
		import numpy
		arr = numpy.arange(12).reshape(3,4) # 3x4维度的二维数组
		arr
		Out[68]: array([[ 0,  1,  2,  3],
			       [ 4,  5,  6,  7],
			       [ 8,  9, 10, 11]])
 
		arr[:,0:1] #取全部行中的第一列,但不包含第二列
		Out[69]: array([[0],
			       [4],
			       [8]])

		arr[:,0:2] #取全部行中的第一到第二列,但不包含第三列
		Out[70]:array([[0, 1],
			      [4, 5],
			      [8, 9]])

		arr[1:2,:] #取第二行中的所有列,但不包含第三行
		Out[71]: array([[4, 5, 6, 7]])

		arr[1:3,:] #取第二到第三行中的所有列,但不包含第三行
		Out[72]:array([[ 4,  5,  6,  7],
			      [ 8,  9, 10, 11]])

	4.第三种用法 例子:[start:end:step] start:起始位置 end:结束位置 step:步长
		>>> range(100)[20:30:2]
		[20, 22, 24, 26, 28]

2.numpy图像数组中冒号的使用
	1.一个64x64的小图,实际上它的数据量是64x64x3,因为图像中的每个像素都有3个RGB颜色通道。
	2.opencv的颜色通道顺序为[B,G,R],而matplotlib的颜色通道顺序为[R,G,B],因此如果使用opencv读取图片后,要使用matplotlib显示图片的话,
  	  首先需要把R和B的位置调换一下,把默认的(0,1,2)变换成(2,1,0),即img = img[:,:,(2,1,0)],如果不先调换R和B的位置就直接显示的话,会出现色差。
	3.遍历和获取三维numpy图像数组的每个值
		print(image.shape)  	#获取图像的形状大小:高度X宽度X通道数
		height=image.shape[0] 	#图像的第一维度:高度
		width=image.shape[1] 	#图像的第二维度:宽度
		channels=image.shape[2] 	#图像的第三维度:通道数
		print("height : %s , width :%s , channels: %s"%(height,width,channels)) #比如一个250X250的彩图的通道数为3
		for row in range(height):
			for col in range(width):
				for c in range(channels):
					pv=image[row,col,c] #一个三维数组,获取每个维度的值
	4.语义分割和数据集 一章节中


利用numpy、PIL、scipy.misc、matplotlib、opencv 进行读取和保存图片

Matplotlib 中文文档:https://www.matplotlib.org.cn/

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) # 保存图片

6.opencv的颜色通道顺序为[B,G,R],而matplotlib的颜色通道顺序为[R,G,B],因此如果使用opencv读取图片后,要使用matplotlib显示图片的话,
  首先需要把R和B的位置调换一下,把默认的(0,1,2)变换成(2,1,0),即img = img[:,:,(2,1,0)],如果不先调换R和B的位置就直接显示的话,会出现色差。
	图片原图1.png:

	import cv2  # 利用opencv读取图像
	import numpy as np
	# 利用matplotlib显示图像
	import matplotlib.pyplot as plt 

	#使用opencv读取图片后,使用matplotlib显示图片,注意还要把默认的(0,1,2)变换成(2,1,0)
	img = cv2.imread("./1.png") #读取图像
	# 显示图像
	plt.imshow(img)
	plt.axis('off')
	plt.show()

	img = img[:,:,(2,1,0)]
	# 显示图像
	plt.imshow(img)
	plt.axis('off')
	plt.show()

7.把彩图转换为灰度图像
	1.图像灰度化算法Gray = 0.299 * R + 0.587 * G + 0.114 * B
	2.读取的原图同上
		import cv2  # 利用opencv读取图像
		import numpy as np
		# 利用matplotlib显示图像
		import matplotlib.pyplot as plt 

		img = cv2.imread("./1.png") #读取图像
		r,g,b = [img[:,:,i] for i in range(3)]
		#图像灰度化算法Gray = 0.299 * R + 0.587 * G + 0.114 * B
		img_gray = r*0.299+g*0.587+b*0.114
		#需要显示为灰度图像的话,必须指定cmap的色彩参数为cmap="gray",参阅Colormap参考:Matplotlib附带的色彩映射参考
		#cmap="gray":将图像显示为黑底白字。cmap="gray_r":将图像显示为白底黑字。
		plt.imshow(img_gray,cmap="gray")
		plt.axis('off')
		plt.show()

		#需要显示为灰度图像的话,必须指定cmap的色彩参数为cmap="gray",参阅Colormap参考:Matplotlib附带的色彩映射参考
		#cmap="gray":将图像显示为黑底白字。cmap="gray_r":将图像显示为白底黑字。
		plt.imshow(img_gray,cmap="gray_r")
		plt.axis('off')
		plt.show()

	3.Matplotlib附带的色彩映射参考
		1.Matplotlib 中文文档:https://www.matplotlib.org.cn/
	  	  Matplotlib附带的色彩映射参考:https://www.matplotlib.org.cn/gallery/color/colormap_reference.html#Colormap%E5%8F%82%E8%80%83
		  Matplotlib中选择Colormaps:https://matplotlib.org/tutorials/colors/colormaps.html
		
		2.Colormap参考:Matplotlib附带的色彩映射参考
			1.通过将 _r 附加到名称(例如,viridis_r),可以获得每个这些颜色映射的反转版本。
 			2.请参阅在Matplotlib中选择Colormaps(https://matplotlib.org/tutorials/colors/colormaps.html)以深入讨论色彩映射,
			  包括colorblind-friendlyliness。
			3.下载python源码: colormap_reference.py(https://matplotlib.org/_downloads/colormap_reference.py)
			  下载Jupyter notebook: colormap_reference.ipynb(https://matplotlib.org/_downloads/colormap_reference.ipynb)
			4.python源码
				"""
				==================
				Colormap reference
				==================

				Reference for colormaps included with Matplotlib.

				A reversed version of each of these colormaps is available by appending
				``_r`` to the name, e.g., ``viridis_r``.

				See :doc:`/tutorials/colors/colormaps` for an in-depth discussion about
				colormaps, including colorblind-friendliness.
				"""

				import numpy as np
				import matplotlib.pyplot as plt


				cmaps = [('Perceptually Uniform Sequential', [
							'viridis', 'plasma', 'inferno', 'magma', 'cividis']),
						 ('Sequential', [
							'Greys', 'Purples', 'Blues', 'Greens', 'Oranges', 'Reds',
							'YlOrBr', 'YlOrRd', 'OrRd', 'PuRd', 'RdPu', 'BuPu',
							'GnBu', 'PuBu', 'YlGnBu', 'PuBuGn', 'BuGn', 'YlGn']),
						 ('Sequential (2)', [
							'binary', 'gist_yarg', 'gist_gray', 'gray', 'bone', 'pink',
							'spring', 'summer', 'autumn', 'winter', 'cool', 'Wistia',
							'hot', 'afmhot', 'gist_heat', 'copper']),
						 ('Diverging', [
							'PiYG', 'PRGn', 'BrBG', 'PuOr', 'RdGy', 'RdBu',
							'RdYlBu', 'RdYlGn', 'Spectral', 'coolwarm', 'bwr', 'seismic']),
						 ('Cyclic', ['twilight', 'twilight_shifted', 'hsv']),
						 ('Qualitative', [
							'Pastel1', 'Pastel2', 'Paired', 'Accent',
							'Dark2', 'Set1', 'Set2', 'Set3',
							'tab10', 'tab20', 'tab20b', 'tab20c']),
						 ('Miscellaneous', [
							'flag', 'prism', 'ocean', 'gist_earth', 'terrain', 'gist_stern',
							'gnuplot', 'gnuplot2', 'CMRmap', 'cubehelix', 'brg',
							'gist_rainbow', 'rainbow', 'jet', 'nipy_spectral', 'gist_ncar'])]


				gradient = np.linspace(0, 1, 256)
				gradient = np.vstack((gradient, gradient))


				def plot_color_gradients(cmap_category, cmap_list):
					# Create figure and adjust figure height to number of colormaps
					nrows = len(cmap_list)
					figh = 0.35 + 0.15 + (nrows + (nrows-1)*0.1)*0.22
					fig, axes = plt.subplots(nrows=nrows, figsize=(6.4, figh))
					fig.subplots_adjust(top=1-.35/figh, bottom=.15/figh, left=0.2, right=0.99)

					axes[0].set_title(cmap_category + ' colormaps', fontsize=14)

					for ax, name in zip(axes, cmap_list):
						ax.imshow(gradient, aspect='auto', cmap=plt.get_cmap(name))
						ax.text(-.01, .5, name, va='center', ha='right', fontsize=10,
								transform=ax.transAxes)

					# Turn off *all* ticks & spines, not just the ones with colormaps.
					for ax in axes:
						ax.set_axis_off()


				for cmap_category, cmap_list in cmaps:
					plot_color_gradients(cmap_category, cmap_list)

				plt.show()

				#############################################################################
				#
				# ------------
				#
				# References
				# """"""""""
				#
				# The use of the following functions, methods, classes and modules is shown
				# in this example:

				import matplotlib
				matplotlib.colors
				matplotlib.axes.Axes.imshow
				matplotlib.figure.Figure.text
				matplotlib.axes.Axes.set_axis_off


矩阵乘法之内积、格拉姆矩阵(Gram matrix)、小批量矩阵乘法

1.内积
	内积指的是两个矩阵(向量)的乘积和,相当于卷积层中的卷积核和输入矩阵(向量)的两个矩阵相乘的乘积和。
	比如有两个向量:
		A矩阵:(x1,x2,...,xn)。B矩阵:(y1,y2,...,yn)。
		那么A矩阵和B矩阵的内积为(两个矩阵(向量)的乘积和):x1*y1+x2*y2+...+xn*yn

2.矩阵X(向量X)的格拉姆矩阵(Gram matrix)XX⊤∈Ra×a中的i行j列的元素值Xij实际为矩阵Xi(向量Xi)与矩阵Xj(向量Xj)的内积
	1.X⊤表示矩阵X(向量X)的转置
	2.矩阵X(向量X)的格拉姆矩阵(Gram matrix)的表达式为XX⊤∈Ra×a。
		1.XX⊤表示矩阵X(向量X)和转置后的矩阵X(向量X)进行两个矩阵(向量)之间的相乘,求内积(乘积和)
		2.矩阵Y为转置后的矩阵X,其中矩阵X的行a等于矩阵Y的列a,矩阵X的列b等于矩阵Y的行b。
		  那么矩阵X*矩阵Y得出的结果矩阵的shape计算规则:“作为被乘数的矩阵X的”行值变为结果矩阵的行值,“作为乘数的矩阵Y的”列值变为结果矩阵的列值。
		  即结果矩阵的shape为(作为被乘数的矩阵X的行a,作为乘数的矩阵Y的列a)。
		  乘法里(被乘数*乘数),前面的是被乘数,后面是乘数。
		  除法里(被除数/除数),前面的是被除数,后面是除数。
		3.Ra×a表示此处的矩阵X(向量X)的行a*列b通过转置操作后变成列b*行a,那么矩阵X(向量X)和转置后的矩阵X(向量X)进行相乘的话,
		  结果矩阵的表达式写为∈R行a×行a。

3.矩阵X(向量X)的格拉姆矩阵的示例
	矩阵X的行a等于矩阵Y的列a,矩阵X的列b等于矩阵Y的行b,矩阵X乘以矩阵Y得出的结果矩阵shape为(矩阵X的行a,矩阵Y的列a)。
	结果矩阵shape的计算规是行值必须为“作为被乘数的矩阵X的”行值,而列值必须为“作为乘数的矩阵Y的”列值。
	乘法里(被乘数*乘数),前面的是被乘数,后面是乘数。
	除法里(被除数/除数),前面的是被除数,后面是除数。
		1.例子1
			>>> import numpy as nd
			>>> x = nd.arange(12)
			>>> X1 = x.reshape((3, 4))
			>>> X1
			array([[ 0,  1,  2,  3],
				   [ 4,  5,  6,  7],
				   [ 8,  9, 10, 11]])
			>>> X1.T
			array([[ 0,  4,  8],
				   [ 1,  5,  9],
				   [ 2,  6, 10],
				   [ 3,  7, 11]])
			>>> X1.shape
			(3, 4)
			>>> X1.T.shape
			(4, 3)
			>>> Y = nd.dot(X1, X1.T)
			>>> Y
			array([[ 14,  38,  62],
				   [ 38, 126, 214],
				   [ 62, 214, 366]])
			>>> Y.shape
			(3, 3)

		2.例子2
			>>> import numpy as nd
			>>> x = nd.arange(12)
			>>> X1 = x.reshape((4, 3))
			>>> X1
			array([[ 0,  1,  2],
				   [ 3,  4,  5],
				   [ 6,  7,  8],
				   [ 9, 10, 11]])
			>>> X1.T
			array([[ 0,  3,  6,  9],
				   [ 1,  4,  7, 10],
				   [ 2,  5,  8, 11]])
			>>> X1.shape
			(4, 3)
			>>> X1.T.shape
			(3, 4)
			>>> Y = nd.dot(X1, X1.T)
			>>> Y
			array([[  5,  14,  23,  32],
				   [ 14,  50,  86, 122],
				   [ 23,  86, 149, 212],
				   [ 32, 122, 212, 302]])
			>>> Y.shape
			(4, 4)

4.点积运算
	点积运算,也叫张量积(tensor product,不要与逐元素的乘积弄混),是最常见也最有用的张量运算。
  	与逐元素的运算不同,它将输入张量的元素合并在一起。在 Numpy、Keras、Theano 和 TensorFlow 中,都是用 * 实现逐元素乘积。
  	TensorFlow 中的点积使用了不同的语法,但在 Numpy 和 Keras 中,都是用标准的 dot 运算符来实现点积。
  		import numpy as np
  		z = np.dot(x, y)
  	数学符号中的点(.)表示点积运算。
  		z=x.y

	注意,如果两个张量中有一个的 ndim 大于 1,那么 dot 运算就不再是对称的,也就是说,dot(x, y) 不等于 dot(y, x)。
	当然,点积可以推广到具有任意个轴的张量。最常见的应用可能就是两个矩阵之间的点积。
	对于两个矩阵 x 和 y,当且仅当 x.shape[1] == y.shape[0] 时,你才可以对它们做点积(dot(x, y))。
	得到的结果是一个形状为 (x.shape[0], y.shape[1]) 的矩阵,其元素为 x的行与 y 的列之间的点积。
	其简单实现如下。

1.gram(X)函数传入的矩阵X的shape为样本数(批量大小)*通道数*高*宽
2.num_channels = X.shape[1] 表示num_channels为通道数
  n = X.size // X.shape[1] 表示n为样本数(批量大小)*通道数*高*宽 / 通道数,因为样本数(批量大小)为1,因此n为高*宽
3.X = X.reshape((num_channels, n)) 表示矩阵X的shape变换为(通道数,高*宽),通道数为行数,高*宽为列数
4.nd.dot(X, X.T) / (num_channels * n) 
	1.其中的 nd.dot(X, X.T)表示矩阵X与转置后的矩阵X相乘,计算乘积和(内积),计算得出的结果矩阵的shape为(通道数,通道数),通道数为行数,通道数为列数。
	2.矩阵X*转置后的矩阵X得出的结果矩阵的shape计算规则:“作为被乘数的矩阵X的”行值变为结果矩阵的行值,“作为乘数的转置后的矩阵X的”列值变为结果矩阵的列值。
	3.num_channels * n 表示 矩阵X中元素的个数,即通道数*高*宽


broadcast_axis

>>> from mxnet import nd
#时间步数seq_len, 批量⼤小batch_size, 隐藏单元个数num_hiddens
>>> seq_len, batch_size, num_hiddens = 10, 4, 8
#键项和值项均为编码器在所有时间步的隐藏状态enc_states,形状为(时间步数, 批量⼤小, 隐藏单元个数)
>>> enc_states = nd.zeros((seq_len, batch_size, num_hiddens))
#解码器在上⼀时间步的隐藏状态dec_state,形状为(批量⼤小, 隐藏单元个数)
>>> dec_state = nd.zeros((batch_size, num_hiddens))
#形状为(时间步数, 批量⼤小, 隐藏单元个数)
>>> enc_states.shape
(10, 4, 8) 
#形状为(批量⼤小, 隐藏单元个数)
>>> dec_state.shape
(4, 8) 
#给形状为(批量⼤小, 隐藏单元个数)的解码器在上⼀时间步的隐藏状态dec_state中 增加多第一维,变成“和编码器在所有时间步的隐藏状态enc_states的”形状相同
>>> dec_state.expand_dims(0).shape
(1, 4, 8)
#编码器在所有时间步的隐藏状态enc_states的第一维
>>> enc_states.shape[0]
10
#将解码器在上⼀时间步的隐藏状态dec_state ⼴播到“和编码器在所有时间步的隐藏状态enc_states的”形状相同
#axis=0 表示在隐藏状态dec_state第一维(axis轴为0)上进行广播大小
#目的把隐藏状态dec_state第一维为1的大小值拓展到“和隐藏状态enc_states”形状相同第一维为10的大小值相同
>>> dec_states = nd.broadcast_axis(dec_state.expand_dims(0), axis=0, size=enc_states.shape[0])
>>> dec_states.shape
(10, 4, 8)
#解码的隐藏状态器dec_states与编码器在所有时间步上隐藏状态enc_states的一一连结
#dim=2 表示在第三维度上连结,enc_states形状(10, 4, 8)和dec_statesenc_states形状(10, 4, 8)两者在第三维度上连结为(10, 4, 16)
>>> enc_and_dec_states = nd.concat(enc_states, dec_states, dim=2)
>>> enc_and_dec_states.shape
(10, 4, 16)

mxnet中全连接层Dense的flatten选项和mxnet中flatten()的区别

>>> from mxnet import nd
>>> a = nd.zeros((2, 3, 4, 5)) #格式为(批量⼤小,通道数,⾼,宽)
>>> a.shape
(2, 3, 4, 5)
>>> b = nd.zeros((2, 6, 7, 8)) #格式为(批量⼤小,通道数,⾼,宽)
>>> b.shape
#当输入的维度⼤于2时,默认情况下,Dense实例会将除了第⼀维以外的维度均视作需要仿射变换的特征维,并将输入自动转成行X列的二维矩阵,第⼀维以外的维度都相乘作为列。
#把“批量⼤小,通道数,⾼,宽”压缩为“批量⼤小,通道数X⾼X宽的乘积值” 
>>> a = a.flatten() 
>>> b = b.flatten()
>>> a.shape
(2, 60)
>>> b.shape
(2, 336)

#Dense实例的flatten选项。
#当输入的维度⼤于2时,默认情况下,Dense实例会将除了第⼀维(样本维)以外的维度均视作需要仿射变换的特征维,并将输入自动转成行为样本数、列为特征值的二维矩阵。
#计算后,输出矩阵的形状为(样本数, 输出个数)。如果我们希望全连接层只对输⼊的最后⼀维做仿射变换,而保持其他维度上的形状不变,便需要将Dense实例的flatten选项设为False。
#在下⾯例⼦中,全连接层只对输⼊的最后⼀维做仿射变换,因此输出形状中只有最后⼀维变为全连接层的输出个数2。
>>> from mxnet.gluon import nn 
>>> from mxnet import nd
>>> dense = nn.Dense(2, flatten=False)
>>> dense.initialize()
#输出形状中只有最后⼀维变为全连接层的输出个数2 
>>> dense(nd.zeros((3, 5, 7))).shape
(3, 5, 2)
>>> dense = nn.Dense(2)
>>> dense.initialize()
#输出形状中除第一维保留之外,输入的其他维都被去除,然后第二维被替换为全连接层的输出个数2 
>>> dense(nd.zeros((3, 5, 7))).shape
(3, 2)

含注意力机制的解码器进行⽮量化计算

>>> from mxnet.gluon import nn 
>>> from mxnet import nd
#时间步数seq_len, 批量⼤小batch_size, 隐藏单元个数num_hiddens
>>> seq_len, batch_size, num_hiddens = 10, 4, 8
#键项和值项均为编码器在所有时间步的隐藏状态enc_states,形状为(时间步数, 批量⼤小, 隐藏单元个数)
>>> enc_states = nd.zeros((seq_len, batch_size, num_hiddens))
#解码器在上⼀时间步的隐藏状态dec_state,形状为(批量⼤小, 隐藏单元个数)
>>> dec_state = nd.zeros((batch_size, num_hiddens))
#形状为(时间步数, 批量⼤小, 隐藏单元个数)
>>> enc_states.shape
(10, 4, 8) 
#形状为(批量⼤小, 隐藏单元个数)
>>> dec_state.shape
(4, 8) 
#给形状为(批量⼤小, 隐藏单元个数)的解码器在上⼀时间步的隐藏状态dec_state中 增加多第一维,变成“和编码器在所有时间步的隐藏状态enc_states的”形状相同
>>> dec_state.expand_dims(0).shape
(1, 4, 8)
#编码器在所有时间步的隐藏状态enc_states的第一维
>>> enc_states.shape[0]
10
#将解码器在上⼀时间步的隐藏状态dec_state ⼴播到“和编码器在所有时间步的隐藏状态enc_states的”形状相同
#axis=0 表示在隐藏状态dec_state第一维(axis轴为0)上进行广播大小
#目的把隐藏状态dec_state第一维为1的大小值拓展到“和隐藏状态enc_states”形状相同第一维为10的大小值相同
>>> dec_states = nd.broadcast_axis(dec_state.expand_dims(0), axis=0, size=enc_states.shape[0])
>>> dec_states.shape
(10, 4, 8)
#解码的隐藏状态器dec_states与编码器在所有时间步上隐藏状态enc_states的一一连结
#dim=2 表示在第三维度上连结,enc_states形状(10, 4, 8)和dec_statesenc_states形状(10, 4, 8)两者在第三维度上连结为(10, 4, 16)
>>> enc_and_dec_states = nd.concat(enc_states, dec_states, dim=2)
>>> enc_and_dec_states.shape
(10, 4, 16)
 
#1.Dense实例的flatten选项。
#  当输入的维度⼤于2时,默认情况下,Dense实例会将除了第⼀维(样本维)以外的维度均视作需要仿射变换的特征维,并将输入自动转成行为样本数、列为特征值的二维矩阵。
#  计算后,输出矩阵的形状为(样本数, 输出个数)。如果我们希望全连接层只对输⼊的最后⼀维做仿射变换,而保持其他维度上的形状不变,便需要将Dense实例的flatten选项设为False。
#  在下⾯例⼦中,全连接层只对输⼊的最后⼀维做仿射变换,因此输出形状中只有最后⼀维变为全连接层的输出个数2。
#2.这⾥函数a有多种选择,如果两个输⼊向量⻓度相同,⼀个简单的选择是计算它们的内积a(s,h) = s⊤*h。
#  而最早提出注意⼒机制的论⽂则将输⼊连结后通过含单隐藏层的多层感知机变换:a(S, H) = v⊤*tanh(WsS+ WhH),其中v、Ws、Wh都是可以学习的模型参数。
#3.实现“注意⼒机制”⼀节中定义的函数a:将输⼊连结后通过含单隐藏层的多层感知机变换。
#  其中隐藏层的输⼊是解码器的隐藏状态与编码器在所有时间步上隐藏状态的⼀⼀连结,且使⽤tanh函数作为激活函数。
#  输出层的输出个数为1。两个Dense实例均不使⽤偏差use_bias=False,且设flatten=False。
#  其中函数a定义⾥向量v的⻓度是⼀个超参数,即attention_size。
>>> model = nn.Sequential()
>>> attention_size = 10
>>> model.add(nn.Dense(attention_size, activation='tanh', use_bias=False, flatten=False), nn.Dense(1, use_bias=False, flatten=False))
>>> model.initialize()

#做前向计算,输出形状为(时间步数, 批量大小, 1)
>>> e = model(enc_and_dec_states)
>>> e.shape #形状为(时间步数, 批量大小, 1)
(10, 4, 1)

#softmax(e, axis=0) 表示在时间步维度做softmax运算
>>> alpha = nd.softmax(e, axis=0) 
>>> alpha.shape
(10, 4, 1)

>>> e
[[[0.]
  [0.]
  [0.]
  [0.]]

 [[0.]
  [0.]
  [0.]
  [0.]]

 [[0.]
  [0.]
  [0.]
  [0.]]

 [[0.]
  [0.]
  [0.]
  [0.]]

 [[0.]
  [0.]
  [0.]
  [0.]]

 [[0.]
  [0.]
  [0.]
  [0.]]

 [[0.]
  [0.]
  [0.]
  [0.]]

 [[0.]
  [0.]
  [0.]
  [0.]]

 [[0.]
  [0.]
  [0.]
  [0.]]

 [[0.]
  [0.]
  [0.]
  [0.]]]
<NDArray 10x4x1 @cpu(0)>

>>> alpha
[[[0.1]
  [0.1]
  [0.1]
  [0.1]]

 [[0.1]
  [0.1]
  [0.1]
  [0.1]]

 [[0.1]
  [0.1]
  [0.1]
  [0.1]]

 [[0.1]
  [0.1]
  [0.1]
  [0.1]]

 [[0.1]
  [0.1]
  [0.1]
  [0.1]]

 [[0.1]
  [0.1]
  [0.1]
  [0.1]]

 [[0.1]
  [0.1]
  [0.1]
  [0.1]]

 [[0.1]
  [0.1]
  [0.1]
  [0.1]]

 [[0.1]
  [0.1]
  [0.1]
  [0.1]]

 [[0.1]
  [0.1]
  [0.1]
  [0.1]]]
<NDArray 10x4x1 @cpu(0)>

#最终计算背景变量,注意⼒机制采⽤更⾼效的⽮量化计算(softmax(QK⊤)V):编码器在所有时间步的隐藏状态enc_states和softmax运算输出的值相乘
#alpha.shape为 (10, 4, 1),enc_states.shape为 (10, 4, 8),(alpha * enc_states).shape为 (10, 4, 8),sum(axis=0)表示在第一维上进行相加和
>>> result = (alpha * enc_states).sum(axis=0)
>>> result.shape
(4, 8)

exp()、log()、log2()、log10()

1.exp函数即指数函数:e的x次方的函数
	exp:高等数学里以自然常数e为底的指数函数,等于2.718281828459045
	numpy.exp():返回e的幂次方,e是一个常数为2.718281828459045
	exp(0) = e的0次方 = 1
	exp(1) = e的1次方 = e = 2.718281828459045
 	exp(2) = e的2次方 = 7.38905609893065
 
	>>> import numpy as np
	>>> np.exp(1)
	2.718281828459045
	>>> np.exp(2)
	7.38905609893065

2.log10()、log2()
	#log10:以10为底数的对数,对数是对求幂的逆运算
	#log2:以2为底数的对数,对数是对求幂的逆运算

	>>> import numpy as np
	#log10:以10为底,求10的多少次方为1,即10的0次方为1
	>>> np.log10(1)
	0.0
	#log10:以10为底,求10的多少次方为10,即10的1次方为10
	>>> np.log10(10)
	1.0
	#log10:以10为底,求10的多少次方为100,即10的2次方为100
	>>> np.log10(100)
	2.0
	>>> np.log10(1000)
	3.0

	#log2:以2为底,求2的多少次方为1,即2的0次方为1
	>>> np.log2(1)
	0.0
	#log2:以2为底,求2的多少次方为2,即2的1次方为2
	>>> np.log2(2)
	1.0
	#log2:以2为底,求2的多少次方为4,即2的2次方为4
	>>> np.log2(4)
	2.0
	>>> np.log2(8)
	3.0
	>>> np.log2(16)
	4.0

3.log()
	#log默认以e为底,求e(2.718281828459045)的多少次方为1,即e(2.718281828459045)的0次方为1
	>>> np.log(1)
	0.0
	#log默认以e为底,求e(2.718281828459045)的多少次方为e,即e(2.718281828459045)的1次方为e
	>>> np.log(np.e)
	1.0
	#log默认以e为底,求e(2.718281828459045)的多少次方为10,即e(2.718281828459045)的2.302585092994046次方为10
	>>> np.log(10)
	2.302585092994046
	#log默认以e为底,求e(2.718281828459045)的多少次方为100,即e(2.718281828459045)的4.605170185988092次方为100
	>>> np.log(100)
	4.605170185988092

4.math.log()、math.log2()、math.log10()
	#math.log()、math.log2()、math.log10() 等同于 numpy的log()、log2()、log10()
	>>> import math
	#log默认以e为底,求e(2.718281828459045)的多少次方为1,即e(2.718281828459045)的0次方为1
	>>> math.log(1)
	0.0
	>>> math.log(math.e)
	1.0
	>>> math.log(10)
	2.302585092994046
	>>> math.log(100)
	4.605170185988092

	#log2:以2为底,求2的多少次方为1,即2的0次方为1
	>>> math.log2(1)
	0.0
	>>> math.log2(2)
	1.0
	>>> math.log2(4)
	2.0
	 
	#log10:以10为底,求10的多少次方为1,即10的0次方为1
	>>> math.log10(1)
	0.0
	>>> math.log10(10)
	1.0
	>>> math.log10(100)
	2.0

5.math.log(m,n)	和对应的numpy写法(np.log(m) / np.log(n))
	#math.log(m,n) 表示n为底数,m为真数,即以n为底m的对数

	#4的1次方为4
	>>> math.log(4,4)
	1.0
	#3的1.2618595071429148次方约为4
	>>> math.log(4,3)
	1.2618595071429148
	#2的2次方约为4
	>>> math.log(4,2)
	2.0

	#等同于 math.log(4,4)
	>>> np.log(4) / np.log(4)
	1.0
	#等同于 math.log(4,3)
	>>> np.log(4) / np.log(3)
	1.2618595071429148
	#等同于 math.log(4,2)
	>>> np.log(4) / np.log(2)
	2.0


numpy.random.multinomial、概率分布之二项分布与多项分布、采样策略之softmax温度

>>> import numpy
>>> numpy.random.binomial(n=10, p=0.7, size = 1)
array([7])
 
>>> a = numpy.random.binomial(n=10, p=0.7, size = 10)
>>> a
array([8, 7, 5, 7, 6, 7, 5, 7, 5, 8])
>>> b = numpy.mean(a)
>>> b
6.5
>>> a = numpy.random.binomial(n=10, p=0.7, size = 10)
>>> b = numpy.mean(a)
>>> b
7.4
 
>>> a = numpy.random.binomial(n=10, p=0.1, size = 20)
>>> a
array([1, 1, 0, 2, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 2, 0, 1])
>>> b = numpy.mean(a)
>>> b
0.55
>>> a = numpy.random.binomial(n=10, p=0.1, size = 20)
>>> b = numpy.mean(a)
>>> b
1.35
结果生成一个一维数组,数组中每个元素值均位于均为 0到n,n由参数n指定,此处每个元素值均为 0到10 之间的整数,
如果令参数 size=100,则生成数量大小为100的一维数组。设置 p=0.1时,数组的均值会在1上下,其均值的分布趋近于p所设置的概率0.1。
设置 p=0.7时,数组的均值会在7上下,其均值的分布趋近于p所设置的概率0.7。下图中根据p=0.7得出的结果所示,可见正例出现 7 的样本数最多,并以 7 为中心向两侧递减。

>>> import numpy
>>> numpy.random.multinomial(n=10, pvals=[0.2,0.4,0.4], size = 1)
array([[1, 4, 5]])
>>> numpy.random.multinomial(n=20, pvals=[0.3,0.3,0.4], size = 2)
array([[9, 4, 7],
       [6, 6, 8]])
>>> np.random.multinomial(n=20, pvals=[1/6.]*6, size=1)
array([[3, 3, 3, 4, 1, 6]])
#[1/6.]*6 为 [0.16666666666666666, 0.16666666666666666, 0.16666666666666666, 0.16666666666666666, 0.16666666666666666, 0.16666666666666666]
 
>>> a = numpy.random.multinomial(n=10.0, pvals=[0.2,0.4,0.4], size = 1000)
>>> a
array([[1, 7, 2],
       [1, 3, 6],
       [2, 5, 3],
       ...,
       [0, 4, 6],
       [3, 4, 3],
       [2, 3, 5]])
>>> a.shape
(1000, 3)
>>> b = numpy.mean(a,axis=0)
>>> b
array([1.927, 3.985, 4.088])
>>> a = numpy.random.multinomial(n=10.0, pvals=[0.2,0.4,0.4], size = 1000)
>>> b = numpy.mean(a,axis=0)
>>> b
array([2.027, 4.015, 3.958])
结果为一个二维数组,二维数组中元素数量由 size值指定,而二维数组中每个元素均为 一维数组(N维向量),一维数组的大小 即 N维向量的 N 等于 pvals参数数组的长度大小,
一维数组(N维向量)中每个元素值位于 0到n值 之间,n值 由参数n指定,一维数组(N维向量)中所有元素值之和也同样为n值,也同样由参数n指定。比如此时设置size = 1000,
那么二维数组中就会有1000个一维数组(N维向量),此时1000个向量的均值基本是在[2.xxx, 4.xxx, 4.xxx] 附近,
从上述计算结果 array([2.027, 4.015, 3.958]) 和 array([1.927, 3.985, 4.088]) 可以得出这个结论,也即可见其均值的分布趋近于pvals所设置的概率[0.2, 0.4, 0.4]。

发布了225 篇原创文章 · 获赞 111 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/zimiao552147572/article/details/104084374
今日推荐