易語言怎么做網(wǎng)站壓力測試軟件國外b站視頻推廣網(wǎng)站
1
目標(biāo)檢測是計算機視覺領(lǐng)域中的一項重要任務(wù),它的目標(biāo)是在圖像或視頻中檢測出物體的位置和類別。YOLO(You Only Look Once)是一系列經(jīng)典的目標(biāo)檢測算法,最初由Joseph Redmon等人于2016年提出。YOLO算法具有快速、簡單、端到端的特點,并且在速度和準(zhǔn)確率上取得了很好的平衡,因此受到了廣泛的關(guān)注和應(yīng)用。
YOLO系列算法的核心思想是將目標(biāo)檢測問題轉(zhuǎn)化為一個回歸問題。它將整個圖像分成一個固定大小的網(wǎng)格,每個網(wǎng)格負(fù)責(zé)檢測該網(wǎng)格內(nèi)的物體。YOLO算法在每個網(wǎng)格上預(yù)測多個邊界框(bounding box),以及每個邊界框所屬的物體類別以及置信度分?jǐn)?shù)。
YOLO算法系列有多個版本,包括YOLOv1、YOLOv2(也稱為YOLO9000)、YOLOv3和YOLOv4等。每個版本都在YOLO的基礎(chǔ)上進(jìn)行了改進(jìn),提高了檢測精度、速度和通用性。
「今天我們將實現(xiàn)YOLO V6的遙感影像目標(biāo)檢測。」
YOLO V6
YOLOv6 是美團(tuán)視覺智能部研發(fā)的一款目標(biāo)檢測框架,致力于工業(yè)應(yīng)用。本框架同時專注于檢測的精度和推理效率,在工業(yè)界常用的尺寸模型中:YOLOv6-nano 在 COCO 上精度可達(dá) 35.0% AP,在 T4 上推理速度可達(dá) 1242 FPS;YOLOv6-s 在 COCO 上精度可達(dá) 43.1% AP,在 T4 上推理速度可達(dá) 520 FPS。在部署方面,YOLOv6 支持 GPU(TensorRT)、CPU(OPENVINO)、ARM(MNN、TNN、NCNN)等不同平臺的部署,極大地簡化工程部署時的適配工作。目前,項目已開源至 Github。
解決的問題:
RepVGG提出的結(jié)構(gòu)重參數(shù)化方法表現(xiàn)良好,但在此之前沒有檢測模型使用。作者認(rèn)為RepVGG的block縮放不合理,小模型和大模型沒必要保持相似網(wǎng)絡(luò)結(jié)構(gòu);小模型使用單路徑架構(gòu),大模型就不適合在單路徑上堆參數(shù)量。
使用重參數(shù)化的方法后,檢測器的量化也需要重新考慮,否則因為訓(xùn)練和推理時的結(jié)構(gòu)不同,性能可能會退化。
前期工作很少關(guān)注部署。前期工作中,推理是在V100等高配機器完成的,但實際使用時往往用T4等低功耗推理gpu,作者更關(guān)注后者的性能。
針對網(wǎng)絡(luò)結(jié)構(gòu)的變化,重新考慮標(biāo)簽分配和損失函數(shù)。
對于部署,可以調(diào)整訓(xùn)練策略,在不增加推理成本的情況下提升性能,如使用知識蒸餾。
具體實現(xiàn):
網(wǎng)絡(luò)設(shè)計
在one-satge的目標(biāo)檢測網(wǎng)絡(luò)中,Backbone決定了表征能力,也很大程度上影響了參數(shù)量和推理效率;Neck主要作用是聚合高低層次的語義信息;Head由幾個卷積層組成,負(fù)責(zé)預(yù)測最終結(jié)果。
考慮到硬件推理的因素,YOLOv6提出兩個可縮放的可重參數(shù)化的Backbone和Neck來適應(yīng)不同大小的模型,還提出一個使用混合通道策略的高效解耦頭,總體網(wǎng)絡(luò)結(jié)構(gòu)如下:

BackBone
在分類性能上,多分支網(wǎng)絡(luò)相比單分支表現(xiàn)更好,但隨并行性降低,其推理速度減慢。RepVGG的結(jié)構(gòu)重參數(shù)化方式,采用多分支訓(xùn)練和單分支推理,達(dá)到了較好的精度-速度權(quán)衡。 YOLOv6設(shè)計了可重參數(shù)化的Backbone并命名為EfficientRep。對于小模型,backbone的主要組成部分是訓(xùn)練階段的 RepBlock,如圖2(a)所示。在推理階段,RepBlock轉(zhuǎn)換為3×3卷積層+ReLU激活函數(shù)的堆疊(記為 RepConv),如圖2(b)所示。因為3*3卷積在CPU和GPU上優(yōu)化和計算密度都更好,所以在增強表征能力的同時,可以有效利用計算資源同時增加推理速度。 然而隨模型容量增加,單路徑模型的計算代價和參數(shù)量呈指數(shù)級提升,所以改用CSPStackRep Block作為中大型網(wǎng)絡(luò)的Backbone,如圖2(c)所示。CSPStackRep Block由三個1×1卷積和兩個帶殘差連接的RepVGG block(訓(xùn)練使用)或RepConv(推理使用)組成的模塊堆疊。可以在不增加計算成本的前提下提升性能,做到準(zhǔn)確率和速度的權(quán)衡。
Neck
集成多尺度的特征是檢測模型常用且有效的手段,YOLOv6也不例外,在PAN的基礎(chǔ)上,把CSPBlock替換為RepBlock(小模型使用)或CSPStackRep Block(大模型使用),并調(diào)整寬度和深度,將YOLOv6的頸部命名為Rep-PAN。
Head
YOLOv5的檢測頭在分類和回歸上共享參數(shù),而FCOS和YOLOX將兩個分支解耦,在每個分支中引入兩個額外3×3卷積層提高性能。YOLOv6則采用混合通道策略構(gòu)建高效解耦頭,即中間3*3卷積只使用一個,Head的寬度由Backbone和Neck的寬度因子共同縮放,從而進(jìn)一步降低了計算成本和延遲。此外,YOLOv6使用基于錨點的Anchor free方式,預(yù)測錨點到邊界框四周的距離。
源碼
源碼地址;https://github.com/meituan/YOLOv6
安裝
git?clone?https://github.com/meituan/YOLOv6
cd?YOLOv6
pip?install?-r?requirements.txt
DIOR數(shù)據(jù)集
「DIOR」由23463張最優(yōu)遙感圖像和190288個目標(biāo)實例組成,這些目標(biāo)實例用軸向?qū)R的邊界框手動標(biāo)記,由192472個軸對齊的目標(biāo)邊界框注釋組成。數(shù)據(jù)集中圖像大小為800×800像素,空間分辨率為0.5m ~ 30m。該數(shù)據(jù)集分為訓(xùn)練驗證集(11725張圖像)和測試集(11738張圖像)。 「DIOR」是一個用于光學(xué)遙感圖像目標(biāo)檢測的大規(guī)?;鶞?zhǔn)數(shù)據(jù)集。涵蓋20個對象類。這20個對象類是飛機、機場、棒球場、籃球場、橋梁、煙囪、水壩、高速公路服務(wù)區(qū)、高速公路收費站、港口、高爾夫球場、地面田徑場、天橋、船舶、體育場、儲罐、網(wǎng)球場、火車站、車輛和風(fēng)磨。 論文地址:Object Detection in Optical Remote Sensing Images: A Survey and A New Benchmark
數(shù)據(jù)集處理
由于dior數(shù)據(jù)集是voc格式,所以需要將其轉(zhuǎn)換為yolo格式??梢詤⒄誽olo v6中給出的voc2yolo.py。
也可以參照以下的方法。
新建一個文件夾JPEGImages,將JPEGImages-test和PEGImages-trainval里的圖片都放進(jìn)JPEGImages里面。 代碼參考鏈接:https://blog.csdn.net/weixin_43365477/article/details/135622835
#?coding:utf-8
import?os
import?random
import?argparse
import?xml.etree.ElementTree?as?ET
from?os?import?getcwd
from?shutil?import?copyfile
parser?=?argparse.ArgumentParser()
#xml文件的地址,根據(jù)自己的數(shù)據(jù)進(jìn)行修改?xml一般存放在Annotations下
parser.add_argument('--xml_path',?default='DIOR/Annotations',?type=str,?help='input?xml?label?path')
#數(shù)據(jù)集的劃分,地址選擇自己數(shù)據(jù)下的ImageSets/Main
opt?=?parser.parse_args()
sets?=?['train',?'val',?'test']
classes?=?['airplane',?'airport',?'baseballfield',?'basketballcourt',?'bridge',?'chimney',?'dam',
??????????????'Expressway-Service-area',?'Expressway-toll-station',?'golffield',?'groundtrackfield',?'harbor',
??????????????'overpass',?'ship',?'stadium',?'storagetank',?'tenniscourt',?'trainstation',?'vehicle',?'windmill']
abs_path?=?os.getcwd()
print(abs_path)
#?if?not?os.path.exists('/DIOR'):
#?????os.makedirs('DIOR')
if?not?os.path.exists('DIOR_dataset/labels/'):
????os.makedirs('DIOR_dataset/labels/')
if?not?os.path.exists('DIOR_dataset/labels/train'):
????os.makedirs('DIOR_dataset/labels/train')
if?not?os.path.exists('DIOR_dataset_yolo/labels/test'):
????os.makedirs('DIOR_dataset/labels/test')
if?not?os.path.exists('DIOR_dataset_yolo/labels/val'):
????os.makedirs('DIOR_dataset/labels/val')
if?not?os.path.exists('DIOR_dataset/images/'):
????os.makedirs('DIOR_dataset/images/')
if?not?os.path.exists('DIOR_dataset/images/train'):
????os.makedirs('DIOR_dataset/images/train')
if?not?os.path.exists('DIOR_dataset/images/test'):
????os.makedirs('DIOR_dataset/images/test')
if?not?os.path.exists('DIOR_dataset/images/val'):
????os.makedirs('DIOR_dataset/images/val')
def?convert(size,?box):
????dw?=?1.?/?(size[0])
????dh?=?1.?/?(size[1])
????x?=?(box[0]?+?box[1])?/?2.0?-?1
????y?=?(box[2]?+?box[3])?/?2.0?-?1
????w?=?box[1]?-?box[0]
????h?=?box[3]?-?box[2]
????x?=?x?*?dw
????w?=?w?*?dw
????y?=?y?*?dh
????h?=?h?*?dh
????return?x,?y,?w,?h
def?convert_annotation(image_id,?path):
#輸入輸出文件夾,根據(jù)實際情況進(jìn)行修改
????in_file?=?open('DIOR/Annotations/%s.xml'?%?(image_id),?encoding='UTF-8')
????out_file?=?open('DIOR_dataset/labels/'?+?path?+?'/%s.txt'?%?(image_id),?'w')
????tree?=?ET.parse(in_file)
????root?=?tree.getroot()
????size?=?root.find('size')
????w?=?int(size.find('width').text)
????h?=?int(size.find('height').text)
????for?obj?in?root.iter('object'):
????????#difficult?=?obj.find('difficult').text
????????#difficult?=?obj.find('Difficult').text
????????cls?=?obj.find('name').text
????????if?cls?not?in?classes:
????????????continue
????????cls_id?=?classes.index(cls)
????????xmlbox?=?obj.find('bndbox')
????????b?=?(float(xmlbox.find('xmin').text),?float(xmlbox.find('xmax').text),?float(xmlbox.find('ymin').text),
?????????????float(xmlbox.find('ymax').text))
????????b1,?b2,?b3,?b4?=?b
????????#?標(biāo)注越界修正
????????if?b2?>?w:
????????????b2?=?w
????????if?b4?>?h:
????????????b4?=?h
????????b?=?(b1,?b2,?b3,?b4)
????????bb?=?convert((w,?h),?b)
????????out_file.write(str(cls_id)?+?"?"?+?"?".join([str(a)?for?a?in?bb])?+?'\n')
train_percent?=?0.6
test_percent?=?0.2
val_percent?=?0.2
xmlfilepath?=?opt.xml_path
#?txtsavepath?=?opt.txt_path
total_xml?=?os.listdir(xmlfilepath)
#?if?not?os.path.exists(txtsavepath):
#?????os.makedirs(txtsavepath)
num?=?len(total_xml)
list_index?=?range(num)
list_index?=?list(list_index)
random.shuffle(list_index)
train_nums?=?list_index[:int(num?*?train_percent)]
test_nums?=?list_index[int(num?*?train_percent):?int(num?*?test_percent)+int(num?*?train_percent)]
val_nums?=?list_index[int(num?*?test_percent)+int(num?*?train_percent):]
for?i?in?list_index:
????name?=?total_xml[i][:-4]
????if?i?in?train_nums:
????????convert_annotation(name,?'train')???#?lables
????????image_origin_path?=?'DIOR/JPEGImages/'?+?name?+?'.jpg'
????????image_target_path?=?'DIOR_dataset/images/train/'?+?name?+?'.jpg'
????????copyfile(image_origin_path,?image_target_path)
????if?i?in?test_nums:
????????convert_annotation(name,?'test')???#?lables
????????image_origin_path?=?'DIOR/JPEGImages/'?+?name?+?'.jpg'
????????image_target_path?=?'DIOR_dataset/images/test/'?+?name?+?'.jpg'
????????copyfile(image_origin_path,?image_target_path)
????if?i?in?val_nums:
????????convert_annotation(name,?'val')???#?lables
????????image_origin_path?=?'DIOR/JPEGImages/'?+?name?+?'.jpg'
????????image_target_path?=?'DIOR_dataset/images/val/'?+?name?+?'.jpg'
????????copyfile(image_origin_path,?image_target_path)
最終會生成yolo格式的數(shù)據(jù)集,且按訓(xùn)練集、驗證集、測試集劃分開。最終數(shù)據(jù)集形式如下
YOLO V6訓(xùn)練DIOR
YOLO V6的操作文檔可以看這里:https://yolov6-docs.readthedocs.io/zh-cn/latest/ 我們針對我們制作的DIOR數(shù)據(jù)集,來修改參數(shù)。
修改dataset.yaml
找到源代碼中data/dataset.yaml。
#?Please?insure?that?your?custom_dataset?are?put?in?same?parent?dir?with?YOLOv6_DIR
#?放入剛處理的DIOR數(shù)據(jù)集路徑
train:?.\DIOR_dataset\images\train?#?train?images
val:?.\DIOR_dataset\images\val?#?val?images
test:?.\DIOR_dataset\images\test?#?test?images?(optional)
#?whether?it?is?coco?dataset,?only?coco?dataset?should?be?set?to?True.
is_coco:?False
#?Classes,類別名
nc:?20??#?number?of?classes
names:?['airplane',?'airport',?'baseballfield',?'basketballcourt',?'bridge',?'chimney',?'dam',
??????????????'Expressway-Service-area',?'Expressway-toll-station',?'golffield',?'groundtrackfield',?'harbor',
??????????????'overpass',?'ship',?'stadium',?'storagetank',?'tenniscourt',?'trainstation',?'vehicle',?'windmill']??#?class?names
修改train.py
找到源代碼中tools/train.py。 修改img-size為800,其他選項根據(jù)注釋自行修改。
訓(xùn)練
運行train.py
測試
訓(xùn)練結(jié)束后,運行tools/eval.py。即可驗證精度(注意weights改成訓(xùn)練結(jié)果路徑),img-size為800。
輸出結(jié)果
運行tools/infer.py source為test圖片路徑,其它參數(shù)根據(jù)注釋選擇性修改。 部分測試結(jié)果如下。
總結(jié)
今天的分享就到這里,感興趣的可以自行下載數(shù)據(jù)集與源代碼試試。
往期精彩





本文由 mdnice 多平臺發(fā)布