Что такое функция потерь YOLOv3 - PullRequest
3 голосов
/ 28 марта 2019

Я собирался написать свою собственную реализацию YOLOv3 и столкнулся с некоторой проблемой с функцией потерь. В оригинальной статье упоминается, что он использует двоичную перекрестную энтропию в части предсказания классов, что я и сделал.

Я попытался прочитать некоторый код по оригинальному коду даркнета, но я не нашел ничего, что могло бы быть связано с потерей BCE. Более того, я читаю с некоторым подходом, использующим Keras, Pytorch и TensorFlow. Кажется, у каждого свое мнение о функции потерь. Некоторые просто принимают MSE для оценки ширины и высоты, а другие - с помощью BCE, некоторые - x, y, w, h с MSE, а остальные - с BCE.

Вот мой код:

loss_x = self.mse_loss(x[mask], tx[mask])
loss_y = self.mse_loss(y[mask], ty[mask])
loss_w = self.mse_loss(w[mask], tw[mask])
loss_h = self.mse_loss(h[mask], th[mask])
loss_conf = self.bce_loss(pred_conf[conf_mask_false], tconf[conf_mask_false]) + self.bce_loss(pred_conf[conf_mask_true],tconf[conf_mask_true])
loss_cls = (1 / nB) * self.ce_loss(pred_cls[mask],torch.argmax(tcls[mask], 1))
loss = loss_x + loss_y + loss_w + loss_h + loss_conf + loss_cls

Поскольку функция потерь играет важную роль в обучении. Я бы хотел, чтобы кто-нибудь помог мне разобраться.

1 Ответ

1 голос
/ 29 марта 2019

Функция потери Yolo v3, посмотрите на src / yolo_layer.c

дельта для коробки, строка 93

float delta_yolo_box(box truth, float *x, float *biases, int n, int index, int i, int j, int lw, int lh, int w, int h, float *delta, float scale, int stride)
{
    box pred = get_yolo_box(x, biases, n, index, i, j, lw, lh, w, h, stride);
    float iou = box_iou(pred, truth);

    float tx = (truth.x*lw - i);
    float ty = (truth.y*lh - j);
    float tw = log(truth.w*w / biases[2*n]);
    float th = log(truth.h*h / biases[2*n + 1]);

    delta[index + 0*stride] = scale * (tx - x[index + 0*stride]);
    delta[index + 1*stride] = scale * (ty - x[index + 1*stride]);
    delta[index + 2*stride] = scale * (tw - x[index + 2*stride]);
    delta[index + 3*stride] = scale * (th - x[index + 3*stride]);
    return iou;
}

дельта для класса, строка 111

void delta_yolo_class(float *output, float *delta, int index, int class, int classes, int stride, float *avg_cat)
{
    int n;
    if (delta[index]){
        delta[index + stride*class] = 1 - output[index + stride*class];
        if(avg_cat) *avg_cat += output[index + stride*class];
        return;
    }
    for(n = 0; n < classes; ++n){
        delta[index + stride*n] = ((n == class)?1 : 0) - output[index + stride*n];
        if(n == class && avg_cat) *avg_cat += output[index + stride*n];
    }
}

дельта для объектности, строка 178

l.delta[obj_index] = 0 - l.output[obj_index];
                    if (best_iou > l.ignore_thresh) {
                        l.delta[obj_index] = 0;

и

l.delta[obj_index] = 1 - l.output[obj_index];

Потеря = сумма квадрата

*(l.cost) = pow(mag_array(l.delta, l.outputs * l.batch), 2);

Во всяком случае, я просто дам вам представление о функции потерь в Yolo V3. Для подробного объяснения вы должны следовать этому обсуждению на github:
https://github.com/AlexeyAB/darknet/issues/1695#issuecomment-426016524
и
https://github.com/AlexeyAB/darknet/issues/1845#issuecomment-434079752

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...