Python(基本的なこと009: mnist_交差エントロピー_サイコロの目)
■Tensorflowのサンプルとしてmnistを実行してみるの続き
mnistのサンプルの内容の理解にあたって、いくつかよく分からない言葉が出てきた。前回のソフトマックス関数に続き、交差エントロピーについて調べてみる。
交差エントロピーは、下のような関数。
ここでxとyは確率分布。

xとyの確率分布が同じになるとき、交差エントロピーHが最も小さくなるらしい。 機械学習では、yに真の確率、xに推定の確率を入れ、最もHが小さくなる部分を探すということをやるので、yの値を固定して、xを動かしてx-Hのグラフを作ってみた。コードは下の通り。
import math
import numpy as np
import matplotlib.pyplot as mp
num_list = []
result = []
for num in range(1, 100):
x = np.array([num / 100, 1 - (num / 100)])
#y = np.array([0.01, 0.99])
#y = np.array([0.50, 0.50])
y = np.array([0.75, 0.25])
num_list.append(num)
result.append((-y[0] * math.log(x[0])) + (-y[1] * math.log(x[1])))
print(x, ":",result[num-1])
mp.plot(num_list, result, color="red")
mp.grid()
mp.show()
ここで、yは[1/100, 99/100], [1/2, 1/2], [3/4, 1/4]の確率を持つものとし、1-99までの数字に応じて、xを[1/100, 99/100], [2/100, 98/100] ... [99/100, 1/100]となるようしてHの値を求めていった。上から y = [1/100, 99/100], y = [1/2, 1/2], y = [3/4, 1/4]。 それぞれxとyが同じになるとき、Hが最も小さくなる。



これで交差エントロピーの関数の動きのイメージはついた。
次に、交差エントロピーの値について少し見てみる。
上の y = [1/2, 1/2] では、最も小さなHは0.6931だった。この時は要素の数が2(1/2が2つ)だけど、これが増えた場合Hの値はどうなるか。
同じ確率の要素を増やした場合で、最もHが小さくなる(xとyが同じ)ときの値を下のコードで求めた。
x = np.array([1 / 4, 1 / 4, 1 / 4, 1 / 4])
y = np.array([1 / 4, 1 / 4, 1 / 4, 1 / 4])
print("4:", (-y[0] * math.log(x[0])) + (-y[1] * math.log(x[1])) + (-y[2] * math.log(x[2]))+ (-y[3] * math.log(x[3])))
x = np.array([1 / 5, 1 / 5, 1 / 5, 1 / 5, 1 / 5])
y = np.array([1 / 5, 1 / 5, 1 / 5, 1 / 5, 1 / 5])
print("5:", (-y[0] * math.log(x[0])) + (-y[1] * math.log(x[1])) + (-y[2] * math.log(x[2]))+ (-y[3] * math.log(x[3]))+ (-y[4] * math.log(x[4])))
x = np.array([1 / 6, 1 / 6, 1 / 6, 1 / 6, 1 / 6, 1 / 6])
y = np.array([1 / 6, 1 / 6, 1 / 6, 1 / 6, 1 / 6, 1 / 6])
print("6:",(-y[0] * math.log(x[0])) + (-y[1] * math.log(x[1])) + (-y[2] * math.log(x[2]))+ (-y[3] * math.log(x[3]))+ (-y[4] * math.log(x[4]))+ (-y[5] * math.log(x[5])))
結果は、下の通り。要素の数が増えるに従い大きくなった。xとyの確率分布を同じにしても、要素の数が増えるだけでHの値は大きくなってしまうので、別の交差エントロピーと値を比較することには意味がないのではと思う。
4つ: 1.3862943611198906
5つ: 1.6094379124341005
6つ: 1.7917594692280547
最後に、サイコロを投げて出た目から確率分布を出して、真の確率([出た目1, 2, 3, 4, 5, 6] = [1/6, 1/6, 1/6, 1/6, 1/6, 1/6])との交差エントロピーを求めてみた。
randomのライブラリを使って、1-6までの数値をランダムに得る。投げる回数はDICE_COUNT_1TRIALで指定し、それをTRIAL_COUNTの数だけ繰り返す。下のコードでは、36000回ふった数から、出た目(1-6)の確率分布をだし、10トライアル分のデータにする(6列×10行のnumpyデータ)。
なお、tensorflowライブラリのtf.reduce_sum, tf.reduce_meanを使用して、numpyデータをまとめていく。これはmnistのサンプルを動かす部分と同じコード。ここでは、tf.reduce_sumで出た目の y * log(x)を合計し、tf.reduce_meanで10トライアル分のデータの平均を出している(計算するにつれ、6列×10行のデータが、10行のデータ、1つの値のデータと次元が減る)。
import tensorflow as tf
import numpy as np
import random
i = 0
cntList = []
DICE_COUNT_1TRIAL = 36000
TRIAL_COUNT = 10
cnt = [0, 0, 0, 0, 0, 0]
for i in range(0, TRIAL_COUNT):
cnt = [0, 0, 0, 0, 0, 0]
for var in range(0, DICE_COUNT_1TRIAL):
num = random.randint(1, 6)
if num == 1:
cnt[0] = cnt[0] + 1
elif num == 2:
cnt[1] = cnt[1] + 1
elif num == 3:
cnt[2] = cnt[2] + 1
elif num == 4:
cnt[3] = cnt[3] + 1
elif num == 5:
cnt[4] = cnt[4] + 1
elif num == 6:
cnt[5] = cnt[5] + 1
for var in range(0, 6):
if cnt[var] == 0:
cnt[var] = 0.000000000000000000001
cntList.append(cnt)
print(cntList)
cntNp = np.array(cntList, dtype='float32')
print(cntNp / DICE_COUNT_1TRIAL)
y = np.array([1 / 6, 1 / 6, 1 / 6, 1 / 6, 1 / 6, 1 / 6], dtype='float32')
elementwise_product = y * tf.log(cntNp / DICE_COUNT_1TRIAL)
xentropy = -tf.reduce_sum(elementwise_product, reduction_indices=1)
loss = tf.reduce_mean(xentropy)
sess = tf.Session()
result = sess.run(elementwise_product)
print(result)
result_xent = sess.run(xentropy)
print(result_xent)
result_loss = sess.run(loss)
print("Dice throw in a trial:", DICE_COUNT_1TRIAL, " Trial number:", TRIAL_COUNT, " cross-entropy:", result_loss)
結果は下の通り。
投げる回数(DICE_COUNT_1TRIAL) | トライアル(TRIAL_COUNT) | 交差エントロピー |
360 | 10 | 1.7999942 |
3600 | 10 | 1.7925708 |
36000 | 10 | 1.7918148 |
360000 | 10 | 1.7917680 |
3600000 | 10 | 1.7917604 |
360 | 1000 | 1.7986851 |
36000 | 1000 | 1.7918298 |
上のコードで真の確率と推定の確率が同じときは1.7917594と分かったので、この値が最も小さくなる。投げる回数を増やすほど、この値に近づく。直感的には当然のことだけど、交差エントロピーから見ても回数を増やした方が1/6の確率に近づくことが分かる。トライアルの数は平均なので、数を増やすほど安定した値となる。信頼度がますといえばいいのかな。ここでは1000トライアルに増やす意味をあまり感じないけど。
交差エントロピーはひとまずこんなところで。