【问题标题】:How is this Python function read?这个 Python 函数是如何读取的?
【发布时间】:2018-10-31 21:44:10
【问题描述】:

维基百科有以下softmax 的示例代码。

>>> import numpy as np
>>> z = [1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0]
>>> softmax = lambda x : np.exp(x)/np.sum(np.exp(x))
>>> softmax(z)
array([0.02364054, 0.06426166, 0.1746813 , 0.474833  , 0.02364054 , 0.06426166, 0.1746813 ])

当我运行它时,它运行成功。我不明白如何阅读lambda 函数。尤其是参数x如何引用分子中的一个数组元素,并跨越分母中的所有元素?

[注:The question 这个问题大概重复了大约lambdas。这个问题不一定是关于lambda。它是关于如何阅读np 约定的。 @Paul Panzer 和 @Mihai Alexandru-Ionut 的答案都回答了我的问题。太糟糕了,我无法在回答问题时同时检查两者。

确认我理解他们的回答(并澄清我的问题是关于什么的):

  • x 是整个数组(应该是因为数组作为参数传递)。
  • np.exp(x) 返回每​​个元素 x[i] 替换为 np.exp(x[i]) 的数组。调用这个新数组x_new
  • x_new/np.sum(x_new)x_new 的每个元素除以x_new 的总和。

]

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    三句话。

    示例中lambda 的使用实际上是不好的风格,参见。本段来自Python style guide

    始终使用 def 语句而不是赋值语句 将 lambda 表达式直接绑定到标识符。

    是的:

    def f(x): 返回 2*x

    没有:

    f = λx: 2*x

    第一种形式表示生成的函数对象的名称是 特别是“f”而不是通用的“”。这更 通常对回溯和字符串表示很有用。使用 赋值语句消除了 lambda 的唯一好处 表达式可以通过显式的 def 语句提供(即它可以 嵌入到更大的表达式中)

    重新内容。你看到的是数组算术。 np.exp 是一个 numpy ufunc,它按元素操作,因此它将返回一个与其参数形状相同的数组。 np.sum 是一个归约函数,当使用数组作为其唯一参数调用时,它将返回一个标量。 / 运算符被二进制ufunc 重载;像 np.exp 一样,它按元素运行。此外,它还进行广播:在这种情况下,标量分母将与数组分子的每个元素配对,从而形成一个数组。

    最后:Here 是如何实现softmax properly

    【讨论】:

    • 当我使用def 定义函数时:def fsoftmax(x): np.exp(x)/np.sum(np.exp(x)) 然后print(fsoftmax(z)) 我得到None 而不是向量。这是为什么呢?
    • @RussAbbott,你必须使用return 声明:def fsoftmax(x): return np.exp(x)/np.sum(np.exp(x))
    • 因为标准函数必须返回结果,所以使用 return 语句 return np.exp(x)/np.sum(np.exp(x))。 lambda 不需要 return 语句。见stackoverflow.com/questions/37024343/…
    • 好的。有道理。
    【解决方案2】:

    lambda 表达式类似于anonymous function。在这种情况下,行

    softmax = lambda x : np.exp(x)/np.sum(np.exp(x))
    

    等价于

    def softmax(x):
        return np.exp(x)/np.sum(np.exp(x))
    

    【讨论】:

    • 查看我对@Paul Panzer 回答的评论。
    • 请阅读我的回答,如果你的函数没有返回语句,你会得到 None 作为结果...
    【解决方案3】:

    我不明白如何阅读 lambda 函数。

    lambda 函数是一个匿名函数,不绑定名称

    特别是,参数x如何引用数组中的元素 分子和跨度分母中的所有元素?

    不,参数x 不是指数组元素,而是指整个数组。 np.exp(x) 方法也返回一个新数组。

    通过写入np.exp(x)/np.sum(np.exp(x)),由np.exp(x)产生的数组将被划分为sum,这意味着数组中的每个项目都将被划分为该总和。

    【讨论】:

    • 查看我对@Paul Panzer 回答的评论。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-20
    • 1970-01-01
    • 1970-01-01
    • 2021-10-31
    • 1970-01-01
    • 1970-01-01
    • 2018-11-24
    相关资源
    最近更新 更多