如何理解numpy多维数组与Tensorflow张量中的axis概念

时间:2021-02-07 21:24:49

在numpy中,使用的axis的地方非常多,常用的操作如average、max、min、sum。

在Tensorflow中也一样。但是由于网上很多文章都说得云里雾里,没办法真正搞懂axis以及对应上面这些操作的真正含义。

比如,求和这事:

在numpy中,可能是这样:

import numpy as np

np.random.seed(1980)
x = np.random.randint(0,5,[2,2])
print("x:",x)
print()
snone = x.sum(axis=None)
print("sNone:",snone)
print()
s0 = x.sum(axis=0)
print("s0:",s0)
print()
s1 = x.sum(axis=1)
print("s1:",s1)
print()

结果为:

x: [[4 0]

 [0 3]]

sNone: 7

s0: [4 3]

s1: [4 3]

在TensorFlow中,可能是这样

import tensorflow as tf    
x=tf.constant([[1.,2.],[5.,2.]])     
xShape=tf.shape(x)  
z1=tf.reduce_mean(x,axis=0)#沿axis=0操作  
z2=tf.reduce_mean(x,axis=1)#沿axis=1操作  
with tf.Session() as sess:  
 xShapeValue,d1,d2=sess.run([xShape,z1,z2])  
    print('shape= %s'%(xShapeValue))  
    print(d1)  
    print(d2)  

输出结果为:

shape= [2 2]
[3. 2.]
[1.5 3.5]

如何理解上述的两段代码,如何理解axis的含义,还有各种不同的操作包括:sum, prod,mean,average,min,max,sort

为系统的理解,我们首先重新定义以上的各大操作:

sum, prod,mean=average, 均为同一类型的操作,可视为输入一组张量,返回一个张量(注意这里的结果降维了)

即: res_tensor =  func( [tensor])

举个简单的例子: res = sum([1,2,3,4,5])

输出为一个标量(0阶张量)res=15, 这里确实降维了,原来输入为一个数组,可看成向量,或者1阶张量,经过sum操作后,变为一个0阶张量了

再举个输入为二阶张量数组的列子(整个输入可看做3阶张量)

res = sum([[1,2],[3,4]])  (注意这里是我们对操作的定义,非numpy里面的函数prod,涉及code部分后面会给出)

我们要对数组里面的每个元素做加法,数组的元素有2个:[1,2]  和 [3,4] ,每个元素可看成一个向量或者1阶张量。现定义求和从操作对向量的方法为,对每个向量的分量分别求和,即 结果为:[sum(1,3),sum(2,4)] = [4,6]

同理,prod,mean,average的操作也是一样,当碰到张量时,分别对应张量的分量进行操作。

min,max操作与sum,prod也差不多。如:

res = min([[1,2],[3,4]] , 结果为:[min(1,3), min(2,4)] = [1,2]

sort操作与上面的有些不同, 相当于:

[res_tnesor] = func([tensor]) 

输入一个张量数组,输出仍然为一个张量数组,没有降维。

如:sort([3,5,1,2]), 结果为:[1,2,3,5]

下面我解释一下,tensorflow或者numpy中,关于axis的概念:

比如numpy数组:[ [ 1, 2] , [3, 4] ] 

我的方法是,axis就是括号组的序号,即axis=0, 指的是从左到右的第一组括号,这里就是最左边的那个,这组括号对应的

元素集合为:[1,2] 和[3,4] 一共2个元素,都是向量。

axis = 1 ,指的是从左往右边数,第二组括号。在这组括号,分成了2个集合。第二组括号的第一个元素集合为:

1和2,第二个元素集合为:3和4。

这里需要注意的是,像sum, average,mean等等函数,可以同时对,多个标量数组操作(多个集合操作)

即:[res_tensor1, res_tensor2] = func([tensor1], [tensor2])

如: sum([1,2], [3,4]) = [3,7] 

有了上面的概念,我们就可以理解numpy或者tensorflow中的代码了。

比如:sum0 = np.sum([[1,2],[3,4]],axis=0)

首先,数括号,得到括号组对应的元素集合,这里只有一个[1,2]和[3,4]构成的集合,然后计算这两个张量元素的和(对应分量求和),得到sum0 = [sum(1,3), sum(2,4)] , 结果为:[4,6] 

sum1 = np.sum([[1,2],[3,4]], axis=1)

数括号,左边的第二个括号(对应的组),集合有个2个:1跟2构成的集合,3跟4构成的集合。对这些集合求sum.

sum1 = [sum([1,2]), sum([3,4])] ,结果为:[3,7]

最后给出一段程序,希望大家能充分理解axis的概念以及对应的操作的意义

 

import numpy as np

np.random.seed(1980)
x = np.random.randint(0,5,[3,2,2])
print("x:",x)
print()
snone = x.sum(axis=None)
print("sNone:",snone)
print()
s0 = x.sum(axis=0)
print("s0:",s0)
print()
s1 = x.sum(axis=1)
print("s1:",s1)
print()
s2 = x.sum(axis=2)
print("s2:",s2)
print()

print("x:",x)
print()
mnone = x.min(axis=None)
print("mNone:",mnone)
print()
m0 = x.min(axis=0)
print("m0:",m0)
print()
m1 = x.min(axis=1)
print("m1:",m1)
print()
m2 = x.min(axis=2)
print("m2:",m2)
print()

print("x:",x)
print()
#b = x.copy()
#b.sort(axis=None)    排序asix不允许为None
#print("ssNone:",b)
#print()
b = x.copy()
b.sort(axis=0)
print("ss0:",b)
print()
b = x.copy()
b.sort(axis=1)
print("ss1:",b)
print()
b = x.copy()
b.sort(axis=2)
print("ss2:",b)
print()

print("x:",x)
print()
prdNone = x.prod(axis=None)
print("prdNone:",prdNone)
print()
prd0 = x.prod(axis=0)
print("prd0:",prd0)
print()
prd1 = x.prod(axis=1)
print("prd1:",prd1)
print()
prd2 = x.prod(axis=2)
print("prd2:",prd2)
print()

输出结果为:

x: [[[4 0]
  [0 3]]
 [[0 3]
  [1 0]]
 [[4 2]
  [1 3]]]

sNone: 21

s0: [[8 5]
 [2 6]]

s1: [[4 3]
 [1 3]

 [5 5]]

s2: [[4 3]
 [3 1]
 [6 4]]

x: [[[4 0]
  [0 3]]
 [[0 3]
  [1 0]]
 [[4 2]

  [1 3]]]

mNone: 0

m0: [[0 0]
 [0 0]]

m1: [[0 0]
 [0 0]
 [1 2]]


m2: [[0 0]
 [0 0]
 [2 1]]

x: [[[4 0]
  [0 3]]
 [[0 3]
  [1 0]]
 [[4 2]
  [1 3]]]

ss0: [[[0 0]
  [0 0]]
 [[4 2]
  [1 3]]
 [[4 3]
  [1 3]]]

ss1: [[[0 0]
  [4 3]]
 [[0 0]
  [1 3]]
 [[1 2]
  [4 3]]]

ss2: [[[0 4]
  [0 3]]
 [[0 3]
  [0 1]]
 [[2 4]
  [1 3]]]

x: [[[4 0]
  [0 3]]
 [[0 3]
  [1 0]]
 [[4 2]
  [1 3]]]

prdNone: 0

prd0: [[0 0]
 [0 0]]

prd1: [[0 0]
 [0 0]
 [4 6]]

prd2: [[0 0]
 [0 0]
 [8 3]]


主要:axis=None,表示操作sum, prod等对每一个标量元素进行;即吧数据全部打平(flatten),然后来操作。

而sort函数,aixs不能为None,否则出错。

版权声明:本文为博主原创文章,未经博主允许不得转载。https://blog.csdn.net/aumtopsale/article/details/79698633