当我使用这个随机生成器时:numpy.random.multinomial
,我一直得到:
ValueError: sum(pvals[:-1]) > 1.0
我总是传递这个softmax函数的输出:
def softmax(w, t = 1.0):
e = numpy.exp(numpy.array(w) / t)
dist = e / np.sum(e)
return dist
除非我收到此错误,我还为参数(pvals
)添加了此内容:
while numpy.sum(pvals) > 1:
pvals /= (1+1e-5)
但这并没有解决它。确保我避免此错误的正确方法是什么?
编辑:这是包含此代码的函数
def get_MDN_prediction(vec):
coeffs = vec[::3]
means = vec[1::3]
stds = np.log(1+np.exp(vec[2::3]))
stds = np.maximum(stds, min_std)
coe = softmax(coeffs)
while np.sum(coe) > 1-1e-9:
coe /= (1+1e-5)
coeff = unhot(np.random.multinomial(1, coe))
return np.random.normal(means[coeff], stds[coeff])
答案 0 :(得分:3)
我在语言建模工作中也遇到过这个问题。
这个问题的根源来自numpy的隐式数据转换:我的sorfmax()的输出是listwidget_2
类型,但float32
将转换numpy.random.multinomial()
进入pval
类型IMPLICITLY。由于数字舍入,此数据类型转换有时会导致float64
超过1.0。
此问题已被识别并发布here
答案 1 :(得分:2)
很少有人注意到的事情:通过从值中删除logsumexp可以轻松获得softmax的强大版本:
from scipy.misc import logsumexp
def log_softmax(vec):
return vec - logsumexp(vec)
def softmax(vec):
return np.exp(log_softmax(vec))
检查一下:
print(softmax(np.array([1.0, 0.0, -1.0, 1.1])))
简单,不是吗?
答案 2 :(得分:1)
我使用的softmax
实现对于我使用它的值不够稳定。因此,有时输出的总和大于1
(例如1.0000024...
)。
这种情况应该由while循环处理。但有时输出包含NaN,在这种情况下,循环永远不会被触发,并且错误仍然存在。
此外,numpy.random.multinomial
如果看到NaN,则不会引发错误。
以下是我现在正在使用的内容,而不是:
def softmax(vec):
vec -= min(A(vec))
if max(vec) > 700:
a = np.argsort(vec)
aa = np.argsort(a)
vec = vec[a]
i = 0
while max(vec) > 700:
i += 1
vec -= vec[i]
vec = vec[aa]
e = np.exp(vec)
return e/np.sum(e)
def sample_multinomial(w):
"""
Sample multinomial distribution with parameters given by softmax of w
Returns an int
"""
p = softmax(w)
x = np.random.uniform(0,1)
for i,v in enumerate(np.cumsum(p)):
if x < v: return i
return len(p)-1 # shouldn't happen...
答案 3 :(得分:0)
我知道这个问题很旧,但是由于我刚才遇到了同样的问题,在我看来它仍然有效。这是我为它找到的解决方案:
a = np.asarray(a).astype('float64') a = a / np.sum(a) b = np.random.multinomial(1, a, 1)
我把重要的部分加粗了。如果您省略该部分,您提到的问题将不时发生。但是,如果将数组的类型更改为float64,它将永远不会发生。