#Help understanding how LossFunctions.jl works

1 messages · Page 1 of 1 (latest)

vague jackal
#

I've been looking at this code [https://github.com/JuliaML/LossFunctions.jl/blob/cfcdc6a9d0f42d90ea4c2d268cc6be34e93d8926/src/losses.jl], specifically the unary fallback operations. I don't understand how that works in Julia. (loss::DistanceLoss)(output::Number, target::Number) = loss(output - target) this operator overload for example, is calling the same operator overload of the same class. How does that work, where is it defined?

Or a little bit below that we see this:
function sum(loss::SupervisedLoss, outputs, targets) sum(loss(ŷ, y) for (ŷ, y) in zip(outputs, targets)) end
But SupervisedLoss does not have a () overload defined, so what function will be called for loss(ŷ, y).

lethal burrow
#

(loss::LPDistLoss{P})(difference::Number) where {P} = abs(difference)^P```
vague jackal
#

OK so maybe I am not understanding Julia properly. How would we write this in C++?
Because let's say that we have distance loss defined as:
class Loss {}; class SupervisedLoss : public Loss {}; class DistanceLoss : public SupervisedLoss {};

Then they have overloaded the () operator so it would be something like this:

double operator()(const DistanceLoss& loss, double output, double target) { return loss(output - target); }

Then what is loss(output - target), where would it be defined in the C++ equivalent, or in other words what will Julia call once it tries to execute that line?
And I think fundamentally my second question above is the same thing.

#

Or when it says Distance loss, it means all the other classes that inherit from distance loss?

lethal burrow
#

I'm not familiar with cpp, @jolly spear might be

#

Julia doesn't have classes or overloading in the c++ sense though

jolly spear
#

it's method dispatching, this operator takes two arguments:

(loss::DistanceLoss)(output::Number, target::Number) = loss(output - target)

and the operator it calles takes one argument, which is a different method

#
struct DistanceLoss 
{
  // call operator with 2 args
  auto operator()(Number output, Number target)
  {  
    this->operator(out - target);  // calls 1 arg
  }

  // call operator with 1 arg
  auto operator()(Number x)
  {  
    // do something else
  }
}
#

(pseudo code I'm too lazy to do the templates for number and check if this compiles)

#

I think you're confused because you're thinking object oriented, the (loss::DistanceLoss) is just a way to refer to the instance that is called, in C++ we have this to refer to the current instance, in julia you need to make that a free-floating function instead of a member function and give the instance an argument name, loss