3

I am trying to implement custom objective function for multiclassification following the guides in: https://catboost.ai/docs/concepts/python-usages-examples.html#custom-objective-function

I would like to know what is the expected format of the gradient and the Hessian matrix defined in calc_ders_multi().

To see how it works, I tried to reproduce the MultiClass loss function, but with defined gradient and Hessian matrix the program starts and gets stuck without throwing any errors. If I don't define a Hessian (return []), the program runs without problems.

import numpy as np
from catboost import Pool, CatBoostClassifier


class MultiClassObjective(object):
    def calc_ders_multi(self, approxes, targets, weights):
        # approxes, targets, weights are indexed containers of floats
        # (containers with only __len__ and __getitem__ defined).
        # weights parameter can be None.
        n_classes = len(approxes)
        exponents = np.exp(approxes)
        softmax = exponents / np.sum(exponents)
        targets = np.array([1 if x == targets else 0 for x in range(n_classes)])

        der1 = targets - softmax
        der2 = np.zeros((n_classes, n_classes))
        for x in range(n_classes):
            for y in range(n_classes):
                if x == y:
                    der2[x, y] = -softmax[x] * (1 - softmax[y])
                else:
                    der2[x, y] = softmax[x] * softmax[y]

        if weights is not None:
            der1 *= weights
            der2 *= weights

        return der1, der2
        # return der1, []

train_data = [[1, 4, 5, 6],
              [4, 5, 6, 7],
              [11, 20, 30, 30],
              [30, 40, 50, 60],
              [100, 300, 200, 400]]

train_labels = [0, 0, 1, 1, 2]

train_data = Pool(data=train_data , label=train_labels )

# Initialize CatBoostClassifier with custom `loss_function`
model = CatBoostClassifier(loss_function=MultiClassObjective(),
                           eval_metric="MultiClass",
                           iterations=100,
                           random_seed=0,
                           verbose=True
                          )
# Fit model
model.fit(train_data)
bzografov
  • 31
  • 2

0 Answers0