From aa55692b97df056298ca016a5be4771902baafd9 Mon Sep 17 00:00:00 2001 From: Tomasz Sobczyk Date: Sun, 29 Nov 2020 17:08:22 +0100 Subject: [PATCH] Cross entropy loss. --- src/learn/autograd.h | 36 ++++++++++++++++++++++++++++++++++-- src/learn/learn.cpp | 17 +++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/learn/autograd.h b/src/learn/autograd.h index f83d4d72..a4ad8b7f 100644 --- a/src/learn/autograd.h +++ b/src/learn/autograd.h @@ -282,6 +282,38 @@ namespace Learner::Autograd::UnivariateStatic return Product(Constant(lhs), std::move(rhs)); } + template + struct Negation : Evaluable> + { + using ValueType = T; + + explicit Negation(ArgT x) : + m_x(std::move(x)) + { + } + + template + T value(const std::tuple& args) const + { + return -m_x.value(args); + } + + template + T grad(const std::tuple& args) const + { + return -m_x.grad(args); + } + + private: + ArgT m_x; + }; + + template + auto operator-(ArgT x) + { + return Negation(std::move(x)); + } + template struct Sigmoid : Evaluable> { @@ -318,7 +350,7 @@ namespace Learner::Autograd::UnivariateStatic } }; - template + template auto sigmoid(ArgT x) { return Sigmoid(std::move(x)); @@ -394,7 +426,7 @@ namespace Learner::Autograd::UnivariateStatic } }; - template + template auto log(ArgT x) { return Log(std::move(x)); diff --git a/src/learn/learn.cpp b/src/learn/learn.cpp index e558b56a..83229c61 100644 --- a/src/learn/learn.cpp +++ b/src/learn/learn.cpp @@ -200,11 +200,14 @@ namespace Learner static ValueWithGrad get_loss(Value shallow, Value teacher_signal, int result, int ply) { using namespace Learner::Autograd::UnivariateStatic; + + /* auto q_ = sigmoid(VariableParameter{} * winning_probability_coefficient); auto p_ = sigmoid(ConstantParameter{} * winning_probability_coefficient); auto t_ = (ConstantParameter{} + 1.0) * 0.5; auto lambda_ = ConstantParameter{}; auto loss_ = pow(lambda_ * (q_ - p_) + (1.0 - lambda_) * (q_ - t_), 2.0); + */ /* auto q_ = VariableParameter{}; @@ -212,6 +215,20 @@ namespace Learner auto loss_ = pow(q_ - p_, 2.0) * (1.0 / (2400.0 * 2.0 * 600.0)); */ + const double epsilon = 1e-12; + + auto q_ = sigmoid(VariableParameter{} * winning_probability_coefficient); + auto p_ = sigmoid(ConstantParameter{} * winning_probability_coefficient); + auto t_ = (ConstantParameter{} + 1.0) * 0.5; + auto lambda_ = ConstantParameter{}; + auto teacher_entropy_ = -(p_ * log(p_ + epsilon) + (1.0 - p_) * log(1.0 - p_ + epsilon)); + auto outcome_entropy_ = -(t_ * log(t_ + epsilon) + (1.0 - t_) * log(1.0 - t_ + epsilon)); + auto teacher_loss_ = -(p_ * log(q_) + (1.0 - p_) * log(1.0 - q_)); + auto outcome_loss_ = -(t_ * log(q_) + (1.0 - t_) * log(1.0 - q_)); + auto result_ = lambda_ * teacher_loss_ + (1.0 - lambda_) * outcome_loss_; + auto entropy_ = lambda_ * teacher_entropy_ + (1.0 - lambda_) * outcome_entropy_; + auto loss_ = result_ - entropy_; + auto args = std::tuple((double)shallow, (double)teacher_signal, (double)result, calculate_lambda(teacher_signal)); return loss_.eval(args); }