darknet-yolov3模型預測框size不正確的原因


問題描述:預測框的中心位置正常,但是預測的框的widthheight不正常。

解決方法:使得訓練的配置cfg和測試中cfg的輸入width, height, anchorbox保持一致!

問題是我在修改anchorbox時遇到的,當時訓練和測試不在同一環境下,測試端沒有及時更新cfg文件造成的,如下圖所示:

mAP也是極低的。

修改后,檢測框正常,如下圖所示:

下面做下boundingbox來源分析:

首先是yolo(you only look once)中是這樣定義的:

算法中明確告訴我們:boundingbox只和cell(featuremap中的)位置(Cx,Cy)以及anchorbox的(Pw,Ph)直接相關。所以我們可以重點關注這兩個量。

對應到源代碼中的實現主要是以下兩個函數:

yolo_layer.c
...

box get_yolo_box(float *x, float *biases, int n, int index, int i, int j, int lw, int lh, int w, int h, int stride) 
/* 
輸入參數解析:(*x 預測數據),(*biases 存放anchor數據),
(i、j 對應在feature map上的坐標),
(n 表示anchor數組的mask,為了讓三個yolo_layer能取到自己對應的三組anchor, 小尺寸feature map對應大size anchor,比較好理解小尺寸特征圖負責檢查大尺寸目標),
(index,當前bbox對應的數據的起始下標),
(lw lh,特征圖的w h),
(w h, 網絡輸入的w h),
(同一個bbox數據之間的stride lw*lh)
*/
{
    box b; // 網絡為了每一個bbox都給出了4個坐標預測值: tx ty tw ty
    /*
    其中tx 和 ty是相對於當前feature map坐標的偏移 
    除以lw&&lh 是計算出bbox坐標在圖像中的比例
    */
    b.x = (i + x[index + 0*stride]) / lw;
    b.y = (j + x[index + 1*stride]) / lh;
    /*
    e^tw * biases[2*n] 表示學習到的w回歸值和對應prior bbox(anchor) w的乘積得到
    bbox在網絡輸入size基礎上的w size, 除以 net_w得到相對於網絡輸入圖像的比例
    h的計算同理, 這部分的內容涉及到yolov3論文中的圖二
    */
    b.w = exp(x[index + 2*stride]) * biases[2*n]   / w;
    b.h = exp(x[index + 3*stride]) * biases[2*n+1] / h;
    return b;
    /*補充一下,這里算出的x,y,w,h都是相對於net input size的比例*/
}
此不分為轉載:
https://blog.csdn.net/wwwhp/article/details/84718089
...
int get_yolo_detections(layer l, int w, int h, int netw, int neth, float thresh, int *map, int relative, detection *dets)
{
    int i,j,n;
    float *predictions = l.output;
    if (l.batch == 2) avg_flipped_yolo(l);
    int count = 0;
    for (i = 0; i < l.w*l.h; ++i){
        int row = i / l.w;
        int col = i % l.w;
    //printf("get_yolo_detections:i =%d,row = i / l.w=%d, col = i % l.w;\n",i, row, col);
        for(n = 0; n < l.n; ++n){
            int obj_index  = entry_index(l, 0, n*l.w*l.h + i, 4);
            float objectness = predictions[obj_index];//objectness:有框的
        //printf("objectness:%f\n",objectness);
            if(objectness <= thresh) continue;
        printf("obj_index = %d,objectness:%f, thresh:%f\n",obj_index,objectness,thresh);
            int box_index  = entry_index(l, 0, n*l.w*l.h + i, 0);
            dets[count].bbox = get_yolo_box(predictions, l.biases, l.mask[n], box_index, col, row, l.w, l.h, netw, neth, l.w*l.h);//模型推理出偏移量
            dets[count].objectness = objectness;
            dets[count].classes = l.classes;
            for(j = 0; j < l.classes; ++j){
                int class_index = entry_index(l, 0, n*l.w*l.h + i, 4 + 1 + j);
                float prob = objectness*predictions[class_index];//predictions[class_index]:框中物體是class的概率,prob:置信度
        printf("get_yolo_detections1:prob=objectness*predictions[class_index] = %f * predictions[%d] = %f * %f = %f;\n",objectness,class_index,objectness,predictions[class_index],prob);
                dets[count].prob[j] = (prob > thresh) ? prob : 0;
        printf("get_yolo_detections2:[dets[count].prob[j] = (prob > thresh) ? prob : 0] = [ %f = (%f > %f) ? %f : 0];\n",dets[count].prob[j],prob,thresh,prob);
            }
            ++count;
        }
    }
    correct_yolo_boxes(dets, count, w, h, netw, neth, relative);
    return count;
}
...

如有疑問可以留言。

希望可以幫到困惑的你!

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM