码迷,mamicode.com
首页 > 其他好文 > 详细

Log-Sum-Exp Trick to Prevent Numerical Underflow

时间:2015-03-15 23:36:10      阅读:561      评论:0      收藏:0      [点我收藏+]

标签:

 

引自: http://wittawat.com/log-sum_exp_underflow.html

 

Multiplying a series of terms p1p2?pn where 0pi1 can easily result in a numerical underflow. This is especially the case when dealing with probabilistic models which involve such multiplication all the time. One solution commonly used is to work with the log of probabilities instead:

logp1?pn=ilogpi,

which turns multiplication into a summation. Since a summation does not decrease the magnitude of the result, the underflow problem can be avoided.

Unfortunately, this little trick alone does not work when we have a sum of products of probabilities as in the case of, for example, the backward algorithm used in HMM:

βk(zk)=zk+βk+1(zk+1)p(xk+1 | zk+1)p(zk+1 | zk).

The exact meaning of each term is irrelevant. What is important here is that as we successively apply this recurrence relation (i.e., as k gets lower), βk(zk) will underflow. The solution here is the same as before. That is, we work with logβk(zk) instead. So, by taking the log on both sides as well as putting explog in the sum, we have:

logβk(zk)=logzk+exp logβk+1(zk+1)p(xk+1 | zk+1)p(zk+1 | zk)

               →logiexpai.

The reason to apply explog on the RHS is to make the log version of βk+1 so the recurrence relation can be used. We have defined ai which absorbs the log term on the RHS. Note that typically ai?0. So we still have the underflow when calculating expai. The remedy this time is to define

b=maxiai,  ai = logβk+1(zk+1)p(xk+1 | zk+1)p(zk+1 | zk)

and calculate logexp(b)iexp(aib) instead.

logiexpai=logexp(b)iexp(aib)=b+logiexp(aib)

Since b<0 (因为 ai = logβk+1(zk+1)p(xk+1 | zk+1)p(zk+1 | zk))aib is actually positive. So, underflow does not occur when computing exp(aib). We have avoided the underflow problem by using the RHS of the last line.

 

对比下面这段代码:

def logsumexp(A):
    k = max(A)
    return log(sum( exp(i-k) for i in A ))+k

def calc_feat(x, i, l, r):
    return { ("T", l, r): 1, ("E", r, x[i]): 1 }
def calc_e(x, i, l, r, w, e_prob):
    if (i, l, r) not in e_prob:
        e_prob[i,l,r] = dot(calc_feat(x, i, l, r), w)
    return e_prob[i,l,r]

def calc_f(x, i, l, w, e, f):   #### forward
    if (i, l) not in f:
        if i == 0:
            f[i,0] = 0
        else:
            prev_states = (range(1, len(tagids)) if i != 1 else [0])
            f[i,l] = logsumexp([
                calc_f(x, i-1, k, w, e, f) + calc_e(x, i, k, l, w, e)
                    for k in prev_states])
    return f[i,l]   # 重复利用log值

 

Soft-Max Function

Just a side note, logiexpai (分母)is called a soft max function because

logiexpaimaxiai.

The approximation error tends to get larger as the magnitude of ai gets smaller, however.

Source: (ML 14.10) Underflow and the log-sum-exp trick by mathematicalmonk

Log-Sum-Exp Trick to Prevent Numerical Underflow

标签:

原文地址:http://www.cnblogs.com/Dminer/p/4340716.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!