首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在使用numpy.random.multinomial时避免值错误?

如何在使用numpy.random.multinomial时避免值错误?
EN

Stack Overflow用户
提问于 2014-04-24 00:19:36
回答 3查看 6.8K关注 0票数 7

当我使用这个随机生成器:numpy.random.multinomial时,我总是得到:

代码语言:javascript
复制
ValueError: sum(pvals[:-1]) > 1.0

我总是传递这个softmax函数的输出:

代码语言:javascript
复制
def softmax(w, t = 1.0):
    e = numpy.exp(numpy.array(w) / t)
    dist = e / np.sum(e)
    return dist

除了得到这个错误之外,我还为参数(pvals)添加了以下内容:

代码语言:javascript
复制
while numpy.sum(pvals) > 1:
    pvals /= (1+1e-5)

但这并没有解决问题。确保我避免这个错误的正确方法是什么?

编辑:下面是包含以下代码的函数

代码语言:javascript
复制
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])
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-04-07 02:43:40

我在语言建模工作中也遇到了这个问题。

这个问题的根源来自于numpy的隐式数据转换:我sorfmax()的输出是float32类型,但是numpy.random.multinomial()会隐式地将pval转换成float64类型。这种数据类型转换会导致pval.sum()超过1.0,有时是由于数值舍入。

此问题已被识别并在这里上发布

票数 8
EN

Stack Overflow用户

发布于 2016-01-24 16:58:55

很少有人注意到:通过从值中删除logsumexp,可以很容易地获得softmax的健壮版本:

代码语言:javascript
复制
from scipy.misc import logsumexp

def log_softmax(vec):
    return vec - logsumexp(vec)

def softmax(vec):
    return np.exp(log_softmax(vec))

只要检查一下:

代码语言:javascript
复制
print(softmax(np.array([1.0, 0.0, -1.0, 1.1])))

很简单,不是吗?

票数 2
EN

Stack Overflow用户

发布于 2014-04-24 17:29:36

我所使用的softmax实现对于我使用它的值来说还不够稳定。因此,有时输出的和大于1 (例如,1.0000024...)。

这种情况应该由while循环处理。但是有时输出包含NaNs,在这种情况下,循环永远不会被触发,并且错误仍然存在。

而且,如果numpy.random.multinomial看到一个NaN,它不会引发错误。

以下是我现在正在使用的东西:

代码语言:javascript
复制
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...
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23257587

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档