【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

补充,识别部分函数调用图:
在这里插入图片描述

©️2020 CSDN 皮肤主题: 终极编程指南 设计师:CSDN官方博客 返回首页