深度學習·目標檢測和語義分割基礎

邊緣框

  • 不是標準的x,y坐標軸。
  • 邊緣框三種表示:左上右下下坐標,左上坐標+長寬,中心坐標+長寬
    在這里插入圖片描述

COCO

  • 目標檢測數據集的格式:注意一個圖片有多個物體,使用csv或者文件夾結構的格式不可取

在這里插入圖片描述

錨框算法

  • 生成很多個錨框
  • 錨框之間和真實邊緣框匹配(標簽)。
  • 一般的目標檢測模型不直接預測錨框的四個位置,而是預測與真實值的偏移

  • 對于背景類,會有個掩碼將偏移值設置為0.
  • 匹配標簽后使用NMS輸出最后預測的錨框

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

在訓練數據中標注錨框

label:subsec_labeling-anchor-boxes

在訓練集中,我們將每個錨框視為一個訓練樣本。
為了訓練目標檢測模型,我們需要每個錨框的類別(class)和偏移量(offset)標簽,其中前者是與錨框相關的對象的類別,后者是真實邊界框相對于錨框的偏移量。
在預測時,我們為每個圖像生成多個錨框,預測所有錨框的類別和偏移量,根據預測的偏移量調整它們的位置以獲得預測的邊界框,最后只輸出符合特定條件的預測邊界框。

目標檢測訓練集帶有真實邊界框的位置及其包圍物體類別的標簽。
要標記任何生成的錨框,我們可以參考分配到的最接近此錨框的真實邊界框的位置和類別標簽。
下文將介紹一個算法,它能夠把最接近的真實邊界框分配給錨框。

將真實邊界框分配給錨框

給定圖像,假設錨框是A1,A2,…,AnaA_1, A_2, \ldots, A_{n_a}A1?,A2?,,Ana??,真實邊界框是B1,B2,…,BnbB_1, B_2, \ldots, B_{n_b}B1?,B2?,,Bnb??,其中na≥nbn_a \geq n_bna?nb?
讓我們定義一個矩陣X∈Rna×nb\mathbf{X} \in \mathbb{R}^{n_a \times n_b}XRna?×nb?,其中第iii行、第jjj列的元素xijx_{ij}xij?是錨框AiA_iAi?和真實邊界框BjB_jBj?的IoU。
該算法包含以下步驟。

  1. 在矩陣X\mathbf{X}X中找到最大的元素,并將它的行索引和列索引分別表示為i1i_1i1?j1j_1j1?。然后將真實邊界框Bj1B_{j_1}Bj1??分配給錨框Ai1A_{i_1}Ai1??。這很直觀,因為Ai1A_{i_1}Ai1??Bj1B_{j_1}Bj1??是所有錨框和真實邊界框配對中最相近的。在第一個分配完成后,丟棄矩陣中i1th{i_1}^\mathrm{th}i1?th行和j1th{j_1}^\mathrm{th}j1?th列中的所有元素。
  2. 在矩陣X\mathbf{X}X中找到剩余元素中最大的元素,并將它的行索引和列索引分別表示為i2i_2i2?j2j_2j2?。我們將真實邊界框Bj2B_{j_2}Bj2??分配給錨框Ai2A_{i_2}Ai2??,并丟棄矩陣中i2th{i_2}^\mathrm{th}i2?th行和j2th{j_2}^\mathrm{th}j2?th列中的所有元素。
  3. 此時,矩陣X\mathbf{X}X中兩行和兩列中的元素已被丟棄。我們繼續,直到丟棄掉矩陣X\mathbf{X}Xnbn_bnb?列中的所有元素。此時已經為這nbn_bnb?個錨框各自分配了一個真實邊界框。
  4. 只遍歷剩下的na?nbn_a - n_bna??nb?個錨框。例如,給定任何錨框AiA_iAi?,在矩陣X\mathbf{X}X的第ithi^\mathrm{th}ith行中找到與AiA_iAi?的IoU最大的真實邊界框BjB_jBj?,只有當此IoU大于預定義的閾值時,才將BjB_jBj?分配給AiA_iAi?

下面用一個具體的例子來說明上述算法。
如 :numref:fig_anchor_label(左)所示,假設矩陣X\mathbf{X}X中的最大值為x23x_{23}x23?,我們將真實邊界框B3B_3B3?分配給錨框A2A_2A2?
然后,我們丟棄矩陣第2行和第3列中的所有元素,在剩余元素(陰影區域)中找到最大的x71x_{71}x71?,然后將真實邊界框B1B_1B1?分配給錨框A7A_7A7?
接下來,如 :numref:fig_anchor_label(中)所示,丟棄矩陣第7行和第1列中的所有元素,在剩余元素(陰影區域)中找到最大的x54x_{54}x54?,然后將真實邊界框B4B_4B4?分配給錨框A5A_5A5?
最后,如 :numref:fig_anchor_label(右)所示,丟棄矩陣第5行和第4列中的所有元素,在剩余元素(陰影區域)中找到最大的x92x_{92}x92?,然后將真實邊界框B2B_2B2?分配給錨框A9A_9A9?
之后,我們只需要遍歷剩余的錨框A1,A3,A4,A6,A8A_1, A_3, A_4, A_6, A_8A1?,A3?,A4?,A6?,A8?,然后根據閾值確定是否為它們分配真實邊界框。

🏷fig_anchor_label

此算法在下面的assign_anchor_to_bbox函數中實現。
在這里插入圖片描述

標記類別和偏移量

現在我們可以為每個錨框標記類別和偏移量了。
假設一個錨框AAA被分配了一個真實邊界框BBB
一方面,錨框AAA的類別將被標記為與BBB相同。
另一方面,錨框AAA的偏移量將根據BBBAAA中心坐標的相對位置以及這兩個框的相對大小進行標記。
鑒于數據集內不同的框的位置和大小不同,我們可以對那些相對位置和大小應用變換,使其獲得分布更均勻且易于擬合的偏移量。
這里介紹一種常見的變換。
[**給定框AAABBB,中心坐標分別為(xa,ya)(x_a, y_a)(xa?,ya?)(xb,yb)(x_b, y_b)(xb?,yb?),寬度分別為waw_awa?wbw_bwb?,高度分別為hah_aha?hbh_bhb?,可以將AAA的偏移量標記為:

(xb?xawa?μxσx,yb?yaha?μyσy,log?wbwa?μwσw,log?hbha?μhσh),\left( \frac{ \frac{x_b - x_a}{w_a} - \mu_x }{\sigma_x}, \frac{ \frac{y_b - y_a}{h_a} - \mu_y }{\sigma_y}, \frac{ \log \frac{w_b}{w_a} - \mu_w }{\sigma_w}, \frac{ \log \frac{h_b}{h_a} - \mu_h }{\sigma_h}\right),(σx?wa?xb??xa???μx??,σy?ha?yb??ya???μy??,σw?logwa?wb???μw??,σh?logha?hb???μh??),
**]
其中常量的默認值為 μx=μy=μw=μh=0,σx=σy=0.1\mu_x = \mu_y = \mu_w = \mu_h = 0, \sigma_x=\sigma_y=0.1μx?=μy?=μw?=μh?=0,σx?=σy?=0.1σw=σh=0.2\sigma_w=\sigma_h=0.2σw?=σh?=0.2。里插入圖片描述](https://i-blog.csdnimg.cn/direct/d0940b8fa45e4bf982f7ed9a5f981c99.png)

這種轉換在下面的 offset_boxes 函數中實現。

基于錨框的經典算法

在這里插入圖片描述

語義分割

  • 每個像素都會有一個label,這個label也是一個RGB顏色,三個通道

VOC數據集

  • 圖片在JPEGImages,標簽在SegmentationClass中。
  • 格式都為圖片
    taget

在這里插入圖片描述

圖像增強的注意事項

在之前的實驗,例如 :numref:sec_alexnet— :numref:sec_googlenet中,我們通過再縮放圖像使其符合模型的輸入形狀。
然而在語義分割中,這樣做需要將預測的像素類別重新映射回原始尺寸的輸入圖像。
這樣的映射可能不夠精確,尤其在不同語義的分割區域。
為了避免這個問題,我們將圖像裁剪為固定尺寸,而不是再縮放。
具體來說,我們[使用圖像增廣中的隨機裁剪,裁剪輸入圖像和標簽的相同區域]。
小細節:原標簽是一個3d RGB圖片,要進一步轉換為標簽才行。

    def __getitem__(self, idx):feature, label = voc_rand_crop(self.features[idx], self.labels[idx],*self.crop_size)return (feature, voc_label_indices(label, self.colormap2label))# 原標簽是一張RGB圖片,區分不同的背景,將其轉換為可學習的標簽。

將標簽圖片的RGB(3D)轉換為標簽索引(1D)

可見最后的dataloader標簽是一個圖片每個像素是一個標簽

在這里插入圖片描述

正常卷積Conv2d

輸入和輸出通道,
kernel_size=2padding+1,且stride=1時,大小不變。
kernel_size=2
padding,且stride=1時,大小不變。

X = torch.rand(size=(1, 10, 16, 16))
conv = nn.Conv2d(10, 20, kernel_size=5, padding=2, stride=1)
X.shape,conv(X).shape
(torch.Size([1, 10, 16, 16]), torch.Size([1, 20, 16, 16]))

轉置卷積TransConv2d

利用卷積核的感受野,逆還原卷積。
在這里插入圖片描述
在這里插入圖片描述
輸入和輸出通道,
kernel_size=2padding+1,且stride=1時,大小不變。
kernel_size=2
padding,且stride=1時,大小不變。
padding相當于直接減少輸出的大小,與conv相反,步長變為縮放k倍

X = torch.rand(size=(1, 10, 16, 16))
tconv = nn.ConvTranspose2d(10, 20, kernel_size=5, padding=2, stride=1)
X.shape,tconv(X).shape
(torch.Size([1, 10, 16, 16]), torch.Size([1, 20, 16, 16]))

卷積和轉置卷積是可逆的

X = torch.rand(size=(1, 10, 16, 16))
conv = nn.Conv2d(10, 20, kernel_size=5, padding=2, stride=3)
tconv = nn.ConvTranspose2d(20, 10, kernel_size=5, padding=2, stride=3)
tconv(conv(X)).shape == X.shape

在這里插入圖片描述

FCN

CNN+1x1卷積(降低通道數)+轉置卷積(重新縮放)

輸出是(通道數,寬,高),其中通道數是用作類似全連接的標簽,與標簽數一致

pretrained_net = torchvision.models.resnet18(pretrained=True)
num_classes = 21
net.add_module('final_conv', nn.Conv2d(512, num_classes, kernel_size=1))
net.add_module('transpose_conv', nn.ConvTranspose2d(num_classes, num_classes,kernel_size=64, padding=16, stride=32))
RESNET輸出:
torch.Size([1, 512, 10, 15])
加入轉置卷積后輸入和輸出
torch.Size([1, 3, 320, 480])
torch.Size([1, 21, 320, 480])

參考文獻

動手學深度學習主頁

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/914586.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/914586.shtml
英文地址,請注明出處:http://en.pswp.cn/news/914586.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ffmpeg音視頻處理大綱

FFmpeg 是一個功能強大的開源音視頻處理工具集,其核心代碼以 C 語言實現。下面從源碼角度分析 FFmpeg 如何實現轉碼、壓縮、提取、截取、拼接、合并和錄屏等功能: 一、FFmpeg 核心架構與數據結構 FFmpeg 的源碼結構圍繞以下核心組件展開: lib…

網絡安全小練習

一、docker搭建 1.安裝 2.改變鏡像源(推薦國內鏡像源:阿里云鏡像源) 登錄阿里云容器鏡像源服務( 阿里云登錄 - 歡迎登錄阿里云,安全穩定的云計算服務平臺 ) 復制系統分配的專屬地址 配置 sudo mkdir …

數據結構——順序表的相關操作

一、順序表基礎認知?1.順序表的定義與特點?順序表是數據結構中一種線性存儲結構,它將數據元素按照邏輯順序依次存儲在一片連續的物理內存空間中。簡單來說,就是用一段地址連續的存儲單元依次存放線性表的元素,且元素之間的邏輯關系通過物理…

2025最新國產用例管理工具評測:Gitee Test、禪道、藍凌測試、TestOps 哪家更懂研發協同?

在快節奏的 DevOps 時代,測試用例管理已不再是 QA 的獨角戲,而是穿透需求—開發—測試—交付全流程的核心樞紐。想象一下,如果用例結構混亂,覆蓋不全,甚至丟失版本變更歷史,不僅協作亂,還影響交…

在線評測系統開發交流

https://space.bilibili.com/700332132?spm_id_from333.788.0.0 實驗內容爬蟲Web系統設計數據分析實驗指導爬蟲Web系統設計自然語言處理與信息檢索數據可視化評分標準FAQ實驗二:在線評測系統實驗概述實驗內容Step1:題目管理Step2:題目評測S…

Linux操作系統從入門到實戰(十)Linux開發工具(下)make/Makefile的推導過程與擴展語法

Linux操作系統從入門到實戰(十)Linux開發工具(下)make/Makefile的推導過程與擴展語法前言一、 make/Makefile的推導過程1. 先看一個完整的Makefile示例2. make的工作流程(1)尋找Makefile文件(2&…

NFS磁盤共享

步驟:注意事項?:確保服務端防火墻關閉,或者允許2049端口通信,客戶端需具備讀寫權限。服務器端安裝NFS服務器:sudo apt-get install nfs-kernel-server # Debian/Ubuntu sudo yum install nfs-utils # Ce…

ORA-06413: 連接未打開

System.Data.OracleClient.OracleException:ORA-06413: 連接未打開 oracle 報錯 ORA-06413: 連接未打開 db.Open();的報錯鏈接未打開,System.Data.OracleClient.OracleException HResult0x80131938 MessageORA-06413: 連接未打開 關于ORA-06413錯誤(…

【PCIe 總線及設備入門學習專欄 5.1.2 -- PCIe EP core_rst_n 與 app_rst_n】

文章目錄 app_rst_n 和 core_rst_n 的作用1. core_rst_n — PCIe 控制器內部邏輯復位作用控制方式2. app_rst_n — 應用層/用戶邏輯復位作用特點兩者關系圖示:示例流程(Synopsys EP)rst_sync[3] 的作用詳解(復位同步邏輯)為什么使用 rst_sync[3]?圖示說明Synopsys 官方手…

Python初學者筆記第二十期 -- (文件IO)

第29節課 文件IO 在編程中,文件 I/O(輸入/輸出)允許程序與外部文件進行數據交互。Python 提供了豐富且易用的文件 I/O 操作方法,能讓開發者輕松實現文件的讀取、寫入和修改等操作。 IO交互方向 從硬盤文件 -> 讀取數據 -> 內…

Java JUC包概述

Java 的 java.util.concurrent(簡稱 JUC)包是 JDK 5 及以后引入的并發編程工具包,旨在解決傳統線程模型(如 synchronized、wait/notify)的局限性,提供更靈活、高效、可擴展的并發編程組件。它極大簡化了多線…

LeetCode--44.通配符匹配

前言:不知不覺又斷更一天了,其實昨天就把這道題寫得差不多了,只是剛好在力扣里面看見了一種新的解法,本來想寫出來的,但是我把它推到今天了,因為太晚了,但是今天又睡懶覺了,所以我直…

WHAT - 依賴管理工具 CocoaPods

文章目錄1. 什么是 CocoaPods?2. 如何安裝 CocoaPods?(1) 確保已安裝 Ruby(macOS 默認自帶)(2) 安裝 CocoaPods(3) 驗證安裝3. 在 React Native 項目中使用 CocoaPods(1) 進入 iOS 目錄(2) 初始化 Podfile(如果不存在&…

C++ Boost Aiso TCP 網絡聊天(服務端客戶端一體化)

代碼功能說明: 程序模式: 主動連接模式:當用戶指定對端 IP 和端口時,嘗試連接到對端被動監聽模式:當用戶未指定對端 IP 時,等待其他節點連接線程模型: 主線程:處理用戶輸入和消息發送接收線程:后臺接收并顯示對端消息關鍵組件: std::atomic<bool> connected:原…

WeakAuras 5.12.9 Ekkles lua

3.45獵人寶寶狼 技能恢復宏已知3.45BUG RL技能位會清空&#xff0c;小退大退 BB技能全部激活&#xff0c;修復以前可用宏一鍵恢復狀態-------方法一&#xff1a;宏命令---------------------------------------------------------#showtooltip 狂怒之嚎 /petautocaston [btn:1]…

對于編寫PID過程中的問題

當stm32RCT6使用位置環pid控制麥輪轉動一定路程時&#xff0c;在這個時間段內想讓一邊輪胎速度加大應該怎么做&#xff1f;比如我pid的目標脈沖值為9000&#xff0c;在運行到3000的時候車偏左了&#xff0c;那我應該怎樣讓他回正&#xff0c;我想到的辦法是增加其最大的脈沖值&…

LeetCode|Day13|88. 合并兩個有序數組|Python刷題筆記

LeetCode&#xff5c;Day13&#xff5c;88. 合并兩個有序數組&#xff5c;Python刷題筆記 &#x1f5d3;? 本文屬于【LeetCode 簡單題百日計劃】系列 &#x1f449; 點擊查看系列總目錄 >> &#x1f4cc; 題目簡介 題號&#xff1a;88. 合并兩個有序數組 難度&#xf…

【C++】初識C++(1)

個人主頁&#xff1a;我要成為c嘎嘎大王 希望這篇小小文章可以讓你有所收獲&#xff01; 目錄 前言 一、C的第一個程序 二、命名空間 2.1 namespace 的價值 2.2 namespace 的定義 2.2.1 正常的命名空間定義 2.2.2 命名空間可以嵌套 2.2.3 匿名命名空間 2.2.4 同名的name…

在新聞資訊 APP 中添加不同新聞分類頁面,通過 ViewPager2 實現滑動切換

在新聞資訊 APP 中添加不同新聞分類頁面&#xff0c;通過 ViewPager2 實現滑動切換 核心組件的作用 ViewPager2&#xff1a;是 ViewPager 的升級版&#xff0c;基于RecyclerView實現&#xff0c;支持水平 / 垂直滑動、RTL&#xff08;從右到左&#xff09;布局&#xff0c;且修…

vuex操作state為什么要使用mutations作為規范而不是直接修改state

1. 狀態變更的可追蹤性 (Trackable Changes)Devtools 集成&#xff1a;Vue Devtools 可以捕獲每次 mutation 的執行記錄&#xff0c;記錄變更前后的 state 快照、參數和調用棧。直接修改 state&#xff1a;Devtools 無法檢測到變更來源&#xff0c;導致調試困難&#xff08;如無…