KL ダイバージェンス (カルバック ライブラー ダイバージェンス、KL ダイバージェンスと呼ばれる) は、相対エントロピー (Relative Entropy) とも呼ばれる 2 つの確率分布間の差を測定する指標です。KL ダイバージェンスは、情報理論、統計、機械学習、データ サイエンスなどの分野で広く使用されています。
KL ダイバージェンスは、より良い分布 �Q を使用するために必要な追加ビット数 �P に対する、確率分布 �P で情報を捕捉するために必要な追加ビット数の期待値を測定します。�P と �Q の確率分布が同じである場合、KL 発散は 0 であり、2 つの分布が同一であることを示します。�P と �Q の確率分布が異なる場合、KL 発散は正となり、差異を示します。 2 つの分布の間の次数。
KL ダイバージェンスの数式は次のとおりです。
ここで、P(x) と Q(x) は、それぞれ確率分布 P と Q におけるイベント x の確率を示します。
KL 発散は対称性を満たさない、つまり DKL (P∥Q) ≠ DKL (Q∥P) であることに注意してください。したがって、実際のアプリケーションでは、特定の問題に応じてどの分布を基準分布 Q として使用するかを決定する必要があります。
機械学習では、KL 発散は、生成モデルの損失関数の一部として KL 発散を使用したり、クラスタリングおよび分類問題で類似性の尺度として使用したりするなど、2 つの確率分布間の差異の程度を測定するためによく使用されます。
PyTorch では、 torch.nn.functional.kl_div
関数を使用して KL 発散を計算できます。具体的な実装方法は以下の通りです。
PyTorch でのテンソル表現が sum で ある 2 つの確率分布 P とp_tensor
Q が あると仮定するq_tensor
と、KL 発散は次のコードを使用して計算できます。
import torch.nn.functional as F
kl_div = F.kl_div(q_tensor.log(), p_tensor, reduction='batchmean')
このうち、q_tensor.log()
確率分布Qの各要素の対数をとる手段、p_tensor
確率分布Pのテンソル表現をPyTorchで表現する手段、reduction='batchmean'
各サンプルのKL発散度を平均してバッチ全体のKL発散度を求める手段などがあります。
KL 発散の計算では、P と Q の要素が両方とも正の数である必要があるため、計算前に 2 つの確率分布を正規化し、それらの要素の合計が 1 になるようにする必要があることに注意してください。これは次のコードで実現できます。
p_tensor = F.softmax(p_tensor, dim=-1)
q_tensor = F.softmax(q_tensor, dim=-1)
このうち、F.softmax
この関数は、出力の各要素が 0 から 1 の間にあり、要素の合計が 1 になるように、指定された次元の入力テンソルに対してソフトマックス正規化演算を実行することを意味します。
最終的に得られるのは、 kl_div
2 つの確率分布 P と Q の間の KL 発散です。
トレーニング中に KL 発散を損失関数として使用するには、それをモデルの一部として損失関数の計算に含めることができます。たとえば、PyTorch では、損失関数をカスタマイズして KL 発散の計算を実現できます。具体的な手順は次のとおりです。
1. カスタム損失関数を定義する
import torch.nn.functional as F
import torch.nn as nn
class KLDivLoss(nn.Module):
def __init__(self):
super(KLDivLoss, self).__init__()
def forward(self, p, q):
p = F.softmax(p, dim=-1)
q = F.softmax(q, dim=-1)
loss = F.kl_div(q.log(), p, reduction='batchmean')
return loss
カスタム損失関数では、最初に確率分布 P と Q が正規化され、次に関数が torch.nn.functional.kl_div
呼び出されて KL 発散が計算され、最後に KL 発散が損失関数の値として返されます。
2. トレーニング中にカスタム損失関数を呼び出す
import torch.optim as optim
# 初始化模型和优化器
model = MyModel()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 初始化自定义损失函数
kl_div_loss = KLDivLoss()
# 训练模型
for epoch in range(num_epochs):
for batch_idx, (data, target) in enumerate(train_loader):
# 前向传播
output = model(data)
# 计算 KL散度损失
kl_loss = kl_div_loss(output, target)
# 计算总损失
total_loss = kl_loss + other_loss
# 反向传播
optimizer.zero_grad()
total_loss.backward()
optimizer.step()
トレーニング中に、カスタム損失関数が呼び出され、 kl_div_loss
KL 発散損失が計算され、それが合計損失に追加されます total_loss
。逆伝播する場合は、単純に合計損失を逆伝播します。
上記の手順を通じて、KL 発散を損失関数として使用して、トレーニング中にモデルを最適化できます。