darknet原始碼解讀-yolov2損失計算
參考文章:
yolov2損失計算的原始碼集中在region_layer.c檔案forward_region_layer函式中,為了兼顧座標、分類、目標置信度以及訓練效率,損失函式由多個部分組成,且不同部分都被賦予了各自的損失權重,整體計算公式如下。
圖:yolov2損失函式計算公式
W,H指的是特徵圖(13x13)的寬和高,A指每個網格單元(cell)對應的anchor box的數目(5),各種表示各類損失的權重。我們先看第1部分損失:
當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