在利用numpy、TensorFlow和Keras等进行编程时,经常发现很多函数携带axis参数,且具有相同功能的函数的axis(轴)参数取值范围可能不同(操作方式也不一样),从而引起一些困惑。针对这一问题,归纳总结如下:
2. TensorFlow函数中的axis参数理解
在TensorFlow函数中,axis输入参数的取值范围是[-rank(input_tensor), rank(input_tensor))。
2.1 案例1——tf.reduce_sum()
函数原型:
reduce_sum(
input_tensor,
axis=None,
keep_dims=False,
name=None,
reduction_indices=None
)
函数作用:
沿着指定的axis轴,计算输入张量的和
import tensorflow as tf
x = tf.constant([[1, 2, 3], [4, 5, 6]])
sess = tf.InteractiveSession()
print("输入张量:\n",x.eval())
y1 = tf.reduce_sum(x)
print("所有张量元素的和:\n",y1.eval())
y2 = tf.reduce_sum(x, axis = 0)
print("沿着张量0轴方向求和:\n",y2.eval())
y3 = tf.reduce_sum(x, axis = 1)
print("沿着张量1轴方向求和:\n",y3.eval())
y4 = tf.reduce_sum(x, axis = 1, keep_dims=True)
print("沿着张量1轴方向求和,并保持维度:\n",y4.eval())
输入张量:
[[1 2 3]
[4 5 6]]
所有张量元素的和:
21
沿着张量0轴方向求和:
[5 7 9]
沿着张量1轴方向求和:
[ 6 15]
沿着张量1轴方向求和,并保持维度:
[[ 6]
[15]]
注意事项:
根据www.tensorflow.org中对tf.reduce_sum()的描述,axis输入参数的取值范围是[-rank(input_tensor), rank(input_tensor)),那么前述的常数张量x(rank = 2,2阶)的axis取值范围是[-2,2),那么axis = -2、-1究竟是什么含义呢?下依旧利用前述所定义的常数张量x进行试验,即
y2 = tf.reduce_sum(x, axis = 0)
print("沿着张量0轴方向求和:\n",y2.eval())
y5 = tf.reduce_sum(x, axis = -2)
print("沿着张量-2轴方向求和:\n",y5.eval())
y3 = tf.reduce_sum(x, axis = 1)
print("沿着张量1轴方向求和:\n",y3.eval())
y6 = tf.reduce_sum(x, axis = -1)
print("沿着张量-1轴方向求和:\n",y6.eval())
沿着张量0轴方向求和:
[5 7 9]
沿着张量-2轴方向求和:
[5 7 9]
沿着张量1轴方向求和:
[ 6 15]
沿着张量-1轴方向求和:
[ 6 15]
总结:
根据上述试验发现,在axis = [-2,2)的区间内时,axis的取值虽然可以不同,但是实际的效果却存在相同的情况,即
axis = -2 对应 axis = 0,效果一致;
axis = -1 对应 axis = 1,效果一致;
2.2 案例2——tf.argmax()
函数原型:
argmax(
input,
axis=None,
name=None,
dimension=None,
output_type=tf.int64
)
函数作用:
沿着指定axis轴的方向寻找最大值,并返回对应的索引
import numpy as np
import tensorflow as tf
A = np.random.random((3,4))
x = tf.constant(A)
sess = tf.InteractiveSession()
print("输入张量:\n",x.eval())
y1 = tf.argmax(x)
print("axis缺省时,默认axis = 0:\n",y1.eval())
y2 = tf.argmax(x, axis = 0)
print("沿着张量0轴方向求和:\n",y2.eval())
y3 = tf.argmax(x, axis = 1)
print("沿着张量1轴方向求和:\n",y3.eval())
输入张量:
[[ 0.34570824 0.4327304 0.81727727 0.01683761]
[ 0.66160006 0.49774433 0.03712519 0.10179577]
[ 0.17496762 0.48599597 0.90044948 0.01108119]]
axis缺省时,默认axis = 0:
[1 1 2 1]
沿着张量0轴方向求和:
[1 1 2 1]
沿着张量1轴方向求和:
[2 0 2]
注意事项:
根据www.tensorflow.org中对tf.argmax()的描述,axis输入参数的取值范围是[-rank(input), rank(input)),那么前述的常数张量x(rank = 2,2阶)的axis取值范围是[-2,2),那么axis = -2、-1究竟是什么含义呢?下依旧利用前述所定义的常数张量x进行试验,即
y2 = tf.argmax(x, axis = 0)
print("沿着张量0轴方向求和:\n",y2.eval())
y4 = tf.argmax(x, axis = -2)
print("沿着张量-2轴方向求和:\n",y4.eval())
y3 = tf.argmax(x, axis = 1)
print("沿着张量1轴方向求和:\n",y3.eval())
y5 = tf.argmax(x, axis = -1)
print("沿着张量-1轴方向求和:\n",y5.eval())
沿着张量0轴方向求和:
[1 1 2 1]
沿着张量-2轴方向求和:
[1 1 2 1]
沿着张量1轴方向求和:
[2 0 2]
沿着张量-1轴方向求和:
[2 0 2]
总结:
根据上述试验发现,在axis = [-2,2)的区间内时,axis的取值虽然可以不同,但是实际的效果却存在相同的情况,即
axis = -2 对应 axis = 0,效果一致;
axis = -1 对应 axis = 1,效果一致;
2.3 案例3——tf.concat()
函数原型:
concat(
values,
axis,
name=’concat’
)
函数作用:
沿着指定轴(维度)合并张量
import numpy as np
import tensorflow as tf
A = np.ones((2,2))
B = np.zeros((2,2))
x1 = tf.constant(A)
x2 = tf.constant(B)
sess = tf.InteractiveSession()
print("输入张量1:\n",x1.eval())
print("输入张量2:\n",x2.eval())
y1 = tf.concat([x1,x2], axis = 0)
print("沿着张量0轴方向合并(垂直合并):\n",y1.eval())
y2 = tf.concat([x1,x2], axis = 1)
print("沿着张量1轴方向合并(水平合并):\n",y2.eval())
输入张量1:
[[ 1. 1.]
[ 1. 1.]]
输入张量2:
[[ 0. 0.]
[ 0. 0.]]
沿着张量0轴方向合并(垂直合并):
[[ 1. 1.]
[ 1. 1.]
[ 0. 0.]
[ 0. 0.]]
沿着张量1轴方向合并(水平合并):
[[ 1. 1. 0. 0.]
[ 1. 1. 0. 0.]]
注意事项:
根据www.tensorflow.org中对tf.concat()的描述,axis输入参数的取值范围是[-rank(values), rank(values)),那么前述的常数张量x(rank = 2,2阶)的axis取值范围是[-2,2),那么axis = -2、-1究竟是什么含义呢?下依旧利用前述所定义的常数张量x进行试验,即
y1 = tf.concat([x1,x2], axis = 0)
print("沿着张量0轴方向合并(垂直合并):\n",y1.eval())
y3 = tf.concat([x1,x2], axis = -2)
print("沿着张量-2轴方向合并(垂直合并):\n",y3.eval())
y2 = tf.concat([x1,x2], axis = 1)
print("沿着张量1轴方向合并(水平合并):\n",y2.eval())
y4 = tf.concat([x1,x2], axis = -1)
print("沿着张量-1轴方向合并(水平合并):\n",y4.eval())
沿着张量0轴方向合并(垂直合并):
[[ 1. 1.]
[ 1. 1.]
[ 0. 0.]
[ 0. 0.]]
沿着张量-2轴方向合并(垂直合并):
[[ 1. 1.]
[ 1. 1.]
[ 0. 0.]
[ 0. 0.]]
沿着张量1轴方向合并(水平合并):
[[ 1. 1. 0. 0.]
[ 1. 1. 0. 0.]]
沿着张量-1轴方向合并(水平合并):
[[ 1. 1. 0. 0.]
[ 1. 1. 0. 0.]]
总结:
根据上述试验发现,在axis = [-2,2)的区间内时,axis的取值虽然可以不同,但是实际的效果却存在相同的情况,即
axis = -2 对应 axis = 0,效果一致;
axis = -1 对应 axis = 1,效果一致;
在Tensorflow中还有很多函数中存在axis输入参数,比如tf.reduce_mean()、tf.redunce_max()等函数,其对于的axis理解方式跟上述案例完全一致。
3. Keras函数中的axis参数理解
3.1 案例1——sum()
函数原型:
keras.backend.sum(x, axis=None, keepdims=False)
函数作用:
沿着指定的axis轴,计算张量中值的和
import numpy as np
from keras import backend as K
Using TensorFlow backend.
tf_session = K.get_session()
kcon = K.constant([[1, 2,0], [3, 4,5]])
print("输入张量:\n",kcon.eval())
sum0 = K.sum(kcon,axis = 0)
print("沿着张量0轴方向求和:\n",sum0.eval())
sum1 = K.sum(kcon,axis = 1)
print("沿着张量1轴方向求和:\n",sum1.eval())
sum2 = K.sum(kcon)
print("axis缺省时,所有元素求和:\n",sum2.eval())
输入张量:
[[ 1. 2. 0.]
[ 3. 4. 5.]]
沿着张量0轴方向求和:
[ 4. 6. 5.]
沿着张量1轴方向求和:
[ 3. 12.]
axis缺省时,所有元素求和:
15.0
注意事项:
在Keras.io中并未明确的介绍axis的取值范围,初步认为应该与TensorFlow一致(因为本程序是基于TensorFlow后端,最底层的运算时基于TensorFlow),实验如下:
sum4 = K.sum(kcon,axis = -2)
print("沿着张量-2轴方向求和:\n",sum4.eval())
sum5 = K.sum(kcon,axis = -1)
print("沿着张量-1轴方向求和:\n",sum5.eval())
沿着张量-2轴方向求和:
[ 4. 6. 5.]
沿着张量-1轴方向求和:
[ 3. 12.]
#下面超过了axis的取值范围[-2,2),因此会报错
sum6 = K.sum(kcon,axis = -3)
sum7 = K.sum(kcon,axis = -1)
3.2 案例2——argmax()
函数原型:
keras.bacend.argmax(x, axis=-1)
函数作用:
沿着指定的轴寻找最大值,并返回其索引值
import numpy as np
from keras import backend as K
tf_session = K.get_session()
var = np.random.random((3,5))
kcon = K.constant(var)
print("输入张量:\n",kcon.eval())
y0 = K.argmax(kcon,axis = 0)
print("沿着张量0轴方向寻找最大值索引:\n",y0.eval())
y1 = K.argmax(kcon,axis = 1)
print("沿着张量1轴方向寻找最大值索引:\n",y1.eval())
y2 = K.argmax(kcon)
print("axis缺省时,默认为-1,对应1的结果:\n",y2.eval())
输入张量:
[[ 0.13900661 0.4054634 0.64765936 0.5716511 0.61112058]
[ 0.41806924 0.60134852 0.92036146 0.68033886 0.3683911 ]
[ 0.95494515 0.05807289 0.44499308 0.73589486 0.2641674 ]]
沿着张量0轴方向寻找最大值索引:
[2 1 1 2 0]
沿着张量1轴方向寻找最大值索引:
[2 2 0]
axis缺省时,默认为-1,对应1的结果:
[2 2 0]
4. 结论
根据上述试验表明,无论是Numpy、Tensorflow,还是Keras,如果相关函数中需要输入axis参数,那么axis的取值范围均与输入的秩(阶)有关,axis范围:[-rank(input) ,rank(input)),且虽然axis取值不同,但是最终效果可能与其他的重合,如:
axis = -2 对应 axis = 0,效果一致;
axis = -1 对应 axis = 1,效果一致;