2017-12-13 5 views
3

私はpytorchを使ってTextGANを "複製"しようとしています。私はpytorchを初めて使っています。私の現在の懸念はL_G(式7ページ3)を複製することであり、ここでは私の現在のコードです:それは作品Pytorchで上限JSD損失を実装する方法は?

class JSDLoss(nn.Module): 

    def __init__(self): 
     super(JSDLoss,self).__init__() 

    def forward(self, batch_size, f_real, f_synt): 
     assert f_real.size()[1] == f_synt.size()[1] 

     f_num_features = f_real.size()[1] 
     identity = autograd.Variable(torch.eye(f_num_features)*0.1, requires_grad=False) 

     if use_cuda: 
      identity = identity.cuda(gpu) 

     f_real_mean = torch.mean(f_real, 0, keepdim=True) 
     f_synt_mean = torch.mean(f_synt, 0, keepdim=True) 

     dev_f_real = f_real - f_real_mean.expand(batch_size,f_num_features) 
     dev_f_synt = f_synt - f_synt_mean.expand(batch_size,f_num_features) 

     f_real_xx = torch.mm(torch.t(dev_f_real), dev_f_real) 
     f_synt_xx = torch.mm(torch.t(dev_f_synt), dev_f_synt) 

     cov_mat_f_real = (f_real_xx/batch_size) - torch.mm(f_real_mean, torch.t(f_real_mean)) + identity 
     cov_mat_f_synt = (f_synt_xx/batch_size) - torch.mm(f_synt_mean, torch.t(f_synt_mean)) + identity 

     cov_mat_f_real_inv = torch.inverse(cov_mat_f_real) 
     cov_mat_f_synt_inv = torch.inverse(cov_mat_f_synt) 

     temp1 = torch.trace(torch.add(torch.mm(cov_mat_f_synt_inv, cov_mat_f_real), torch.mm(cov_mat_f_real_inv, cov_mat_f_synt))) 
     temp1 = temp1.view(1,1) 
     temp2 = torch.mm(torch.mm((f_synt_mean - f_real_mean), (cov_mat_f_synt_inv + cov_mat_f_real_inv)), torch.t(f_synt_mean - f_real_mean)) 
     loss_g = torch.add(temp1, temp2).mean() 

     return loss_g 

。しかし、私はそれがカスタムロスを作成する方法ではないという疑念を持っています。どんな種類の助けでも大歓迎です!事前に感謝:)

答えて

0

これは、あなたがPytorchでカスタム損失を作成する方法ですPytorch

でカスタム損失を作成する方法。最終的には損失関数によって返された値がスカラー値でなければなりません

  • :あなたは、次の要件を満たす必要があります。ベクトル/テンソルではありません。
  • 返される値は、変数でなければなりません。これは、モデルのパラメータを更新するために使用できるようになっています。 を実行する最良の方法は、xとyの両方が渡されることを確認することです。 このようにして、2つの関数も変数になります。
  • あなたはPytorchのソースコードの例として使用することができますいくつかの損失モジュールを見つけることができ__init__forward方法

を定義します。あなたがミニバッチテンソルを渡す場合https://github.com/pytorch/pytorch/blob/master/torch/nn/modules/loss.py

をあなたの損失関数では、サイズがforward関数で計算できるので、forward関数にミニバッチサイズを渡す必要はありません。

loss = YourLoss() 
input = autograd.Variable(torch.randn(3, 5), requires_grad=True) 
target = autograd.Variable(torch.randn(3, 5)) 
output = loss(input, target) 
output.backward() 

loss.backward()は、あなたの中にすべてのパラメータxためdloss/dxを計算します:どのようにあなたがあなたの損失関数を実装した後は、次のように、あなたが例えば、それを使用することができ、カスタム損失に

を使用

ネットワークはrequires_grad=Trueです。これらはすべてパラメータxに対してx.gradに蓄積されます。擬似コードで:

x.grad += dloss/dx 

optimizer.step勾配x.gradを用いxの値を更新します。たとえば、SGDオプティマイザは実行:

x += -lr * x.grad 

optimizer.zero_grad()オプティマイザ内のすべてのパラメータxためx.gradをクリアします。 loss.backward()の前にこれを呼び出すことが重要です。そうしないと、複数のパスからグラジエントが累積されます。

+0

コメント@JMAに感謝します。私はかなり多くのことをすでに知っていましたが、私の質問は実際には正しい方程式を使うのか、紙の方程式を反映するのかにもっと焦点を当てました。あなたがこのことについて私を助けることができるなら、それは全世界を意味するでしょう:) –

+0

あなたはまだこれを確認する助けが必要ですか? – JMA

+0

はい、ディスカッションを電子メールに移行する場合もOKです –

関連する問題