正規化ベクトルの導関数
ベクトル モジュールの導出: 定義 x ∈ R 1 × d \bm{x}\in \mathbb{R}^{1 \ d 倍} バツ∈R1×d为一个列向量, ∣ ∣ x ∣ ∣ ||\bm{x}|| ∣∣x∣∣为向量的模, x ^ \hat{\bm{x}} バツ^ は、長さ 1 の L2 正規化後のベクトルを表します
∂ ∂ x ( ∣ ∣ x ∣ ∣ ) = ∂ ∂ x x T x = 1 2 2 x T x T x = x T ∣ ∣ x ∣ ∣ = x ^ T \frac{\partial}{\partial \bm{x }}( ||\bm{x}||)=\frac{\partial }{\partial \bm{x}}\sqrt{\bm{x}^T \bm{x}}=\frac{1 }{2}\frac{2\bm{x}^T}{\sqrt{\bm{x}^T \bm{x}}}=\frac{\bm{x}^T}{ ||\ bm{x}||}=\hat{\bm{x}}^T∂x∂ (∣∣x∣ ∣)=∂x∂ バツTx=21 バツTx2xT =∣∣x∣∣バツT =バツ^T
归一化向量求导:
∂ ∂ x ( x ^ ) = ∂ ∂ x ( x ∣ ∣ x ∣ ∣ ) = ∂ ∂ x ( x T 1 ∣ ∣ x ∣ ∣ ) = 1 ∣ ∣ x ∣ ∣ ∂ ∂ x ( x ) + x ∂ ∂ x ( 1 ∣ ∣ x ∣ ∣ ) = 1 ∣ ∣ x ∣ ∣ − x x ^ T ∣ ∣ x ∣ ∣ 2 = ∣ ∣ x ∣ ∣ I − x x ^ T ∣ ∣ x ∣ ∣ 2 = I − x ^ x ^ T ∣ ∣ x ∣ ∣ \frac{\partial}{\partial \bm{x}}(\hat{\bm{x }})=\frac{\partial}{\partial \bm{x}}(\frac{\bm{x}}{ ||\bm{x}||})=\frac{\partial}{\部分 \bm{x}}(\bm{x}^T\frac{1}{ ||\bm{x}||})\\ =\frac{1}{ ||\bm{x}|| }\frac{\partial}{\partial \bm{x}}(\bm{x})+\bm{x}\frac{\partial}{\partial \bm{x}}(\frac{1} { ||\bm{x}||})\\ =\frac{1}{ ||\bm{x}||}-\bm{x}\frac{\hat{\bm{x}}^ T}{||\bm{x}||^2}\\ =\frac{||\bm{x}||I-\bm{x}\hat{\bm{x}}^T}{ ||\bm{x}||^2}\\ =\frac{I-\hat{\bm{x}}\hat{\bm{x}}^T}{||\bm{x}| |} ∂x∂ (バツ^)=∂x∂ (∣∣x∣∣x )=∂x∂ (xT∣∣x∣∣1 )=∣∣x∣∣1 ∂x∂ (x)+バツ∂x∂ (∣∣x∣∣1 )=∣∣x∣∣1 −バツ∣∣x∣∣2バツ^T =∣∣x∣∣2∣∣x∣∣ I−xバツ^T =∣∣x∣∣私−バツ^バツ^T
比較誤差の導関数:
アンカー ベクトルの場合 q q q,对比向量为 { k i } i = 0 K \{k_i\}_{i=0}^K {
ki }i=0K ,其中 k 0 k_0 k0 是正样本向量, { k i } i = 1 K \{k_i\}_{i=1}^K {
ki }i=1K は K 個の負のサンプル ベクトルであり、交差エントロピーに基づく誤差関数は次のとおりです。
L = − log exp ( q T k 0 / τ ) ∑ i = 0 K exp ( q T k i / τ ) L=-\log\frac{\exp(q^Tk_0/\tau)}{\sum_{i=0}^K\exp(q^Tk_i/\tau)} < /a >L=−ロg∑i=0K exp(qTki /τ)exp(qTk0 /τ)
ここで、ロジットは次のように考えることができます。 z = [ q T k 0 / τ , q T k 1 / τ , ⋯ , q T k K / τ ] z=[q ^ Tk_0/\tau,q^Tk_1/\tau,\cdots,q^Tk_K/\tau] と=[qTk0 /τ,qTk1 /τ,⋯、qTkK /τ],这里 τ \tau τ は温度係数であり、相互エントロピー誤差勾配計算ルール (詳細については、参照アドレスを参照してください)。 ∂ L ∂ z i = p i − y i \ frac{\partial L}{\partial z_i}=p_i-y_i
∂zi ∂L =pi −そしてi
その中 p i = exp ( q T k i / τ ) ∑ i = 0 K exp ( q T k i / τ ) p_i=\frac{\exp(q^ Tk_i/\tau)}{\sum_{i=0}^K\exp(q^Tk_i/\tau)} pi =∑i=0K exp(qTki /τ)exp(qTki /τ) は、ソフトマックス正規化後の確率値です。アンカーサンプルの場合 q q q の勾配、計算:
∂ L ∂ q = ∑ i = 0 K ( ∂ L ∂ z i ∂ z i ∂ q ) = ∑ i = 0 K ( p i − y i ) k i / τ \frac{\partial L}{\partial q}=\sum_{i=0}^{K}(\frac{\partial L}{\partial z_i }\frac{\partial z_i}{\partial q})=\sum_{i=0}^{K}(p_i-y_i)k_i/\tau ∂q∂L =i=0∑K (∂zi ∂L ∂q∂zi )=i=0∑K (pi −そしてi )ki /τ
比方向量勾配は次のとおりです。
∂ L ∂ k i = ∂ L ∂ z i ∂ z i ∂ k i = ( p i − y i ) q / τ \frac{\partial L}{\部分 k_i}=\frac{\部分 L}{\部分 z_i}\frac{\部分 z_i}{\部分 k_i}=(p_i-y_i)q/\タウ ∂ki ∂L =∂zi ∂L ∂ki ∂zi =(pi −そしてi )q/τ
温度系数の勾配:
∂ L ∂ τ = ∑ i = 0 K ∂ L ∂ z i ∂ z i ∂ τ = ∑ i = 0 K ( p i − y i ) q T k i ( − 1 / τ 2 ) = ∑ i = 0 K ( y i − p i ) z i / τ \frac{\partial L}{\partial \tau}=\sum_{i=0}^{K}\frac {\partial L}{\partial z_i}\frac{\partial z_i}{\partial \tau}=\sum_{i=0}^K(p_i-y_i)q^Tk_i(-1/\tau^2) =\sum_{i=0}^K(y_i-p_i)z_i/\タウ ∂τ∂L =i=0∑K ∂zi ∂L ∂τ∂zi =i=0∑K (pi −そしてi )qTki (−1/τ2)=i=0∑K (yi −pi )zi /τ
pytorch コードの実装:
import torch
import torch.nn.functional as F
p = torch.tensor([[0.1, 0.2, 0.3],
[0.5, 0.6, 0.8]], requires_grad=True)
k = torch.tensor([[0.4, 0.5, 0.7],
[0.6, 0.8, 0.6],
[0.6, 0.8, 0.6],], requires_grad=True)
tau = torch.tensor(0.01, requires_grad=True)
targets = torch.tensor([0, 0])
class CrossEntropyLoss(torch.autograd.Function):
@staticmethod
def forward(ctx, p, k, tau, targets):
logits = p @ k.T / tau
targets = F.one_hot(targets, num_classes=logits.size(1)).float()
prob = F.softmax(logits, 1)
ctx.save_for_backward(logits, prob, targets, p, k, tau)
logits = F.log_softmax(logits, 1)
loss = -(targets * logits).sum(1).mean()
return loss
@staticmethod
def backward(ctx, grad_output):
logits, prob, targets, p, k, tau = ctx.saved_tensors
grad_p = grad_output * (prob - targets) @ k / tau / targets.size(0)
embed_size = p.size(1)
prob_targets_repeat = (prob - targets).t().repeat(1, embed_size).view(-1,embed_size, p.size(0))
grad_k = grad_output * (prob_targets_repeat * (p.t() / tau).unsqueeze(0)).sum(-1) / targets.size(0)
tau_grad = grad_output * torch.sum((targets - prob) * logits / tau, dim=1).mean()
grad_targets = None
return grad_p, grad_k, tau_grad, grad_targets
loss = CrossEntropyLoss.apply(p, k, tau, targets)
loss.backward()
print(p.grad)
print(k.grad)
print(tau.grad)
出力:
tensor([[ 9.9664, 14.9496, -4.9832],
[10.0000, 15.0000, -5.0000]])
tensor([[-29.9832, -39.9664, -54.9496],
[ 14.9916, 19.9832, 27.4748],
[ 14.9916, 19.9832, 27.4748]])
tensor(-1249.1605)
pytorch関数の検証:
import torch
import torch.nn.functional as F
p = torch.tensor([[0.1, 0.2, 0.3],
[0.5, 0.6, 0.8]], requires_grad=True)
k = torch.tensor([[0.4, 0.5, 0.7],
[0.6, 0.8, 0.6],
[0.6, 0.8, 0.6],], requires_grad=True)
tau = torch.tensor(0.01, requires_grad=True)
logits = p @ k.T / tau
targets = torch.tensor([0, 0])
loss = F.cross_entropy(logits, targets)
loss.backward()
print(p.grad)
print(k.grad)
print(tau.grad)
出力:
tensor([[ 9.9664, 14.9496, -4.9832],
[10.0000, 15.0000, -5.0000]])
tensor([[-29.9832, -39.9664, -54.9496],
[ 14.9916, 19.9832, 27.4748],
[ 14.9916, 19.9832, 27.4748]])
tensor(-1249.1606)