Content #
softmax函数定义如下:
def softmax(x):
if x.ndim == 2:
x = x.T
x = x - np.max(x, axis=0) # For numerical stability
y = np.exp(x) / np.sum(np.exp(x), axis=0)
return y.T
x = x - np.max(x) # For numerical stability
return np.exp(x) / np.sum(np.exp(x))
为什么在二维情况下,需要将x转置,求出结果y后再做一次转置?这不就相当于没有做一次无用的变换?
若不使用转置,softmax实现如下:
def softmax(x):
if x.ndim == 2:
# 直接按行减去每行的最大值
x = x - np.max(x, axis=1, keepdims=True) # For numerical stability
y = np.exp(x) / np.sum(np.exp(x), axis=1, keepdims=True)
return y
x = x - np.max(x) # For numerical stability
return np.exp(x) / np.sum(np.exp(x))
区别在于多了"keepdims=True"这个参数。使用了转置,就无需设置keepdims为 True。
为什么必须设置keepdims=True?
np.max 和 np.sum 函数中的 keepdims 参数用于控制结果数组的维度。
- keepdims=True, 运算结果会保持与输入数组相同的维度,仅在运算轴上的维度大小变为 1;
- keepdims=False(默认值),运算结果会去掉运算轴对应的维度。
假设输入的二维数组 x 如下:
x = np.array([[1, 2, 3],
[4, 5, 6]])
在不使用转置,直接使用 axis=1 按行操作时,若不使用 keepdims=True, np.max(x, axis=1) 结果形状为 (2,),而 x 形状为 (2, 3),从右向左比较维度,(2,) 无法广播到 (2, 3),会导致维度不匹配错误。所以需要 keepdims=True 让结果形状为 (2, 1),才能正确广播。