1. 程式人生 > >darknet原始碼解讀-yolov2損失計算

darknet原始碼解讀-yolov2損失計算

參考文章:

    yolov2損失計算的原始碼集中在region_layer.c檔案forward_region_layer函式中,為了兼顧座標、分類、目標置信度以及訓練效率,損失函式由多個部分組成,且不同部分都被賦予了各自的損失權重,整體計算公式如下。

                                                       圖:yolov2損失函式計算公式

      W,H指的是特徵圖(13x13)的寬和高,A指每個網格單元(cell)對應的anchor box的數目(5),各種\lambda表示各類損失的權重。我們先看第1部分損失:

                                                                         L_{Max IoU < thresh}\lambda _{noobj} * (-b_{ijk}^{o})^{2}

當Max IoU小於閾值thresh時,預測box為沒有目標,由以上公式計算沒有目標時的損失。觀察程式碼的話可以看到,首先預設將所有預測box都當做沒有目標進行了計算,後面當某個預測box的best_iou大於閾值時再將該預測box的目標置信度損失置為0。再來看下第2部分,座標迴歸損失:

                            

當訓練的圖片數量小於12800張的時候計算這些圖片的座標(w,y,h,w)損失。

再看第3大項:

 for(t = 0; t < 30; ++t){
            box truth = float_to_box(net.truth + t*(l.coords + 1) + b*l.truths, 1);
            if(!truth.x) break;
			
            float best_iou = 0;
            int best_n = 0;
			
            i = (truth.x * l.w); //cell(j,i)
            j = (truth.y * l.h);
			
            box truth_shift = truth;
            truth_shift.x = 0;
            truth_shift.y = 0;

			for(n = 0; n < l.n; ++n){ 
                int box_index = entry_index(l, b, n*l.w*l.h + j*l.w + i, 0);
                box pred = get_region_box(l.output, l.biases, n, box_index, i, j, l.w, l.h, l.w*l.h);
                if(l.bias_match){
                    pred.w = l.biases[2*n]/l.w;
                    pred.h = l.biases[2*n+1]/l.h;
                }
				
                pred.x = pred.y = 0;

				float iou = box_iou(pred, truth_shift);
                if (iou > best_iou){
                    best_iou = iou;
                    best_n = n;
                }
            }

            int box_index = entry_index(l, b, best_n*l.w*l.h + j*l.w + i, 0);
            float iou = delta_region_box(truth, l.output, l.biases, best_n, box_index, 
				i, j, l.w, l.h, l.delta, l.coord_scale *  (2 - truth.w*truth.h), l.w*l.h);

            if(l.coords > 4){ //no exec
                int mask_index = entry_index(l, b, best_n*l.w*l.h + j*l.w + i, 4);
                delta_region_mask(net.truth + t*(l.coords + 1) + b*l.truths + 5, 
					l.output, l.coords - 4, mask_index, l.delta, l.w*l.h, l.mask_scale);
            }
			
            if(iou > .5) recall += 1;
            avg_iou += iou;

			//best predict box confidence
            int obj_index = entry_index(l, b, best_n*l.w*l.h + j*l.w + i, l.coords);
            avg_obj += l.output[obj_index];
			
			l.delta[obj_index] = l.object_scale * (1 - l.output[obj_index]);
            if (l.rescore) { 			
                l.delta[obj_index] = l.object_scale * (iou - l.output[obj_index]);
            }
		
            if(l.background){ //no exec
                l.delta[obj_index] = l.object_scale * (0 - l.output[obj_index]);
            }

            int class = net.truth[t*(l.coords + 1) + b*l.truths + l.coords];
            if (l.map) class = l.map[class];

			int class_index = entry_index(l, b, best_n*l.w*l.h + j*l.w + i, l.coords + 1);
			delta_region_class(l.output, l.delta, class_index, class, l.classes, 
				l.softmax_tree, l.class_scale, l.w*l.h, &avg_cat, !l.softmax); //class loss
            ++count;
            ++class_count;
        }

第3部分的損失計算與某個ground truth box匹配的預測框各部分的損失,包括座標誤差、置信度誤差和分類誤差。對於某個ground truth(外層for迴圈),首先要確定其中心點要落在哪個cell上,然後計算這個cell的5個先驗框與ground truth的IoU值(YOLOv2中bias_match=1),計算IoU值時不考慮座標,只考慮形狀,所以先將先驗框與ground truth的中心點都偏移到原點,然後計算出對應的IOU值,IOU值最大的那個先驗框與ground truth匹配,對應的預測框用來預測這個ground truth。在計算obj置信度時,在YOLOv1中target=1,而YOLOv2增加了一個控制引數rescore,當其為1時,target取預測框與ground truth的真實IOU值。對於那些沒有與ground truth匹配的先驗框(與預測框對應),除去那些Max_IOU低於閾值的,其它的就全部忽略,不計算任何誤差(l.deltas在分配空間時預設已置0)。這點在YOLOv3論文中也有相關說明:YOLO中一個ground truth只會與一個先驗框匹配(IOU值最好的),對於那些IOU值超過一定閾值的先驗框,其預測結果就忽略了。

相關推薦

darknet原始碼解讀-yolov2損失計算

參考文章:     yolov2損失計算的原始碼集中在region_layer.c檔案forward_region_layer函式中,為了兼顧座標、分類、目標置信度以及訓練效率,損失函式由多個部分組成,且不同部分都被賦予了各自的損失權重,整體計算公式如下。  

darknet原始碼解讀-load_data

    這裡的資料載入部分的程式碼由detector.c檔案中train_detector函式中load_data處開始解讀。 void train_detector(char *datacfg, char *cfgfile, char *weightfile, int *

darknet原始碼解讀-letterbox_image

letterbox_image對影象調整成輸入尺寸(w,h) //將原圖進行一定比例的縮放,返回的圖片尺寸為(w,h) image letterbox_image(image im, int w, int h) { int new_w = im.w; int

yolo v2 損失函式原始碼解讀

前提說明:     1, 關於 yolo 和 yolo v2 的詳細解釋請移步至如下兩個連結,或者直接看論文(我自己有想寫 yolo 的教程,但思前想後下面兩個連結中的文章質量實在是太好了_(:з」∠)_)         yo

深度學習之---yolo,kmeans計算anchor框原始碼解讀

k-means原理 K-means演算法是很典型的基於距離的聚類演算法,採用距離作為相似性的評價指標,即認為兩個物件的距離越近,其相似度就越大。該演算法認為簇是由距離靠近的物件組成的,因此把得到緊湊且獨立的簇作為最終目標。 問題 K-Means演算法主要解決的問題如下圖所示。我們可以看到

YOLO原始碼Darknet原始碼解讀(im2col.c)

#include "im2col.h" #include <stdio.h> // 獲取影象畫素值 float im2col_get_pixel(float *im, int height, int width, int channels,      

YOLO原始碼Darknet原始碼解讀(convolutional_layer.c)

#include "convolutional_layer.h" #include "utils.h" #include "batchnorm_layer.h" #include "im2col.h" #include "col2im.h" #include "blas.h" #include "g

YOLO原始碼Darknet原始碼解讀(layer.c)

#include "layer.h" #include "cuda.h" #include <stdlib.h> void free_layer(layer l) { if(l.type == DROPOUT){ if(l.rand) fr

YOLO原始碼Darknet原始碼解讀(network.c)

network.c #include <stdio.h> #include <time.h> #include <assert.h> #include "network.h" #include "image.h" #include "data.h" #inclu

YOLO原始碼Darknet原始碼解讀(utils.c)

utils.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <assert.h> #include <u

YOLO原始碼Darknet原始碼解讀(yolo.c)

// 將檢測的boxes結果寫入檔案 void print_yolo_detections(FILE **fps, char *id, int total, int classes, int w, int h, detection *dets) { int i, j; for(i = 0; i

【React原始碼解讀】- 元件的實現

前言 react使用也有一段時間了,大家對這個框架褒獎有加,但是它究竟好在哪裡呢? 讓我們結合它的原始碼,探究一二!(當前原始碼為react16,讀者要對react有一定的瞭解) 回到最初 根據react官網上的例子,快速構建react專案 npx create-react-app

【1】pytorch torchvision原始碼解讀之Alexnet

最近開始學習一個新的深度學習框架PyTorch。 框架中有一個非常重要且好用的包:torchvision,顧名思義這個包主要是關於計算機視覺cv的。這個包主要由3個子包組成,分別是:torchvision.datasets、torchvision.models、torchvision.trans

Set介面_HashSet常用方法_JDK原始碼解讀

Set 介面繼承自 Collection ,Set 沒有新增方法,方法和 Collection 保持一致, Set 容器的特點:無序,不可重複,無序指Set 中的元素沒有索引,我們只能遍歷查詢,不重複指不允許加入重複的元素,更確切的說,新元素如果和Set 中某個元素通過 equals() 方

vux之x-input使用以及原始碼解讀

前言 近期專案中使用的vux中的input,以及使用自定義校驗規則和動態匹配錯誤提示,有時間記錄下自己的使用經歷和原始碼分析。希望大家多多指正,留言區發表自己寶貴的建議。 詳解 列舉官方文件中常用的幾個屬性的使用方法,程式碼如下 <group ref="group">

react-redux connect原始碼解讀

今天看了下react-redux的原始碼,主要來看下connect的方法 首先找到connect的入口檔案。在src/index.js下找到。對應connect資料夾下的connect.js檔案。 大致說下原始碼connect流程 connect.js對外暴露是通過ex

java原始碼解讀之HashMap

1:首先下載openjdk(http://pan.baidu.com/s/1dFMZXg1),把原始碼匯入eclipse,以便看到jdk原始碼            Windows-Prefe

以太坊原始碼解讀(5)BlockChain類的解析及NewBlockChain()分析

一、blockchain的資料結構 type BlockChain struct { chainConfig *params.ChainConfig // 初始化配置 cacheConfig *CacheConfig // 快取配置 db ethdb.Databas

以太坊原始碼解讀(4)Block類及其儲存

一、Block類 type Block struct { /******header*******/ header *Header /******header*******/ /******body*********/ uncle

Hystrix之@EnableCircuitBreaker原始碼解讀

Hystrix是一個供分散式系統使用,提供延遲和容錯功能,保證複雜的分佈系統在面臨不可避免的失敗時,仍能有其彈性。 比如系統中有很多服務,當某些服務不穩定的時候,使用這些服務的使用者執行緒將會阻塞,如果沒有隔離機制,系統隨時就有可能會掛掉,從而帶來很大的風險。 SpringCloud使用Hy