最近项目中需要调用softmax获取最大概率。但是我不想用tensorflow的自带的方法,想用python实现。开始以为很简单,但是发现对于矩阵的sotfmax还是要注意很多地方的,找了很多种方法,只有一种的结果和tensorflow计算的一样。所以记录下来。
Softmax函数实际上是有限项离散概率分布的梯度对数归一化。它能将一个含任意实数的K维向量 Z“压缩”到另一个K维实向量 σ(z) 中,使得每一个元素的范围都在(0,1)之间,并且所有元素的和为1。
主要可以参考sotfmax计算与求导
对于一个数组 x,使用tensorflow进行softmax计算
import tensorflow as tf
softmax_tf=tf.nn.sorfmax(x)
with tf.Session() as sess:
result=sess.run(sotfmax_tf)
对于纯python的实现,进过大量对比,发现他的结果几乎一样,
import numpy as np
def softmax(x):
"""
Compute the softmax function for each row of the input x.
Arguments:
x -- A N dimensional vector or M x N dimensional numpy matrix.
Return:
x -- You are allowed to modify x in-place
"""
orig_shape = x.shape
if len(x.shape) > 1:
# Matrix
#处理多维数组
exp_minmax = lambda x: np.exp(x - np.max(x))
denom = lambda x: 1.0 / np.sum(x)
#根据横轴减去最大的值,方便后面计算
x = np.apply_along_axis(exp_minmax,1,x)
#根据横轴计算要除的总分母
denominator = np.apply_along_axis(denom,1,x)
#将一维扩展到二维,方便后面广播相乘
if len(denominator.shape) == 1:
denominator = denominator.reshape((denominator.shape[0],1))
#广播方式相乘
x = x * denominator
else:
# Vector
#处理一维数组
x_max = np.max(x)
x = x - x_max
numerator = np.exp(x)
denominator = 1.0 / np.sum(numerator)
x = numerator.dot(denominator)
assert x.shape == orig_shape
return x