Pytorch の交差エントロピー誤差の使い方を教えてください。
例えば、
予測値が [[0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]
教師データのインデックスが [1, 2]の場合、誤差は0になると思いますが、結果は以下の通りです。
Python
1import torch 2 3y = [[0.0, 1.0, 0.0], [0.0, 0.0, 1.0]] 4t = [1, 2] 5y = torch.FloatTensor(y) 6t = torch.tensor(t) 7loss = torch.nn.CrossEntropyLoss() 8loss(y, t) 9 10# 出力結果 11# tensor(0.5514)
また、
予測値が、[[0.2, 0.3, 0.5], [0.1, 0.4, 0.5]]
教師データ[[0.1, 0.2, 0.7], [0.0, 0.4, 0.6]]
のような確率分布での学習の場合でも。 -t*log(y) でよいのでしょうか?
Python
1import torch 2# -t*log(y) 3 4y = [[0.2, 0.3, 0.5], [0.1, 0.4, 0.5]] 5t = [[0.1, 0.2, 0.7], [0.0, 0.4, 0.6]] 6y = torch.FloatTensor(y) 7t = torch.FloatTensor(t) 8(-t * torch.log(y)).mean() 9# 出力結果 10# tensor(0.2782) 11 12y = [[0.2, 0.3, 0.5], [0.1, 0.4, 0.5]] # 教師データと同じ値 13t = [[0.2, 0.3, 0.5], [0.1, 0.4, 0.5]] 14y = torch.FloatTensor(y) 15t = torch.FloatTensor(t) 16(-t * torch.log(y)).mean() 17# 出力結果 18# tensor(0.3288)
> 予測値が [[0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]
教師データのインデックスが [1, 2]の場合、誤差は0になる
https://qiita.com/ground0state/items/8933f9ef54d6cd005a69
の「PyTorchのCrossEntropyLoss」に書かれてるように、「torch.nn.CrossEntropyLoss()」は予測値をソフトマックス処理するので、そうはなりません
> # 出力結果
# tensor(0.5514)
import numpy as np
y = [0, 1, 0]
print(-1 * y[1] + np.log(np.exp(y).sum()))
を計算したら「0.5514」になりますので、ご確認ください
y = [0, 10, 0]
y = [0, 100, 0]
の場合も、計算してみてください
> 確率分布での学習の場合でも。 -t*log(y) でよいのでしょうか?
「torch.nn.CrossEntropyLoss()」での計算のやり方に合わせたら、という意味なら、
y = [[0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]
t = [[0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]
の場合の計算結果が「0.5514」になるはずですが、質問に掲載のコードではそうなりません
理由は二つあります
・前のコメントで指摘したように「torch.nn.CrossEntropyLoss()」は予測値をソフトマックス処理する
・一つのサンプルでの複数の結果(この例では三つ)は合計する
たぶん、こんな感じ
(-t * torch.log(y)).mean()
↓ 変更
torch.mean(torch.sum(-t * torch.t(torch.t(y) - torch.log(torch.sum(torch.exp(y), dim=1))), dim=1))
「torch.nn.CrossEntropyLoss()」での計算のやり方(予測値をソフトマックス処理)ではなく、一般的な交差エントロピーの定義の場合ですが、
https://qiita.com/ground0state/items/8933f9ef54d6cd005a69
の「Cross Entropy = 交差エントロピーの定義」に書かれてるように、「y = t」の場合は「カルバック・ライブラー情報量」が「0」になり、それは下記の二つの計算値の合計です
torch.mean(torch.sum(t * torch.log(t), dim=1))
torch.mean(torch.sum(-t * torch.log(y), dim=1))
前者は「y」に無関係なので計算を省略し、後者の「交差エントロピー」のみ計算して「y」を評価します
実際に下記を計算すると、「カルバック・ライブラー情報量」は「0」になりますが、「交差エントロピー」は「0」にならないことが分かります
y = [[0.2, 0.3, 0.5], [0.1, 0.4, 0.5]]
t = [[0.2, 0.3, 0.5], [0.1, 0.4, 0.5]]
y = torch.FloatTensor(y)
t = torch.FloatTensor(t)
# カルバック・ライブラー情報量
torch.mean(torch.sum(t * torch.log(t), dim=1)) + torch.mean(torch.sum(-t * torch.log(y), dim=1))
# 交差エントロピー
torch.mean(torch.sum(-t * torch.log(y), dim=1))
つまり、「t」が0, 1ではなく確率分布の場合は、「y = t」の時に「(ソフトマックス処理無しでも)交差エントロピー」は「0」になりません
(最小値になります)
詳しく説明してくださり、ありがとうございます。カルバック・ライブラー情報量についても大変参考になりました。
回答1件
あなたの回答
tips
プレビュー