numpy代码在REPL中有效,脚本显示类型错误

时间:2018-10-11 14:48:04

标签: python-3.x numpy

将此代码复制并粘贴到python3 REPL中即可,但是当我将其作为脚本运行时,出现类型错误。

"""Softmax."""

scores = [3.0, 1.0, 0.2]

import numpy as np
from math import e

def softmax(x):
    """Compute softmax values for each sets of scores in x."""
    results = []
    x = np.transpose(x)
    for j in range(len(x)):
        exps = [np.exp(s) for s in x[j]]
        _sum = np.sum(np.exp(x[j]))
        softmax = [i / _sum for i in exps]
        results.append(softmax)
    final = np.vstack(results)
    return np.transpose(final)
#    pass  # TODO: Compute and return softmax(x)


print(softmax(scores))

# Plot softmax curves
import matplotlib.pyplot as plt 
x = np.arange(-2.0, 6.0, 0.1)
scores = np.vstack([x, np.ones_like(x), 0.2 * np.ones_like(x)])

plt.plot(x, softmax(scores).T, linewidth=2)
plt.show()

我通过CLI运行脚本的错误如下:

bash$ python3 softmax.py 
Traceback (most recent call last):
  File "softmax.py", line 22, in <module>
    print(softmax(scores))
  File "softmax.py", line 13, in softmax
    exps = [np.exp(s) for s in x[j]]
TypeError: 'numpy.float64' object is not iterable

这种胡言乱语让我非常担心使用此类库在生产环境中运行解释代码,严重不可靠和不确定的行为是IMO完全不可接受的。

1 个答案:

答案 0 :(得分:1)

在脚本顶部,您定义

scores = [3.0, 1.0, 0.2]

这是您第一次致电softmax(scores)时的论点。当转换为numpy数组时,scores是形状为(3,)的一维数组。 您将scores传递给函数,然后通过调用将其转换为numpy数组

    x = np.transpose(x)

但是,它仍然是1-d,形状为(3,)。 transpose函数交换维,但不会将维添加到一维数组中。实际上,transpose应用于一维数组时是“无操作”。

然后,在随后的循环中,x[j]是类型为numpy.float64的标量,因此写[np.exp(s) for s in x[j]]毫无意义。 x[j]是一个标量,而不是一个序列,因此您无法对其进行迭代。

在脚本的底部,将scores重新定义为

x = np.arange(-2.0, 6.0, 0.1)
scores = np.vstack([x, np.ones_like(x), 0.2 * np.ones_like(x)])

现在scores是2维数组(scores.shape是(3,80)),因此调用softmax(scores)时不会出错。