Python 3 & Keras YOLO v3解析與實(shí)現(xiàn)

YOLOv3在YOLOv2的基礎(chǔ)進(jìn)行了一些改進(jìn),這些更改使其效果變得更好。其與SSD一樣準(zhǔn)確,但速度快了三倍,具體效果如下圖。本文對(duì)YOLO v3的改進(jìn)點(diǎn)進(jìn)行了總結(jié),并實(shí)現(xiàn)了一個(gè)基于Keras的YOLOv3檢測(cè)模型。如果先驗(yàn)邊界框不是最好的,但確實(shí)與真實(shí)對(duì)象的重疊超過某個(gè)閾值(這里是0.5),那么就忽略這次預(yù)測(cè)。YOLO v3只為每個(gè)真實(shí)對(duì)象分配一個(gè)邊界框,如果先驗(yàn)邊界框與真實(shí)對(duì)象不吻合,則不會(huì)產(chǎn)生坐標(biāo)或類別預(yù)測(cè)損失,只會(huì)產(chǎn)生物體預(yù)測(cè)損失。demo.py 文件提供了使用yolo v3進(jìn)行檢測(cè)的例子。

YOLOv3在YOLOv2的基礎(chǔ)進(jìn)行了一些改進(jìn),這些更改使其效果變得更好。 在320×320的圖像上,YOLOv3運(yùn)行速度達(dá)到了22.2毫秒,mAP為28.2。其與SSD一樣準(zhǔn)確,但速度快了三倍,具體效果如下圖。本文對(duì)YOLO v3的改進(jìn)點(diǎn)進(jìn)行了總結(jié),并實(shí)現(xiàn)了一個(gè)基于Keras的YOLOv3檢測(cè)模型。

在這里還是要推薦下我自己建的Python開發(fā)學(xué)習(xí)群:483546416,群里都是學(xué)Python開發(fā)的,如果你正在學(xué)習(xí)Python ,小編歡迎你加入,大家都是軟件開發(fā)黨,不定期分享干貨(只有Python軟件開發(fā)相關(guān)的),包括我自己整理的一份2018最新的Python進(jìn)階資料和高級(jí)開發(fā)教程,歡迎進(jìn)階中和進(jìn)想深入Python的小伙伴

inference

PaperYOLOv3: An Incremental Improvement

Official websitehttps://pjreddie.com/darknet/yolo

Githubhttps://github.com/xiaochus/YOLOv3

環(huán)境

Python 3.6

Tensorflow-gpu 1.5.0

Keras 2.1.3

OpenCV 3.4

改進(jìn)點(diǎn)

1.Darknet-53特征提取網(wǎng)絡(luò)

不同于Darknet-19,YOLO v3中使用了一個(gè)53層的卷積網(wǎng)絡(luò),這個(gè)網(wǎng)絡(luò)由殘差單元疊加而成。根據(jù)作者的實(shí)驗(yàn),在分類準(zhǔn)確度上跟效率的平衡上,這個(gè)模型比ResNet-101、 ResNet-152和Darknet-19表現(xiàn)得更好。

Darknet-53

2.邊界框預(yù)測(cè)

基本的坐標(biāo)偏移公式與YOLO v2相同。

box

YOLO v3使用邏輯回歸預(yù)測(cè)每個(gè)邊界框的分?jǐn)?shù)。 如果先驗(yàn)邊界框與真實(shí)框的重疊度比之前的任何其他邊界框都要好,則該值應(yīng)該為1。 如果先驗(yàn)邊界框不是最好的,但確實(shí)與真實(shí)對(duì)象的重疊超過某個(gè)閾值(這里是0.5),那么就忽略這次預(yù)測(cè)。YOLO v3只為每個(gè)真實(shí)對(duì)象分配一個(gè)邊界框,如果先驗(yàn)邊界框與真實(shí)對(duì)象不吻合,則不會(huì)產(chǎn)生坐標(biāo)或類別預(yù)測(cè)損失,只會(huì)產(chǎn)生物體預(yù)測(cè)損失。

3.類別預(yù)測(cè)

為了實(shí)現(xiàn)多標(biāo)簽分類,模型不再使用softmax函數(shù)作為最終的分類器,而是使用logistic作為分類器,使用 binary cross-entropy作為損失函數(shù)。

4.多尺度預(yù)測(cè)

不同于之前的YOLO,YOLO v3從三種不同尺度的特征圖譜上進(jìn)行預(yù)測(cè)任務(wù)。

在Darknet-53得到的特征圖的基礎(chǔ)上,經(jīng)過7個(gè)卷積得到第一個(gè)特征圖譜,在這個(gè)特征圖譜上做第一次預(yù)測(cè)。

然后從后向前獲得倒數(shù)第3個(gè)卷積層的輸出,進(jìn)行一次卷積一次x2上采樣,將上采樣特征與第43個(gè)卷積特征連接,經(jīng)過7個(gè)卷積得到第二個(gè)特征圖譜,在這個(gè)特征圖譜上做第二次預(yù)測(cè)。

然后從后向前獲得倒數(shù)第3個(gè)卷積層的輸出,進(jìn)行一次卷積一次x2上采樣,將上采樣特征與第26個(gè)卷積特征連接,經(jīng)過7個(gè)卷積得到第三個(gè)特征圖譜,在這個(gè)特征圖譜上做第三次預(yù)測(cè)。

每個(gè)預(yù)測(cè)任務(wù)得到的特征大小都為N ×N ×[3?(4+1+80)] ,N為格子大小,3為每個(gè)格子得到的邊界框數(shù)量, 4是邊界框坐標(biāo)數(shù)量,1是目標(biāo)預(yù)測(cè)值,80是類別數(shù)量。

out

實(shí)驗(yàn)

實(shí)現(xiàn)了一個(gè)輸入大小為(416, 416)的yolo v3檢測(cè)模型,模型使用了coco訓(xùn)練的權(quán)值文件。

權(quán)值文件轉(zhuǎn)換

參考了yad2k項(xiàng)目的轉(zhuǎn)換方法,我們?yōu)槠涮砑恿藥讉€(gè)新的層,用來將Darknet的網(wǎng)絡(luò)結(jié)構(gòu)和權(quán)值文件轉(zhuǎn)換為keras 2的網(wǎng)絡(luò)結(jié)構(gòu)和權(quán)值文件。

首先下載權(quán)值文件yolov3.weights

執(zhí)行下列命令轉(zhuǎn)換

python yad2k.py cfgyolo.cfg yolov3.weights datayolo.h5

檢測(cè)

demo.py文件提供了使用yolo v3進(jìn)行檢測(cè)的例子。

"""Demo for use yolo v3"""import osimport timeimport cv2import numpy as npfrom model.yolo_model import YOLOdef process_image(img): """Resize, reduce and expand image. # Argument: img: original image. # Returns image: ndarray(64, 64, 3), processed image. """ image = cv2.resize(img, (416, 416), interpolation=cv2.INTER_CUBIC) image = np.array(image, dtype='float32') image /= 255. image = np.expand_dims(image, axis=0) return imagedef get_classes(file): """Get classes name. # Argument: file: classes name for database. # Returns class_names: List, classes name. """ with open(file) as f: class_names = f.readlines() class_names = [c.strip() for c in class_names] return class_namesdef draw(image, boxes, scores, classes, all_classes): """Draw the boxes on the image. # Argument: image: original image. boxes: ndarray, boxes of objects. classes: ndarray, classes of objects. scores: ndarray, scores of objects. all_classes: all classes name. """ for box, score, cl in zip(boxes, scores, classes): x, y, w, h = box top = max(0, np.floor(x + 0.5).astype(int)) left = max(0, np.floor(y + 0.5).astype(int)) right = min(image.shape[1], np.floor(x + w + 0.5).astype(int)) bottom = min(image.shape[0], np.floor(y + h + 0.5).astype(int)) cv2.rectangle(image, (top, left), (right, bottom), (255, 0, 0), 2) cv2.putText(image, '{0} {1:.2f}'.format(all_classes[cl], score), (top, left - 6), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 1, cv2.LINE_AA)def detect(): """Use yolo v3 to detect images. """ yolo = YOLO(0.6, 0.5) file = 'data/coco_classes.txt' all_classes = get_classes(file) res = [] for (root, dirs, files) in os.walk('images/test'): if files: for f in files: print(f) path = os.path.join(root, f) image = cv2.imread(path) pimage = process_image(image) start = time.time() boxes, classes, scores = yolo.predict(pimage, image.shape) end = time.time() print(boxes) print(classes) print(scores) print(end - start) draw(image, boxes, scores, classes, all_classes) res.append(image) for r in res: cv2.namedWindow("detection") while True: cv2.imshow("detection", r) if cv2.waitKey(110) & 0xff == 27: breakif __name__ == '__main__': detect()

結(jié)果

運(yùn)行python demo.py

dog.png

eagle.png

giraffe.png

horses.png

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容