【Keras+TensorFlow+Yolo3】教你如何識別影視劇模型

一、前言

小王在畢設之餘瘋狂追劇,最近癡迷於《權利的遊戲》中龍母的美貌,太🉑了
在這裏插入圖片描述
當然,二丫 和 雪諾 的故事線也非常好看,我喜歡劇透,歡迎大家向我劇透。👀
在這裏插入圖片描述 在這裏插入圖片描述
當然了,小王也不能忘記畢設進度啦——好像是什麼手語識別來着?

哈哈哈哈,用最近了解的yolo跑個模型測試一下下吧,嘻嘻,效果還不錯!
在這裏插入圖片描述

咳咳,進入正題啦!

前面一篇文章算是打通了【yolo3識別】的任督二脈:
【Yolo3】一文掌握圖像標註、訓練、識別(Keras+TensorFlow-gpu)

梳理一下yolo3的知識點:

1.結構圖

參考CNN流程:
在這裏插入圖片描述
yolov3流程:
輸入圖片->darknet53(三個不同尺度特徵層)->yolo3解碼(卷積+採樣+結合)->(三個特徵結果)
在這裏插入圖片描述
圖片引用見logo

2.步驟

在這裏插入圖片描述
第一步:輸入圖片(調整爲416x416尺寸的圖片)

經過darknet53(5輪,23個殘差塊——對殘差網絡進行特徵提取)
在這裏插入圖片描述
分別得到✅3個不同尺度特徵層:13x13x102426x26x51252x52x256
其中13x13表示網格數、3表示3個先驗框、後面表示類別數。

第二步:13x13的特徵層經過5層卷積
在這裏插入圖片描述在這裏插入圖片描述
第三步:

  1. 再次進行3x3的卷積✅輸出特徵feat3 + 1x1卷積調整通道數
    其中(75分爲4+1+20):

    • 4表示:偏移量x_offset、y_offset、height、width
    • 1表示:置信度
    • 25表示:對象類別數
  2. 13x13尺度: 卷積+上採樣(步長爲2,即把長寬變爲1/2),再與16x16的特徵層結合。
    在這裏插入圖片描述在這裏插入圖片描述
    同理:16x16 五次卷積 -》3x3卷積✅輸出此層特徵feat2 + 1x1卷積調整通道數
    16x16 卷積+上採樣 -》
    同理:52x52 五次卷積 -》3x3卷積✅輸出此層特徵feat1 + 1x1卷積調整通道數
    在這裏插入圖片描述

相關函數:(結合源碼註釋消化,也可參考消化)

在這裏插入圖片描述

3.loss值

作用:判斷模型標準
在這裏插入圖片描述
特別說明:

  1. 先驗框的由來。先驗框數值越大,適合檢測大窗格13x13;對像素小,容易失真的圖片來說,先驗框數值越小檢測越精準,適合檢測小窗格52x52。

  2. loss函數的定義:
    存在的框:

    1. 編碼後長寬與xy偏移量的差距
    2. 置信度與1的差值(loss =| 1- iou |)
    3. 種類預測結果與真實值的對比

    不存在框: 最大iou與0的差值 (loss =| iou - 0|)

    iou的概念補充:一般指代模型預測的 bbox 和 Groud Truth 之間的交併比。
    在這裏插入圖片描述
    左圖爲預測目標位置,右圖爲原始目標位置;交併比就是預測正確部分Area of overrap比上兩個位置所佔的全部面積Area of Union;iou越大,預測效果越好。

  3. 三個檢測結果進行堆疊:

    • 左上和右下角進行標記
      在這裏插入圖片描述
    • 非極大抑制(去掉重疊的框,最多20個框)
      相同目標最近的幾個框都滿足要求,只顯示最大的那個框。
      在這裏插入圖片描述

大概就是這些內容啦,接下來從源碼入手!

二、手識別

本文是對手語數據集訓練的一個記錄,算是 tf2 - keras-yolo3 復現。

下面操作中包含了源碼可訓練,以及loss查看tensorboard的使用。

0.圖片

(選做,用你自己的標註數據)
本次使用的數據集來自:牛津大學Arpit Mittal, Andrew Zisserman和 Phil Torr

綜合的手圖像數據集共有13050個手實例被註釋。大於邊界框固定區域(1500平方像素)的手部實例被認爲“足夠大”以進行檢測,並用於評估。這給出了大約4170個高品質手實例。在收集數據時,對人的姿勢或可見度沒有任何限制,對環境也沒有任何限制。在每幅圖像中,都標註了人類可以清晰感知的所有手。註釋由一個邊界矩形組成,該矩形不必相對於手腕進行軸對齊。
在這裏插入圖片描述
資料下載:

我們用到的數據集爲VOC格式:我們僅下載evaluation_code.tar.gz(13.8M)即可。
在這裏插入圖片描述

1.下載項目框架

參考:重磅!YOLOv3最全復現代碼合集(含TensorFlow/PyTorch和Keras等)
我僅根據做出源碼註釋和修改:keras-tensorflow(https://github.com/qqwweee/keras-yolo3

  1. https://gitee.com/cungudafa/keras-yolo3

  2. 單獨下載yolov3.weights 權重,放在項目根目錄下

  3. 將 DarkNet 的.weights文件轉換成 Keras 的.h5文件

    python convert.py -w yolov3.cfg yolov3.weights model_data/yolo_weights.h5
    

2.標籤分類

  1. 將下載的數據集複製到項目路徑下:
    在這裏插入圖片描述
    事實是數據集有400+圖片,我訓練起來太累了,容易過擬合,這裏只用了009985-010028共40+張圖片進行訓練在這裏插入圖片描述
    開源數據集nb😁,不用手動找資源,再標註啦,嘻嘻嘻!支持開源~😁
    在這裏插入圖片描述 在這裏插入圖片描述 在這裏插入圖片描述
  2. voc標籤格式:voc_annotation.py (後面我重構了一下項目結構,可能有出入)
    在這裏插入圖片描述
    會在ImageSets/Main目錄下生成對應文件
    在這裏插入圖片描述
  3. yolo標籤格式:yolo_annotation.py
    1. 修改classes爲你訓練的對象(我這裏是hand)
      在這裏插入圖片描述
      查看標籤:在VOCdevkit\VOC2007\Annotations\009985_hand.xml
      在這裏插入圖片描述
    2. 這裏需要修改一下float格式
      b = (int(float(xmlbox.find('xmin').text)), int(float(xmlbox.find('ymin').text)),
                   int(float(xmlbox.find('xmax').text)), int(float(xmlbox.find('ymax').text)))
      
    3. 執行yolo_annotation.py,在model_data目錄下生成yolo標籤格式
      在這裏插入圖片描述
      現在我們就得到了model_data(標籤)

3.訓練

Keras2.3.1 + TensorFlow-gpu2.1.0 + cuda 10.0

涉及到的文件和函數目錄
原始目錄:tree_old目錄
我重新整合了一下目錄結構:tree目錄

根目錄
│
│  train.py             --- 模型訓練    
│
├─data            		--- 參數配置
│  │  yolo_weights.h5	--- 權重文件
│  │  
│  ├─anchors
│  │      coco_anchors.txt	--- 先驗參數
│  │      
│  ├─classes
│  │      coco.name
│  │      voc_classes.txt --- 標籤樣本名稱
│  │      
│  └─dataset
│          test.txt
│          train.txt
│          val.txt
│      
└─core
   │  darknet53.py		--- 特徵提取網絡
   │  loss.py			--- 損失函數
   │  yolo3.py 			--- yolo網絡
   └─  utils.py      	--- 圖片加載工具類  

運行train.py 50輪和100輪

(之前我更新了一次keras,導致之前的修改被抹除了,這裏修改一下:)
報錯:在這裏插入圖片描述
參考:'Model’object has no attribute '_get_distribution_strategy’的一種解決方案


問題2:(運行到64輪時,VSCode崩掉了,這裏接着之前的模型運行)
在這裏插入圖片描述
註釋掉前50輪,直接model.load_weights('logs/ep064-loss16.422-val_loss20.496.h5')你覺得合適的版本,
再把 initial_epoch 改爲當前的序號可以接着運行。在這裏插入圖片描述
這是絕招了!

最終我運行到100輪時,loss值爲19.2
在這裏插入圖片描述

神經網絡可視化分析:

  1. 讀取運行時記錄:(這裏train和validation分別記錄)
    在這裏插入圖片描述

  2. 在路徑下打開控制檯運行:

    tensorboard --logdir=logs\
    

    tensorboard 是 tensorflow安裝時就附帶安裝的可視化工具🍳,別說你還沒用過。
    在這裏插入圖片描述

  3. 打開瀏覽器查看:http://localhost:6006/
    在這裏插入圖片描述
    其中GRAPHS可以打印出我們的神經網絡結構:(可以導出爲png圖片)
    在這裏插入圖片描述

4.測試

修改yolo.py的模型路徑,socre和iou——是顯示檢測結果畫框框的重要因素:

"score": 0.45, # 框置信度閾值,小於閾值的框被刪除,需要的框較多,則調低閾值,需要的框較少,則調高閾值
"iou": 0.3, # 同類別框的IoU閾值,大於閾值的重疊框被刪除,重疊物體較多,則調高閾值,重疊物體較少,則調低閾值

在這裏插入圖片描述
直接檢測:predict.py

from keras.layers import Input
from yolo import YOLO,detect_video
from PIL import Image

def for_img(yolo):
    path = 'D:/myworkspace/dataset/test.jpg'
    try:
        image = Image.open(path)
    except:
        print('Open Error! Try again!')
    else:
        r_image = yolo.detect_image(image)
        r_image.show()
    yolo.close_session()


def for_video(yolo):
    detect_video(yolo, "D:/myworkspace/dataset/xuanya.mp4", "D:/myworkspace/dataset/xuanya_detect.mp4")


if __name__ == '__main__':
    _yolo = YOLO()

    for_img(_yolo)
    # for_video(_yolo)

yolo.py測試部分報錯:
在這裏插入圖片描述
最終參考:tf2-keras-yolo3,可以直接對圖片和視頻進行檢測。


因爲模型是訓練一次就好了,測試部分我單獨提出封裝到代碼裏:(後面在這基礎上還要做手語識別,前途明朗~)
識別部分——代碼下載鏈接

yolo_video.py:

import sys
import argparse
from yolo import YOLO, detect_video
from PIL import Image

def detect_img(yolo):
    while True:
        print("Press 'q' quit !")
        img = input('Input image filename:')
        if img.lower() == 'q':
            exit(0)
        try:
            image = Image.open(img)
        except:
            print('Open Error! Try again!')
            continue
        else:            
            r_image = yolo.detect_image(image)
            r_image.show()
    yolo.close_session()

FLAGS = None

if __name__ == '__main__':
    # class YOLO defines the default value, so suppress any default here
    parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
    '''
    Command line options
    '''
    parser.add_argument(
        '--model_path', type=str,
        help='path to model weight file, default ' + YOLO.get_defaults("model_path")
    )

    parser.add_argument(
        '--anchors_path', type=str,
        help='path to anchor definitions, default ' + YOLO.get_defaults("anchors_path")
    )

    parser.add_argument(
        '--classes_path', type=str,
        help='path to class definitions, default ' + YOLO.get_defaults("classes_path")
    )

    parser.add_argument(
        '--gpu_num', type=int,
        help='Number of GPU to use, default ' + str(YOLO.get_defaults("gpu_num"))
    )

    parser.add_argument(
        '--image', default=False, action="store_true",
        help='Image detection mode, will ignore all positional arguments'
    )
    '''
    Command line positional arguments -- for video detection mode
    '''
    parser.add_argument(
        "--input", nargs='?', type=str,required=False,default='./path2your_video',
        help = "Video input path"
    )

    parser.add_argument(
        "--output", nargs='?', type=str, default="",
        help = "[Optional] Video output path"
    )

    FLAGS = parser.parse_args()

    if FLAGS.image:
        """
        Image detection mode, disregard any remaining command line arguments
        """
        print("Image detection mode")
        if "input" in FLAGS:
            print(" Ignoring remaining command line arguments: " + FLAGS.input + "," + FLAGS.output)
        detect_img(YOLO(**vars(FLAGS)))
    elif "input" in FLAGS:
        detect_video(YOLO(**vars(FLAGS)), FLAGS.input, FLAGS.output)
    else:
        print("Must specify at least video_input_path.  See usage with --help.")

或者直接檢測

# 圖片檢測
python yolo_video.py --image
再輸入圖片路徑


# 視頻檢測
python yolo_video.py --input img\test.mp4

圖片識別率都不錯:
在這裏插入圖片描述
在這裏插入圖片描述

視頻檢測最高識別率爲57%
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述 在這裏插入圖片描述
0.5秒檢測一幀,正確率在70%左右

後面會用來檢測我的手語:Python+Opencv2(三)保存視頻關鍵幀

手語手勢識別效果最高88%,非常nice!
在這裏插入圖片描述
yolo目標檢測,比過擬合的模型和openpose粗略估計好很多yo~~
在這裏插入圖片描述 在這裏插入圖片描述

三、總結

40+張圖片,跑的yolov3模型240M,檢測效果比較滿意啦。這裏檢測的是人手,如果把標註改爲權遊的龍,也是能檢測出來的哦,just try it!

環境:【GPU】win10 (1050Ti)+anaconda3+python3.6+CUDA10.0+tensorflow-gpu2.1.0

僅對於yolov3模型來說,模型較大,如果轉換成yolo-tiny甚至是yolo-nano會不會更方便移植。

生命不息,學習不止!😎


源碼:

  1. 訓練: https://gitee.com/cungudafa/keras-yolo3

  2. 識別部分:keras-yolo3-recognize

補充,識別部分函數調用圖:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章