日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

深度学习目标检测系列:一文弄懂YOLO算法|附Python源码

發(fā)布時(shí)間:2024/8/23 python 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深度学习目标检测系列:一文弄懂YOLO算法|附Python源码 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在之前的文章中,介紹了計(jì)算機(jī)視覺(jué)領(lǐng)域中目標(biāo)檢測(cè)的相關(guān)方法——RCNN系列算法原理,以及Faster RCNN的實(shí)現(xiàn)。這些算法面臨的一個(gè)問(wèn)題,不是端到端的模型,幾個(gè)構(gòu)件拼湊在一起組成整個(gè)檢測(cè)系統(tǒng),操作起來(lái)比較復(fù)雜,本文將介紹另外一個(gè)端到端的方法——YOLO算法,該方法操作簡(jiǎn)便且仿真速度快,效果也不差。

YOLO算法是什么?

? ? ? ?YOLO框架(You Only Look Once)與RCNN系列算法不一樣,是以不同的方式處理對(duì)象檢測(cè)。它將整個(gè)圖像放在一個(gè)實(shí)例中,并預(yù)測(cè)這些框的邊界框坐標(biāo)和及所屬類(lèi)別概率。使用YOLO算法最大優(yōu)的點(diǎn)是速度極快,每秒可處理45幀,也能夠理解一般的對(duì)象表示。

YOLO框架如何運(yùn)作?

? ? ? ?在本節(jié)中,將介紹YOLO用于檢測(cè)給定圖像中的對(duì)象的處理步驟。

  • 首先,輸入圖像:

?

  • 然后,YOLO將輸入圖像劃分為網(wǎng)格形式(例如3 X 3):

?

  • 最后,對(duì)每個(gè)網(wǎng)格應(yīng)用圖像分類(lèi)和定位處理,獲得預(yù)測(cè)對(duì)象的邊界框及其對(duì)應(yīng)的類(lèi)概率。

? ? ? ?整個(gè)過(guò)程是不是很清晰,下面逐一詳細(xì)介紹。首先需要將標(biāo)記數(shù)據(jù)傳遞給模型以進(jìn)行訓(xùn)練。假設(shè)已將圖像劃分為大小為3 X 3的網(wǎng)格,且總共只有3個(gè)類(lèi)別,分別是行人(c1)、汽車(chē)(c2)和摩托車(chē)(c3)。因此,對(duì)于每個(gè)單元格,標(biāo)簽y將是一個(gè)八維向量:


其中:

  • pc定義對(duì)象是否存在于網(wǎng)格中(存在的概率);
  • bx、by、bh、bw指定邊界框;
  • c1、c2、c3代表類(lèi)別。如果檢測(cè)對(duì)象是汽車(chē),則c2位置處的值將為1,c1和c3處的值將為0;

? ? ? ?假設(shè)從上面的例子中選擇第一個(gè)網(wǎng)格:


? ? ? ?由于此網(wǎng)格中沒(méi)有對(duì)象,因此pc將為零,此網(wǎng)格的y標(biāo)簽將為:


? ? ? ???意味著其它值是什么并不重要,因?yàn)榫W(wǎng)格中沒(méi)有對(duì)象。下面舉例另一個(gè)有車(chē)的網(wǎng)格(c2=1):


? ? ? ?在為此網(wǎng)格編寫(xiě)y標(biāo)簽之前,首先要了解YOLO如何確定網(wǎng)格中是否存在實(shí)際對(duì)象。大圖中有兩個(gè)物體(兩輛車(chē)),因此YOLO將取這兩個(gè)物體的中心點(diǎn),物體將被分配到包含這些物體中心的網(wǎng)格中。中心點(diǎn)左側(cè)網(wǎng)格的y標(biāo)簽會(huì)是這樣的:


? ? ? ?由于此網(wǎng)格中存在對(duì)象,因此pc將等于1,bx、by、bh、bw將相對(duì)于正在處理的特定網(wǎng)格單元計(jì)算。由于檢測(cè)出的對(duì)象是汽車(chē),所以c2=1,c1和c3均為0。對(duì)于9個(gè)網(wǎng)格中的每一個(gè)單元格,都具有八維輸出向量。最終的輸出形狀為3X3X8。
? ? ? ?使用上面的例子(輸入圖像:100X100X3,輸出:3X3X8),模型將按如下方式進(jìn)行訓(xùn)練:


? ? ? ?使用經(jīng)典的CNN網(wǎng)絡(luò)構(gòu)建模型,并進(jìn)行模型訓(xùn)練。在測(cè)試階段,將圖像傳遞給模型,經(jīng)過(guò)一次前向傳播就得到輸出y。為了簡(jiǎn)單起見(jiàn),使用3X3網(wǎng)格解釋這一點(diǎn),但通常在實(shí)際場(chǎng)景中會(huì)采用更大的網(wǎng)格(比如19X19)。
? ? ? ?即使一個(gè)對(duì)象跨越多個(gè)網(wǎng)格,它也只會(huì)被分配到其中點(diǎn)所在的單個(gè)網(wǎng)格。可以通過(guò)增加更多網(wǎng)格來(lái)減少多個(gè)對(duì)象出現(xiàn)在同一網(wǎng)格單元中的幾率。

如何編碼邊界框?

? ? ? ?如前所述,bx、by、bh和bw是相對(duì)于正在處理的網(wǎng)格單元計(jì)算而言的。下面通過(guò)一個(gè)例子來(lái)說(shuō)明這一點(diǎn)。以包含汽車(chē)的右邊網(wǎng)格為例:


? ? ? ?由于bx、by、bh和bw將僅相對(duì)于該網(wǎng)格計(jì)算。此網(wǎng)格的y標(biāo)簽將為:


? ? ? ?由于這個(gè)網(wǎng)格中有一個(gè)對(duì)象汽車(chē),所以pc=1、c2=1。現(xiàn)在,看看如何決定bx、by、bh和bw的取值。在YOLO中,分配給所有網(wǎng)格的坐標(biāo)都如下圖所示:


? ? ? ?bx、by是對(duì)象相對(duì)于該網(wǎng)格的中心點(diǎn)的x和y坐標(biāo)。在例子中,近似bx=0.4和by=0.3:


? ? ? ?bh是邊界框的高度與相應(yīng)單元網(wǎng)格的高度之比,在例子中約為0.9:bh=0.9,bw是邊界框的寬度與網(wǎng)格單元的寬度之比,bw=0.5。此網(wǎng)格的y標(biāo)簽將為:


? ? ? ?請(qǐng)注意,bx和by將始終介于0和1之間,因?yàn)橹行狞c(diǎn)始終位于網(wǎng)格內(nèi),而在邊界框的尺寸大于網(wǎng)格尺寸的情況下,bh和bw可以大于1。

非極大值抑制|Non-Max Suppression

? ? ? ?這里有一些思考的問(wèn)題——如何判斷預(yù)測(cè)的邊界框是否是一個(gè)好結(jié)果(或一個(gè)壞結(jié)果)?單元格之間的交叉點(diǎn),計(jì)算實(shí)際邊界框和預(yù)測(cè)的邊界框的并集交集。假設(shè)汽車(chē)的實(shí)際和預(yù)測(cè)邊界框如下所示:


? ? ? ?其中,紅色框是實(shí)際的邊界框,藍(lán)色框是預(yù)測(cè)的邊界框。如何判斷它是否是一個(gè)好的預(yù)測(cè)呢?IoU將計(jì)算這兩個(gè)框的并集交叉區(qū)域:

  • IoU =交叉面積/聯(lián)合的面積;
  • 在本例中:

    • IoU =黃色面積/綠色面積;

? ? ? ?如果IoU大于0.5,就可以說(shuō)預(yù)測(cè)足夠好。0.5是在這里采取的任意閾值,也可以根據(jù)具體問(wèn)題進(jìn)行更改。閾值越大,預(yù)測(cè)就越準(zhǔn)確。
? ? ? ?還有一種技術(shù)可以顯著提高YOLO的效果——非極大值抑制。
? ? ? ?對(duì)象檢測(cè)算法最常見(jiàn)的問(wèn)題之一是,它不是一次僅檢測(cè)出一次對(duì)象,而可能獲得多次檢測(cè)結(jié)果。假設(shè):


? ? ? ?上圖中,汽車(chē)不止一次被識(shí)別,那么如何判定邊界框呢。非極大值抑可以解決這個(gè)問(wèn)題,使得每個(gè)對(duì)象只能進(jìn)行一次檢測(cè)。下面了解該方法的工作原理。

  • 1.它首先查看與每次檢測(cè)相關(guān)的概率并取最大的概率。在上圖中,0.9是最高概率,因此首先選擇概率為0.9的方框:

?

  • 2.現(xiàn)在,它會(huì)查看圖像中的所有其他框。與當(dāng)前邊界框較高的IoU的邊界框?qū)⒈灰种啤R虼?#xff0c;在示例中,0.6和0.7概率的邊界框?qū)⒈灰种?#xff1a;

?

  • 3.在部分邊界框被抑制后,它會(huì)從概率最高的所有邊界框中選擇下一個(gè),在例子中為0.8的邊界框:

?

  • 4.再次計(jì)算與該邊界框相連邊界框的IoU,去掉較高IoU值的邊界框:

?

  • 5.重復(fù)這些步驟,得到最后的邊界框:

?

? ? ? ?以上就是非極大值抑制的全部?jī)?nèi)容,總結(jié)一下關(guān)于非極大值抑制算法的要點(diǎn):

  • 丟棄概率小于或等于預(yù)定閾值(例如0.5)的所有方框;
  • 對(duì)于剩余的邊界框:
  • 選擇具有最高概率的邊界框并將其作為輸出預(yù)測(cè);
  • 計(jì)算相關(guān)聯(lián)的邊界框的IoU值,舍去IoU大于閾值的邊界框;
  • 重復(fù)步驟2,直到所有邊界框都被視為輸出預(yù)測(cè)或被舍棄;

Anchor Boxes

? ? ? ?在上述內(nèi)容中,每個(gè)網(wǎng)格只能識(shí)別一個(gè)對(duì)象。但是如果單個(gè)網(wǎng)格中有多個(gè)對(duì)象呢?這就行需要了解 Anchor Boxes的概念。假設(shè)將下圖按照3X3網(wǎng)格劃分:


? ? ? ?獲取對(duì)象的中心點(diǎn),并根據(jù)其位置將對(duì)象分配給相應(yīng)的網(wǎng)格。在上面的示例中,兩個(gè)對(duì)象的中心點(diǎn)位于同一網(wǎng)格中:


? ? ? ?上述方法只會(huì)獲得兩個(gè)邊界框其中的一個(gè),但是如果使用Anchor Boxes,可能會(huì)輸出兩個(gè)邊界框!我們?cè)撛趺醋瞿?#xff1f;首先,預(yù)先定義兩種不同的形狀,稱(chēng)為Anchor Boxes。對(duì)于每個(gè)網(wǎng)格將有兩個(gè)輸出。這里為了易于理解,這里選取兩個(gè)Anchor Boxes,也可以根據(jù)實(shí)際情況增加Anchor Boxes的數(shù)量:

  • 沒(méi)有Anchor Boxes的YOLO輸出標(biāo)簽如下所示:

  • 有Anchor Boxes的YOLO輸出標(biāo)簽如下所示:

?


? ? ? ?前8行屬于Anchor Boxes1,其余8行屬于Anchor Boxes2。基于邊界框和框形狀的相似性將對(duì)象分配給Anchor Boxes。由于Anchor Boxes1的形狀類(lèi)似于人的邊界框,后者將被分配給Anchor Boxes1,并且車(chē)將被分配給Anchor Boxes2.在這種情況下的輸出,將是3X3X16大小。
? ? ? ?因此,對(duì)于每個(gè)網(wǎng)格,可以根據(jù)Anchor Boxes的數(shù)量檢測(cè)兩個(gè)或更多個(gè)對(duì)象。

結(jié)合思想

? ? ? ?在本節(jié)中,首先介紹如何訓(xùn)練YOLO模型,然后是新的圖像進(jìn)行預(yù)測(cè)。

訓(xùn)練

? ? ? ?訓(xùn)練模型時(shí),輸入數(shù)據(jù)是由圖像及其相應(yīng)的y標(biāo)簽構(gòu)成。樣例如下:


? ? ? ?假設(shè)每個(gè)網(wǎng)格有兩個(gè)Anchor Boxes,并劃分為3X3網(wǎng)格,并且有3個(gè)不同的類(lèi)別。因此,相應(yīng)的y標(biāo)簽具有3X3X16的形狀。訓(xùn)練過(guò)程的完成方式就是將特定形狀的圖像映射到對(duì)應(yīng)3X3X16大小的目標(biāo)。

測(cè)試

? ? ? ?對(duì)于每個(gè)網(wǎng)格,模型將預(yù)測(cè)·3X3X16·大小的輸出。該預(yù)測(cè)中的16個(gè)值將與訓(xùn)練標(biāo)簽的格式相同。前8個(gè)值將對(duì)應(yīng)于Anchor Boxes1,其中第一個(gè)值將是該網(wǎng)絡(luò)中對(duì)象的概率,2-5的值將是該對(duì)象的邊界框坐標(biāo),最后三個(gè)值表明對(duì)象屬于哪個(gè)類(lèi)。以此類(lèi)推。
? ? ? ?最后,非極大值抑制方法將應(yīng)用于預(yù)測(cè)框以獲得每個(gè)對(duì)象的單個(gè)預(yù)測(cè)結(jié)果。
? ? ? ?以下是YOLO算法遵循的確切維度和步驟:

  • 準(zhǔn)備對(duì)應(yīng)的圖像(608,608,3);
  • 將圖像傳遞給卷積神經(jīng)網(wǎng)絡(luò)(CNN),該網(wǎng)絡(luò)返回(19,19,5,85)維輸出;
  • 輸出的最后兩個(gè)維度被展平以獲得(19,19,425)的輸出量:

    • 19×19網(wǎng)格的每個(gè)單元返回425個(gè)數(shù)字;
    • 425=5 * 85,其中5是每個(gè)網(wǎng)格的Anchor Boxes數(shù)量;
    • 85= 5+80,其中5表示(pc、bx、by、bh、bw),80是檢測(cè)的類(lèi)別數(shù);
  • 最后,使用IoU和非極大值抑制去除重疊框;

YOLO算法實(shí)現(xiàn)

? ? ? ?本節(jié)中用于實(shí)現(xiàn)YOLO的代碼來(lái)自Andrew NG的GitHub存儲(chǔ)庫(kù),需要下載此zip文件,其中包含運(yùn)行此代碼所需的預(yù)訓(xùn)練權(quán)重。
? ? ? ?首先定義一些函數(shù),這些函數(shù)將用來(lái)選擇高于某個(gè)閾值的邊界框,并對(duì)其應(yīng)用非極大值抑制。首先,導(dǎo)入所需的庫(kù):

import os import matplotlib.pyplot as plt from matplotlib.pyplot import imshow import scipy.io import scipy.misc import numpy as np import pandas as pd import PIL import tensorflow as tf from skimage.transform import resize from keras import backend as K from keras.layers import Input, Lambda, Conv2D from keras.models import load_model, Model from yolo_utils import read_classes, read_anchors, generate_colors, preprocess_image, draw_boxes, scale_boxes from yad2k.models.keras_yolo import yolo_head, yolo_boxes_to_corners, preprocess_true_boxes, yolo_loss, yolo_body%matplotlib inline

然后,實(shí)現(xiàn)基于概率和閾值過(guò)濾邊界框的函數(shù):

def yolo_filter_boxes(box_confidence, boxes, box_class_probs, threshold = .6):box_scores = box_confidence*box_class_probsbox_classes = K.argmax(box_scores,-1)box_class_scores = K.max(box_scores,-1)filtering_mask = box_class_scores>thresholdscores = tf.boolean_mask(box_class_scores,filtering_mask)boxes = tf.boolean_mask(boxes,filtering_mask)classes = tf.boolean_mask(box_classes,filtering_mask)return scores, boxes, classes

之后,實(shí)現(xiàn)計(jì)算IoU的函數(shù):

def iou(box1, box2):xi1 = max(box1[0],box2[0])yi1 = max(box1[1],box2[1])xi2 = min(box1[2],box2[2])yi2 = min(box1[3],box2[3])inter_area = (yi2-yi1)*(xi2-xi1)box1_area = (box1[3]-box1[1])*(box1[2]-box1[0])box2_area = (box2[3]-box2[1])*(box2[2]-box2[0])union_area = box1_area+box2_area-inter_areaiou = inter_area/union_areareturn iou

然后,實(shí)現(xiàn)非極大值抑制的函數(shù):

def yolo_non_max_suppression(scores, boxes, classes, max_boxes = 10, iou_threshold = 0.5):max_boxes_tensor = K.variable(max_boxes, dtype='int32')K.get_session().run(tf.variables_initializer([max_boxes_tensor]))nms_indices = tf.image.non_max_suppression(boxes,scores,max_boxes,iou_threshold)scores = K.gather(scores,nms_indices)boxes = K.gather(boxes,nms_indices)classes = K.gather(classes,nms_indices)return scores, boxes, classes

隨機(jī)初始化下大小為(19,19,5,85)的輸出向量:

yolo_outputs = (tf.random_normal([19, 19, 5, 1], mean=1, stddev=4, seed = 1),tf.random_normal([19, 19, 5, 2], mean=1, stddev=4, seed = 1),tf.random_normal([19, 19, 5, 2], mean=1, stddev=4, seed = 1),tf.random_normal([19, 19, 5, 80], mean=1, stddev=4, seed = 1))

最后,實(shí)現(xiàn)一個(gè)將CNN的輸出作為輸入并返回被抑制的邊界框的函數(shù):

def yolo_eval(yolo_outputs, image_shape = (720., 1280.), max_boxes=10, score_threshold=.6, iou_threshold=.5):box_confidence, box_xy, box_wh, box_class_probs = yolo_outputsboxes = yolo_boxes_to_corners(box_xy, box_wh)scores, boxes, classes = yolo_filter_boxes(box_confidence, boxes, box_class_probs, threshold = score_threshold)boxes = scale_boxes(boxes, image_shape)scores, boxes, classes = yolo_non_max_suppression(scores, boxes, classes, max_boxes, iou_threshold)return scores, boxes, classes

使用yolo_eval函數(shù)對(duì)之前創(chuàng)建的隨機(jī)輸出向量進(jìn)行預(yù)測(cè):

scores, boxes, classes = yolo_eval(yolo_outputs) with tf.Session() as test_b:print("scores[2] = " + str(scores[2].eval()))print("boxes[2] = " + str(boxes[2].eval()))print("classes[2] = " + str(classes[2].eval()))

?


score表示對(duì)象在圖像中的可能性,boxes返回檢測(cè)到的對(duì)象的(x1,y1,x2,y2)坐標(biāo),classes表示識(shí)別對(duì)象所屬的類(lèi)。
現(xiàn)在,在新的圖像上使用預(yù)訓(xùn)練的YOLO算法,看看其工作效果:

sess = K.get_session() class_names = read_classes("model_data/coco_classes.txt") anchors = read_anchors("model_data/yolo_anchors.txt")yolo_model = load_model("model_data/yolo.h5")

在加載類(lèi)別信息和預(yù)訓(xùn)練模型之后,使用上面定義的函數(shù)來(lái)獲取·yolo_outputs·。

yolo_outputs = yolo_head(yolo_model.output, anchors, len(class_names))

之后,定義一個(gè)函數(shù)來(lái)預(yù)測(cè)邊界框并在圖像上標(biāo)記邊界框:

def predict(sess, image_file):image, image_data = preprocess_image("images/" + image_file, model_image_size = (608, 608))out_scores, out_boxes, out_classes = sess.run([scores, boxes, classes], feed_dict={yolo_model.input: image_data, K.learning_phase(): 0})print('Found {} boxes for {}'.format(len(out_boxes), image_file))# Generate colors for drawing bounding boxes.colors = generate_colors(class_names)# Draw bounding boxes on the image filedraw_boxes(image, out_scores, out_boxes, out_classes, class_names, colors)# Save the predicted bounding box on the imageimage.save(os.path.join("out", image_file), quality=90)# Display the results in the notebookoutput_image = scipy.misc.imread(os.path.join("out", image_file))plt.figure(figsize=(12,12))imshow(output_image)return out_scores, out_boxes, out_classes

接下來(lái),將使用預(yù)測(cè)函數(shù)讀取圖像并進(jìn)行預(yù)測(cè):

img = plt.imread('images/img.jpg') image_shape = float(img.shape[0]), float(img.shape[1]) scores, boxes, classes = yolo_eval(yolo_outputs, image_shape)

最后,輸出預(yù)測(cè)結(jié)果:

out_scores, out_boxes, out_classes = predict(sess, "img.jpg")

?


以上就是YOLO算法的全部?jī)?nèi)容

?


原文鏈接
本文為云棲社區(qū)原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。

總結(jié)

以上是生活随笔為你收集整理的深度学习目标检测系列:一文弄懂YOLO算法|附Python源码的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。