argmax和softargmax的基本方法都是找到坐标的期望值,即对array softmax归一化以后得到概率值,然后和坐标相乘得到坐标的期望值,就是最大值的坐标。
argmax的程序:
import numpy as np
array=np.arange(11) #np.random.rand((10))
print(array)
farray_max=np.max(array)
softmax=np.exp(array-farray_max)/np.sum(np.exp(array-farray_max))
softargmax=np.sum(np.multiply(softmax,np.arange(len(array))))
print(softargmax)
print(round(softargmax))
[ 0 1 2 3 4 5 6 7 8 9 10]
9.418207014907832
9.0
可以看到结果是不准确的,argmax这种方法如果队列中最大值、次最大值等距离很近,结果可能不准确,于是有softargmax
一维softargmax:
import numpy as np
f=100
array=np.arange(11) #np.random.rand((10))
print(array)
farray=np.multiply(array,f)
farray_max=np.max(farray)
softmax=np.exp(farray-farray_max)/np.sum(np.exp(farray-farray_max))
softargmax=np.sum(np.multiply(softmax,np.arange(len(array))))
print(softargmax)
print(round(softargmax))
[ 0 1 2 3 4 5 6 7 8 9 10]
10.0
10.0
乘以f=100以后,由于np.exp的指数增长特征,进一步拉开最大值和其他值之间的距离,这样就可以求出最大值的坐标。
二维的softargmax
这种方法通常用于人体姿态估计中最后层输出的heatmap图,这种方法用来求出heatmap图中关键点的坐标。
论文的链接:Human Pose Regression by Combining Indirect Part Detection and Contextual Information
的示意图
import numpy as np
array=np.arange(25)
np.random.shuffle(array)
array=np.reshape(array,(5,5))
print(array)
maxa=np.max(array)
coorda=np.where(array==maxa)
coorda=np.squeeze(coorda)
print('numpy自带求最大值坐标: ',coorda)
fmwidth=5
soft_argmax_x=np.zeros((fmwidth,fmwidth))
soft_argmax_y=np.zeros((fmwidth,fmwidth))
for i in range(1,fmwidth+1,1):
soft_argmax_x[i-1,:] = i / fmwidth
for j in range(1,fmwidth+1,1):
soft_argmax_y[:,j-1]=j / fmwidth
array_softmax=np.exp(array-maxa)/np.sum(np.exp(array-maxa))
xcoord=np.sum(np.multiply(array_softmax,soft_argmax_x))
ycoord=np.sum(np.multiply(array_softmax,soft_argmax_y))
print('softargmax求出的最大值坐标:',round(xcoord*5)-1,round(ycoord*5)-1)
[[17 16 10 15 12]
[14 21 18 13 0]
[ 6 4 23 24 20]
[22 3 2 9 11]
[ 8 1 5 19 7]]
numpy自带求最大值坐标: [2 3]
softargmax求出的最大值坐标: 2.0 2.0
如果加上一行,就可以得到准确的坐标,但深度学习实际使用时,不会加这行,而是让网络自己去学习应该有的分布。
import numpy as np
array=np.arange(25)
np.random.shuffle(array)
array=np.reshape(array,(5,5))
array=np.multiply(array,100)
print(array)
maxa=np.max(array)
coorda=np.where(array==maxa)
coorda=np.squeeze(coorda)
print('numpy自带求最大值坐标: ',coorda)
fmwidth=5
soft_argmax_x=np.zeros((fmwidth,fmwidth))
soft_argmax_y=np.zeros((fmwidth,fmwidth))
for i in range(1,fmwidth+1,1):
soft_argmax_x[i-1,:] = i / fmwidth
for j in range(1,fmwidth+1,1):
soft_argmax_y[:,j-1]=j / fmwidth
array_softmax=np.exp(array-maxa)/np.sum(np.exp(array-maxa))
xcoord=np.sum(np.multiply(array_softmax,soft_argmax_x))
ycoord=np.sum(np.multiply(array_softmax,soft_argmax_y))
print('softargmax求出的最大值坐标:',round(xcoord*5)-1,round(ycoord*5)-1)
[[1500 1900 1600 600 1700]
[1000 2000 1800 800 1300]
[ 400 900 2100 1400 300]
[ 500 200 1100 1200 2300]
[ 700 100 2200 0 2400]]
numpy自带求最大值坐标: [4 4]
softargmax求出的最大值坐标: 4.0 4.0
参考的内容:Numerical Coordinate Regression with Convolutional Neural Networks
Human Pose Regression by Combining Indirect Part Detection and Contextual Information
soft-argmax将热点图转换为数值坐标应用于人体姿态估计 - xiongzihua - 博客园
Integral Human Pose Regression
soft-argmax將熱點圖轉換為數值坐標應用於人體姿態估計 - IT閱讀