Python:定义softmax函数

时间:2017-04-05 03:49:53

标签: python numpy softmax

import numpy as np

def softmax(x):
    row_num = x.shape[0]
    col_num = x.shape[1]
    for m in row_num:
        for n in col_num:
            new_x[m,n] = np.exp(x[m,n])/sum(x[:,n])

    return new_x

logits = [1.0, 2.0, 3.0]
logits2 = np.array([
    [1, 2, 3, 6],
    [2, 4, 5, 6],
    [3, 8, 7, 6]])

print(softmax(logits1))
print(softmax(logits2))

上面是softmax的函数(它用于将logits转换为概率)

我想获得如下所示的解决方案:

[ 0.09003057  0.24472847  0.66524096]

[
    [ 0.09003057  0.00242826  0.01587624  0.33333333]
    [ 0.24472847  0.01794253  0.11731043  0.33333333]
    [ 0.66524096  0.97962921  0.86681333  0.33333333]
]

但是,错误显示“'int'对象不可迭代”。 另外,我希望能够以更低的复杂度看到更有效的代码。

4 个答案:

答案 0 :(得分:2)

这将完成这项工作:

logits = np.array([1.0, 2.0, 3.0])
logits2 = np.array([
    [1, 2, 3, 6],
    [2, 4, 5, 6],
    [3, 8, 7, 6]])
def softmax(x):
    r=np.exp(x - np.max(x))
    return r/r.sum(axis=0)

您收到错误

  

“'int'对象不可迭代”

因为row_num(类似地col_num)是一个数字,所以你不能迭代它。您需要添加range(即for m in range(row_num))。

还有其他问题。例如,x.shape[1]未必定义(它未定义为logits),因此它也会抛出错误。 new_x也没有定义。

答案 1 :(得分:1)

最有效的代码应该是:

import numpy as np
def softmax(x):
    return np.exp(x) / np.sum(np.exp(x), axis=0)

答案 2 :(得分:1)

修改即可。从版本1.2.0开始,scipy包含softmax作为特殊功能:

https://scipy.github.io/devdocs/generated/scipy.special.softmax.html

通常,最好使用向量化实现而不是依赖for循环。你可以利用numpy的broadcasting来做到这一点。还有许多其他问题拥有这种功能的正确实现(例如:herehere)。

为了将答案与问题相关联,我将粘贴在任意轴上操作的一般softmax函数,包括棘手的最大减法位。我还写了一篇关于它的更详细的blog post

def softmax(X, theta = 1.0, axis = None):
    """
    Compute the softmax of each element along an axis of X.

    Parameters
    ----------
    X: ND-Array. Probably should be floats. 
    theta (optional): float parameter, used as a multiplier
        prior to exponentiation. Default = 1.0
    axis (optional): axis to compute values along. Default is the 
        first non-singleton axis.

    Returns an array the same size as X. The result will sum to 1
    along the specified axis.
    """

    # make X at least 2d
    y = np.atleast_2d(X)

    # find axis
    if axis is None:
        axis = next(j[0] for j in enumerate(y.shape) if j[1] > 1)

    # multiply y against the theta parameter, 
    y = y * float(theta)

    # subtract the max for numerical stability
    y = y - np.expand_dims(np.max(y, axis = axis), axis)

    # exponentiate y
    y = np.exp(y)

    # take the sum along the specified axis
    ax_sum = np.expand_dims(np.sum(y, axis = axis), axis)

    # finally: divide elementwise
    p = y / ax_sum

    # flatten if X was 1D
    if len(X.shape) == 1: p = p.flatten()

    return p

答案 3 :(得分:0)

我在numpy模块中实现softmax函数是这样的:

import numpy as np
def softmax(self,x,axis=0):    
    ex = np.exp(x - np.max(x,axis=axis,keepdims=True))
    return ex / np.sum(ex,axis=axis,keepdims=True) 
np.softmax = softmax.__get__(np)

然后可以将softmax函数用作典型的numpy内置函数。就像:

output = model(x)  # output.shape : (50000,10)
softmaxed_value = np.softmax(output,axis=1)