🎵

32bit intと32bit floatの情報量は同じか?

2024/02/16に公開

結論から言うと、一般には違います。さらには、みなさんの予想に反して32bit floatのほうが情報量が大きくなることもあります。どういうことなのでしょうか。


「32bit intと32bit floatの情報量が同じか否か」が巷で話題となっているようです。
ここでは、情報理論における「情報量」の定義に立ち返って、この問について考えてみましょう[1]

変数がもつ情報量

「情報量」とは、一体どのようなものだったでしょうか。「情報量」という概念は情報理論におけるものであり、これは確率の概念に基づいて定義されています。「ある離散確率変数Xの値がxである(X=x)」という情報の情報量I_X(x)は以下のように定義されます[2]

I_X(x) = - \log_2 P_X(x) \quad \text{[bit]}

ここでP_X(x)は、確率変数Xについての離散確率分布です。

では、「32bit intの情報量」すなわちここでは ある32bit符号付き整数型の変数aの値を観測したときに得られる情報量 は、どのようにして定義され、計算されるのでしょうか?
素朴には、「32bitのビット列なのだから、得られる情報量は32bitではないのか?」と思われるかもしれません。

いま、確率変数Xを「変数a : int32の値をprintなどで出力して表示された整数値」[3]として定義しましょう。このとき情報量I_X(x)は、変数a : int32の値を出力したら整数xが表示されたときに得られる情報量を表すことになります。
さらに、表示される値xに依らず確率変数の確率分布P_Xのみから定義される情報量もあります。これは平均情報量(エントロピー) と呼ばれ、具体的な出力結果に依らない その確率変数自体・そのプログラム変数自体の情報量 と言えるでしょう。平均情報量H(X)は以下で定義されます[2:1][4]

H(X) = - \sum_x P_X(x) \log_2 P_X(x)

いま、確率分布P_X(x)が、どんなxに対しても一定の確率だったとしましょう。このような分布は一様分布と呼ばれます[5]。このときの情報量I_X(x)は、確かにどんなxのときも32\ \text{[bit]}となり、平均情報量H(X)32\ \text{[bit]}です。

しかしこれは Xの確率分布として一様分布を仮定したから に他なりません。例えば確率分布として他に、正の値しか格納されない32bit int型変数、すなわちa >= 0に常に(かつ一様に)なり、一方でa < 0となる確率が0の分布

P_X(a) = \begin{cases} 2^{-31} & (a \ge 0) \\ 0 & (a < 0) \end{cases}

が考えられます。このとき、この確率変数の平均情報量すなわち プログラム変数a : int32の情報量H(X)は、計算すると31 bit となります。これは、変数aが実際には31 bitの情報量しか持っていないということを意味しています。

一般に、平均情報量H(X)は必ず0以上となり、さらに上限として、H(X)は必ず\log_2 N以下の値を取ります。ここでNは確率変数Xの取りうるパターンの総数です。例えば32bit intの場合N=2^{32}なので、H(X)は一般に、Xの確率分布に応じて以下の範囲で変化します。

0 \le H(X) \le 32 \quad \text{[bit]}

プログラムの変数は、その使われ方によって妥当な分布の仮定は異なります。
もしそのint型変数が例えばチェックサムやハッシュ値などであれば、一様分布を仮定するのが妥当でしょう。しかしそのような特殊な場合でなければ、一般に一様分布を仮定することはできないはずです。例えば通常のサービスにおけるユーザーの実年齢であればおそらく、負の値を取る確率は0で、その分布は80辺りを境に減衰する形になっているでしょう。このような場合、年齢変数の持つ情報量は明らかに32 bitよりもはるかに小さくなります。

まとめると、

  • 32bit int型変数の情報量は、その変数が保持しうる値(データ)の確率分布に依存して変化する
  • 32bit int型変数が表現可能な最大の情報量は確かに32bit
  • 型の持つ情報量が32bitで最大となるのは、その変数の確率分布が一様分布である場合(そのように仮定できる場合)であり、かつそのときに限る[6]

同様の議論から、32bit floatについても同様のことが言えます[7]

複数の(符号化方式としての)型どうしの情報量の比較

ここまでの話では、単一の型の情報量に着目してきました。しかし、ここまでの話は型自体の情報量というよりも変数の情報量では、というツッコミが考えられ、若干ミスリーディングな所があります。
そもそも一番最初の話では、int型とfloat型の情報量の大小について言及がされていたのでした。何を隠そう、ここまでの話だけでは、例え仮定する分布を固定したところで、型の間で情報量を比較するということができないのです。そこでここからは、「符号化の方法としての型」ごとの情報量の大小関係についても考えてみましょう。

ある情報があって、これをデータ化したいとしましょう。
例えば音楽という情報であれば、これを.wavに保存する場合、現実世界の音の振幅は連続的であるため、量子化という過程を経ることでビット列へと符号化されるのでした。
(ここでは量子化の詳しい話は省略します。標本化についても省略します。他の記事をあたってください。)
さらに、量子化において振幅を整数で符号化する方法と浮動小数点数により符号化する方法の2種類がよく知られているのでした。

一般に、ある情報を複数の符号化方式(型)で表現するという状況では、複数の型について、それぞれで同じ情報を符号化したときの情報量を比較する、ということが可能になってきます。

音楽を32bit intで量子化する場合と32bit floatで量子化する場合では、これも直前の議論と同様、これは音楽の音の振幅がとる確率分布によって符号化後の情報量が変わってきます。このことを利用して、逆にこれらの型の間の情報量の大小関係を恣意的に満たすような確率分布を作ることもできます。

例えば、(32bit floatの情報量) > (32bit intの情報量)となる分布を考えてみましょう。
ここで量子化前の連続確率分布P_X(x)として、振幅(実数値)Xの大きさのオーダーが2^{-127}及び2^{127}となる所の周辺に分布の山が配置されており、そこ以外では確率0となるようなものを考えます。これはつまり、極端に大きな音と極端に小さな音が両方出現しうるような音声を扱おうとしている、ということです[8]。具体的には、例えば次の式で与えられるような分布を考えます。

P_X(x) = \begin{cases} a & (|x| < 2^{-126}) \\ 0 & (2^{-126} < |x| < 2^{126}) \\ b & (2^{126} < |x| < 2^{127}) \\ 0 & (2^{127} < |x|) \end{cases}

ここでa, bは適当な定数です(ただしP_Xが確率分布となる、つまり全体を積分したら1となるという制約の下で)。

このような音声を32bit intで符号化した場合、振幅が-2^{31}から+2^{31}-1の範囲しか符号化できませんから、小さな音は0へ、大きな音は\{-2^{31}, +2^{31}-1\}の2値へと潰れてしまい、結果として3パターンの値しか取り得ないことになります[9]。仮にこの3パターンの値が均等な確率で出現するとして(そのように分布の山の高さa,bを調節して)、32bit intで符号化した場合の、あるサンプルの量子化された振幅値の情報量を考えてみましょう。
量子化された振幅の確率変数をX_\mathrm{int}とすると、この確率変数の情報量は

H(X_\mathrm{int}) = \log_2 3 \fallingdotseq 1.58 \quad \text{[bit]}

となり、32 bitよりも遥かに小さな情報量となります。一方で、32bit floatの場合は2^{-127}2^{127}のオーダーの値に対しても一定の精度で符号化してくれます。その結果、3パターンの値へと潰れることはなく、(floatで量子化した振幅の確率変数をX_\mathrm{float}と書くと) 情報量H(X_\mathrm{float})はintの場合よりも大きくなります。すなわち、H(X_\mathrm{float}) > H(X_\mathrm{int}) \fallingdotseq 1.58 \ \text{bit}です[10]

また、音声処理では大きすぎる音が最大値に潰れてしまうことがないよう正規化を行うことがあります。例えば、振幅が-1から+1の範囲のみとなるようにしたり、あるいは振幅の分散が1となるようスケーリングするのもよいでしょう。いずれにせよ、先程のような分布ではスケーリングを行っても、intによる符号化の場合は小さい方の音と大きい方の音の両方を潰さないようにすることは不可能であり、floatのほうが情報量が大きくなることでしょう(適切なスケーリングを行ったとしてもfloatのほうが情報量が多くなるような分布が存在する)。

さらに、先程「変数の確率分布が一様分布である場合は型の持つ情報量が最大となる」と書きました。しかし、ある同じ情報X(確率分布P_X(x)をもつ)を複数の32bitの型で符号化する場合、確率分布P_X(x)を一様分布として仮定しても符号化後の情報量が最大になる(32bitになる)わけではないことは注意が必要です。
そもそも符号化元の情報Xが(実数だとして)-2^{-31}2^{31}-1の一様分布のように範囲がぴったり型の表現可能な範囲と一致していなければ、無駄な範囲を符号化したり飽和して潰れたりして32bitよりも小さくなります。さらに(十分広い)連続一様分布をfloatで符号化すれば、一様にもかかわらず0付近を重点的に符号化するので、その分だけ符号化後の確率分布P_{X_\mathrm{float}}は一様ではなく偏りのある離散確率分布となり、これも32bitよりも小さくなるわけです。

あとちなみに、(符号化前の情報Xが実数だとして、)符号化後の型(が表現可能な値の集合)をT、符号化関数f_T : \mathbb{R} \rightarrow Tとしたとき、H(X_T)H(f_T(X))と書けます。先程の例ではTがintだったりfloatだったりしたわけです。ようは符号化前の確率変数Xを符号化関数で写して得られる確率変数X_T = f_T(X)についてのエントロピーなわけですね。それはそうか。

まとめ

  • 32bit int、32bit floatの情報量は、それらが表現するデータの確率分布をどのように仮定するかによって変化する
  • 一般にはこれらの情報量は0bit以上32bit以下となる
  • ある情報(情報源)を32bit intと32bit floatの2種類の型(符号化方式)で符号化した場合、符号化されたデータの情報量を比較すると、一般にその大小関係は情報源の分布に依存し、同じ・どちらが大きい・小さいのように言い切ることはできない
    • 分布を固定してはじめて大小関係を議論できる
    • 分布に合わせた符号化(型)を選ぶことで、情報を効率的に符号化できる(情報量を最大化できる)
      • これは「用途に合わせた型を選ぼう」というベストプラクティスの理由付けにもなるはず

余談ですが、例えば想定される状況として、オーディオマニアの方が「intよりfloatのほうが情報量が多くて〜」と言った場合、これは先程のintとfloatの符号化方式としての比較の意味で「情報量」という言葉を使ったのだ、と解釈することができます。この意味では、やはり振幅の分布の仮定に依るので一概には言えませんが、「確かにfloatによる符号のほうが情報量が多くなるような分布がありうる」という意味で間違っていると言い切ることも簡単にはできないでしょう。
もっとも普通の音楽の分布を想定した場合に、本当にfloatのほうが情報量が多くなるかは確かに怪しいです。しかし、例え普通の分布を仮定する限りfloatもintも大差なかったとしても、その人はひょっとしたら振幅分布がかなり普通ではない音楽を嗜んでいるコアなオーディオマニアの可能性があります。

振幅分布異常音楽に次に魅入ることになるのは、紛れもない貴方自身かもしれません……

https://x.com/lilbeshramko/status/1818259307886166160

音割れ 本来は良くない

脚注
  1. 「32bit int/floatの情報量」というフレーズに対して、本記事で提示する2つの解釈以外にも情報理論的な解釈がありうると考える方がいらっしゃいましたら、是非コメントください。 ↩︎

  2. 19.6 平均情報量 ↩︎ ↩︎

  3. ここでの「変数」は、数学ではなくプログラムにおける意味での変数 ↩︎

  4. P_X(x)=0のとき\log_2の引数が0となり0 \times -\inftyの不定形が出現しますが、この場合は0 \times -\infty = 0とみなして計算します ↩︎

  5. 例えば、サイコロの出る目は各確率が\frac{1}{6}の一様分布です ↩︎

  6. あと、確率分布として一様分布を仮定するのは、その変数がどういう使われ方をするのかが一切仮定できない場合の、ある種「無情報事前分布」的な見方をするという意味付けもできるかもしれません。32bitより小さくなるのはその分の情報量だけその変数(ビットパターン)がどういう使われ方をするのかの知識を事前に知っているから、と言うこともできるかもしれない。ただその場合もそういう仮定を置いてるという但し書きがない限り正しくないと思う ↩︎

  7. IEEE 754より、取りうる浮動小数点数のパターンの数N2^{32}よりも小さくなるはずで、そこだけ注意が必要です ↩︎

  8. 話を簡単にするために、この2種類の音が重なり合う場合はないものとします。 ↩︎

  9. 量子化元の振幅(実数)を、そこと最も近い符号の点へと移すような符号化を考えています。例えばintへの符号化は四捨五入など。 ↩︎

  10. H(X_\mathrm{float})の具体的な値の計算は少し難しそうです。誰か適当な分布作って計算に成功したら教えてください(他力本願) ↩︎

Discussion