3 votes

Quelle est la fonction de perte de YOLOv3 ?

J'étais sur le point d'écrire ma propre implémentation de la YOLOv3 et j'ai rencontré un problème avec la fonction de perte. L'article original mentionne qu'il utilise l'entropie croisée binaire pour la partie prédiction de classe, ce que j'ai fait.

J'ai essayé de lire certains codes du darknet original, mais je n'ai rien trouvé qui soit lié à la perte de BCE. J'ai également lu d'autres approches utilisant Keras, Pytorch et TensorFlow. Tout le monde semble avoir sa propre opinion sur la fonction de perte. Certains prennent juste MSE pour l'estimation de la largeur et de la hauteur, et le reste avec BCE, certains prennent x,y,w,h avec MSE et le reste avec BCE.

Voici une partie de mon code :

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

Comme la fonction de perte joue un rôle important dans la formation. J'aimerais que quelqu'un puisse m'aider à résoudre ce problème.

2voto

gameon67 Points 1538

Fonction de perte de Yolo v3, regardez dans src/yolo_layer.c

delta pour la case, ligne 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;
}

delta pour la classe, ligne 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];
    }
}

delta pour l'objectivité, ligne 178

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

et

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

Perte = somme des carrés

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

Bref, je viens de vous donner un aperçu de la fonction de perte dans Yolo V3. Pour une explication détaillée, vous devriez suivre cette discussion github :
https://github.com/AlexeyAB/darknet/issues/1695#issuecomment-426016524
et
https://github.com/AlexeyAB/darknet/issues/1845#issuecomment-434079752

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X