本記事では、指数関数の和の対数を取る際に生じるオーバフローを避ける一つの方法である『logsumexp法』を説明します。
また、後半ではNumpyとPyTorchによるlogsumexpの実装れいを示します。
logsumexp法とは
以下のような対数指数関数の和を計算するとき、頻繁にoverflow問題に悩まされます。
$$\log \left(\sum_{i} e^{a_{i}} \right)$$
この計算のオーバフローを避ける方法の一つが『logsumexp法』です。
具体的には、以下の式変形を行い、途中で大きな数が出てこないようにします。
logsumexp法の式変形
logsumexp法の実装例
ここからは、Numpy(scipyを経由)とPyTorchによるlogsumexp法の実装例を示します。
scipyによるlogsumexp法の実装例
log-sum-exp法は、scipyに実装されおり、以下のように使用できます。
import numpy as np
from scipy.special import logsumexp
a = np.arange(1000)
print('logsumexpを使用せず計算:', np.log(np.sum(np.exp(a))))
print('logsumexpを使用して計算:', logsumexp(a))
<output>
logsumexpを使用せず計算: inf
logsumexpを使用して計算: 999.4586751453871
このように、logsumexp法を使用することで、オーバーフローを避けることができます!
詳しい使い方は、公式ドキュメント(scipy.special.logsumexp)を参考にしてください。
Pytorchによるlogsumexp法の実装例
PyTorchでも簡単に実装することができます。
具体例を以下に示します。
import torch
# floatにする必要あり
a = torch.arange(1000).float()
print(torch.logsumexp(a, 0))
<output>
tensor(999.4587)
scipyと異なり、第二引数に次元(dim
)を設定する必要があることに注意してください。
まとめ
本記事では、指数関数の対数を取る際に生じるオーバーフローを避ける方法の一つであるlogsumexp法を紹介しました。
scipyを利用すれば、誰でも簡単に実装できます!
Pythonを学習するのに効率的なサービスを紹介していきます。
まず最初におすすめするのは、Udemyです。
Udemyは、Pythonに特化した授業がたくさんあり、どの授業も良質です。
また、セール中は1500円定義で利用することができ、コスパも最強です。
下記の記事では、実際に私が15個以上の講義を受講して特におすすめだった講義を紹介しています。
他のPythonに特化したオンライン・オフラインスクールも下記の記事でまとめています。
自分の学習スタイルに合わせて最適なものを選びましょう。
また、私がPythonを学ぶ際に使用した本を全て暴露しているので参考にしてください。