【python】axis 的形象化理解

在这里插入图片描述

大开眼界,4D 5D 6D


最近一次修订时间为 2020-10-19



np.argmax()

np.argmax()功能是,返回某维度中最大值的下标,借此机会,我们好好分析下axis

eg 二维情况1

np.argmax(prediction, 1) 返回每行最大值的下标

np.argmax(prediction, 0) 返回每列最大值的下标

这里写图片描述

import numpy as np
test = np.array([[1,4],
                 [2,1],
                 [3,0]])
print(test.shape)
print(np.argmax(test,0))
print(np.argmax(test,1))

output

(3, 2)
[2 0]
[1 0 0]

形象化理解

import numpy as np
test = np.array([[[1, 2, 3], 
                  [3, 4, 5], 
                  [6, 7, 8]],
                 
                 [[6, 7, 8], 
                  [3, 4, 5], 
                  [1, 2, 3]],
                 
                 [[1, 2, 3], 
                  [6, 7, 8], 
                  [3, 4, 5]]
                ])

看看个维度的大小

test.shape

output

(3, 3, 3)

从左到右依次为 axis = 0,axis = 1,axis = 2

可以形象的用下图表示

这里写图片描述

np.argmax(test, 0)

可以形象的理解为对 axis = 0 进行降维打击,从正面把长方体押扁,所以押扁后 axis = 0就没有了,输出的shape为(3,3)

output

array([[1, 1, 1],
       [2, 2, 2],
       [0, 0, 0]])

同样的

np.argmax(test, 1)

理解为对 axis = 1 进行降维打击,从上面一巴掌把长方体押扁,所以押扁后 axis = 1就没有了,输出的shape为(3,3)
output

array([[2, 2, 2],
       [0, 0, 0],
       [1, 1, 1]])

最后

np.argmax(test, 2)

理解为对 axis = 2 进行降维打击,从右面一巴掌把长方体押扁,所以押扁后 axis = 2就没有了,输出的shape为(3,3)
output

array([[2, 2, 2],
       [2, 2, 2],
       [2, 2, 2]])

tf.reduce_mean()

官方文档:https://tensorflow.google.cn/api_docs/python/tf/math/reduce_mean

reduce就是“对矩阵降维”的含义,下划线后面的部分就是降维的方式,在reduce_sum()中就是按照求和的方式对矩阵降维。那么其他reduce前缀的函数也举一反三了,比如reduce_mean()就是按照某个维度求平均值,等等2

import os  
os.environ["CUDA_DEVICE_ORDER"]="PCI_BUS_ID"   
os.environ["CUDA_VISIBLE_DEVICES"]="1" 
import tensorflow as tf
import numpy as np

a = tf.constant(np.arange(8).reshape(2,2,2))
b = tf.reduce_mean(a,0) # 对0维度进行降维打击
c = tf.reduce_mean(a,1) # 对1维度进行降维打击
d = tf.reduce_mean(a,2) # 对2维度进行降维打击
e = tf.reduce_mean(a,[0,1]) # 对0,1维度进行降维打击,剩下第2维
f = tf.reduce_mean(a,[0,2]) # 对0,2维度进行降维打击,剩下第1维
g = tf.reduce_mean(a,[1,2]) # 对1,2维度进行降维打击,剩下第0维
h = tf.reduce_mean(a,[0,1,2]) # 对0,1,2维度进行降维打击,剩下第0维

with tf.Session() as sess:
    print(sess.run(a),'\n')
    print('--------------')
    print(sess.run(b),'\n')
    print(sess.run(c),'\n')
    print(sess.run(d),'\n')
    print('--------------')
    print(sess.run(e),'\n')
    print(sess.run(f),'\n')
    print(sess.run(g),'\n')
    print('--------------')    
    print(sess.run(h),'\n')

output

[[[0 1]
  [2 3]]

 [[4 5]
  [6 7]]] 

--------------
[[2 3]
 [4 5]] 

[[1 2]
 [5 6]] 

[[0 2]
 [4 6]] 

--------------
[3 4] 

[2 4] 

[1 5] 

--------------
3 

在这里插入图片描述

CNN 中 global average pooling 操作,往往如 e/f/g 这种形式,也即在 feature maphw 维度进行 reduce_mean,而保留channels维度,我们可以借助 global average pooling 来理解同时对两个维度进行降维打击的操作,哈哈哈!会形象很多。

e = tf.reduce_mean(a,[0,1]) # 对0,1维度进行降维打击,剩下第2维
f = tf.reduce_mean(a,[0,2]) # 对0,2维度进行降维打击,剩下第1维
g = tf.reduce_mean(a,[1,2]) # 对1,2维度进行降维打击,剩下第0维

np.transpose()

参考 Numpy中transpose()函数的可视化理解

import numpy as np

a = np.arange(1,25,1).reshape((2, 3, 4))
print(a,'\n')

print("234:\n",np.transpose(a, (0, 1, 2)),'\n') # 1,2,3 dim raw c

output

[[[ 1  2  3  4]
  [ 5  6  7  8]
  [ 9 10 11 12]]

 [[13 14 15 16]
  [17 18 19 20]
  [21 22 23 24]]] 

234:
 [[[ 1  2  3  4]
  [ 5  6  7  8]
  [ 9 10 11 12]]

 [[13 14 15 16]
  [17 18 19 20]
  [21 22 23 24]]] 

新建一个 3 维数组 a,axis = 0,1,2 的长度分别为 2,3,4!调用 transpose(a, (0, 1, 2),数组 axis 的顺序还是原来 0,1,2,因此结果同原数组 a 。可视化效果如下

在这里插入图片描述

下面试试其他情况

print("243:\n",np.transpose(a, (0, 2, 1)),'\n') # 243

np.transpose(a, (0, 2, 1),可以看到数组 a 的 axis 顺序以改变了,原来 axis = 0,1,2 的长度为 2,3,4!改变 axis = 1 和 2 的顺序后,新的数组 axis = 0,1,2 的长度应该为 2,4,3!所以转变后的新数组应该由 2 个 4×3 的二维矩阵构成

目前我们知道新数组的 shape 了,具体每个位置的数值怎么确定呢?我们画个图来解释 transpose 的过程

在这里插入图片描述

(1)是原数组 a
(2)是调用 np.transpose(a, (0, 2, 1) 后,axis 的变动情况
(3)展示的是,在转换后的 axis 中,按照原数组 a 的排列形式,把数组重新画出来(相当于用不同视角来观察数组 a),重画的时候可以根据相对关系来画,比如,沿着 axis=0,是两个二维数组,沿着 axis = 1 数组依次为 1,5,9,沿着 axis = 2,数组依次为 1,2,3,4。其他位置的数值同理!
(4)展示的是新数组,具体操作为在(3)的基础上,把 axis 恢复成 0,1,2 的形式,然后按照本博客前文介绍的 axis 理论,结合新数组的 shape,把新数组每个位置的值确认出来!

看看代码运行的结果

243:
 [[[ 1  5  9]
  [ 2  6 10]
  [ 3  7 11]
  [ 4  8 12]]

 [[13 17 21]
  [14 18 22]
  [15 19 23]
  [16 20 24]]] 

和(4)一摸一样,大功告成


上面的例子比较直接,再试试一个难度稍微高的例子

print("432:\n",np.transpose(a, (2, 1, 0)),'\n') # 432

先确认新数组 axis 的长度,axis = 0,1,2 的长度应该为 4,3,2。再绘图试试

在这里插入图片描述

注意下步骤(4),同一颜色为一个平面,

代码输出的结果为

432:
 [[[ 1 13]
  [ 5 17]
  [ 9 21]]

 [[ 2 14]
  [ 6 18]
  [10 22]]

 [[ 3 15]
  [ 7 19]
  [11 23]]

 [[ 4 16]
  [ 8 20]
  [12 24]]] 

与绘图一致


其他情况的结果如下,自己可以试着按照上述的画图方法推导下

print("324:\n",np.transpose(a, (1, 0, 2)),'\n') # 324
print("342:\n",np.transpose(a, (1, 2, 0)),'\n') # 342
print("423:\n",np.transpose(a, (2, 0, 1)),'\n') # 423

output

324:
 [[[ 1  2  3  4]
  [13 14 15 16]]

 [[ 5  6  7  8]
  [17 18 19 20]]

 [[ 9 10 11 12]
  [21 22 23 24]]] 

342:
 [[[ 1 13]
  [ 2 14]
  [ 3 15]
  [ 4 16]]

 [[ 5 17]
  [ 6 18]
  [ 7 19]
  [ 8 20]]

 [[ 9 21]
  [10 22]
  [11 23]
  [12 24]]] 
  
423:
 [[[ 1  5  9]
  [13 17 21]]

 [[ 2  6 10]
  [14 18 22]]

 [[ 3  7 11]
  [15 19 23]]

 [[ 4  8 12]
  [16 20 24]]] 

  1. tf.argmax()以及axis解析 ↩︎

  2. TensorFlow基础1:reduce_sum()函数和reduce_mean()函数 ↩︎

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值