美文网首页
TORCH03-08Darknet分类训练与使用

TORCH03-08Darknet分类训练与使用

作者: 杨强AT南京 | 来源:发表于2020-05-04 10:30 被阅读0次

      Darknet这种结构化的封装是一种学习启示,其中对图像数据的组织方式比较规律化,可以作为一种定式来学习。
      这个主题主要是用比较简单的分类训练来说明这种定式的数据组织方式,数据组织可能需要程式化的处理,这里写了了一些Python脚本程序来验证这一点。同时训练了两种网络AlexNet与VGG,再次证明少量的ImageNet数据在VGG收敛是个考验。
      除了程式化的训练数据预处理,可能标签工具的开发与应用也是一个方面,这个主题没有涉及。


    • 掌握YOLO的训练,我们直接使用现成的darknet实现来训练。

    • 相关的资源链接:

      1. yolo官网:https://pjreddie.com/darknet/yolo/
      2. darknet官网:https://pjreddie.com/darknet/
      3. github安装下载:
        1. Linux:https://github.com/pjreddie/darknet
        2. windows:https://github.com/AlexeyAB/darknet

    DarkNet的下载与安装

    下载

    • 地址:https://github.com/AlexeyAB/darknet
    window安装下载页面

    安装

    1. 解压
    解压目录
    1. 使用CMake -gui配置
      • 基本上采用默认就行
    使用CMake-GUI生成Visual Studio项目
    1. 使用Visual Studio打开工程
      • 记得使用管理员权限打开工程
    darknet.sln
    1. 开始编译
      • 选择【ALL BUILD】,在生成菜单选择【重新生成ALL BUILD】
      • 选择【INSTALL】,在生成菜单选择【重新生成ALL BUILD】
    开始编译
    1. 编译需要一定时间
    完整成功后提示7个任务完成
    1. 把安装路径设置为PATH,就可以在任何人地方使用darknet了
    设置PATH环境变量
    1. 记得设置几个PATH
      • 因为使用的是darknet提供的多线程库。
    记得配置darknet安装包自带的线程库
    1. 使用darknet工具
      • 记得重启控制终端或者powershell。
      • 下面使用随便一个非法的-选项来执行。会输出cuda与opencv的信息。具体的选项可以阅读C的源代码。
    测试命令是否可以运行

    使用Darknet

    • 可以提供很多选项来,使用darknet
    darknet的执行选项
    • 下面使用detect指令执行,指令的使用帮助可以阅读源代码获取。
      • ./darknet detect 模型文件 与训练的权重文件 检测的图像文件
    detect的调用代码
    • 测试需要准备的文件

      • 网络结构配置文件:在下载包的cfg目录中有很多模型文件,我们使用yolov3.cfg
      • 预训练的模型文件:可以去下载:https://pjreddie.com/darknet/yolo/
        • https://pjreddie.com/media/files/yolov3.weights
      • 一张需要侦测的图像:可以随便找一张,在下载包的data目录中有几张官方的侦测图像。
    • 运行

      • darknet detect .\cfg\yolov3.cfg .\yolov3.weights .\data\person.jpg
    执行detect结果

    使用python调用darknet

    • python调用darknet是加载dll或者so库来实现调用的。具体的范例在Darknet安装包提供了两个范例文件:

      • darknet.py
      • darknet_video.py
    • 其中需要确认下dll库的名字是正确的。

    DLL库名根据自己的编译结果改变
    • 这个例子实际就是python调用C编译动态库的例子。可以慢慢模仿调用。本质还是C/C++调用。

    使用Darknet训练定制数据集

    训练图像分类

    • 图像分类训练的指令是:

      • ./darknet classifier train cfg/imagenet1k.data cfg/csdarknet53-omega.cfg -topk
    • 需要准备的条件:

      1. 网络模型结构的配置文件:cfg文件
      2. 训练相关的数据集描述
        1. 描述文件: data文件
          1. train = data/imagenet1k.train.list

          2. valid = data/inet.val.list

          3. labels = data/imagenet.labels.list

          4. names = data/imagenet.shortnames.list

          5. classes = 1000

          6. top=5

          7. backup = backup

        2. 描述文件依赖的实际数据集

    DarkNet预训练的网络

    • 下面是Darknet官方提供的图像分类预先训练的网络列表
    DarkNet预训练的图像分类网络

    分类网络的模型选择

    • 下面使用VGG-D16作为测试
      • 模型下载:https://github.com/pjreddie/darknet/blob/master/cfg/vgg-16.cfg
    [net]
    # Training
    # batch=128
    # subdivisions=4
    
    # Testing
    batch=1
    subdivisions=1
    
    height=256
    width=256
    channels=3
    learning_rate=0.00001
    momentum=0.9
    decay=0.0005
    
    [crop]
    crop_height=224
    crop_width=224
    flip=1
    exposure=1
    saturation=1
    angle=0
    
    [convolutional]
    filters=64
    size=3
    stride=1
    pad=1
    activation=relu
    
    [convolutional]
    filters=64
    size=3
    stride=1
    pad=1
    activation=relu
    
    [maxpool]
    size=2
    stride=2
    
    [convolutional]
    filters=128
    size=3
    stride=1
    pad=1
    activation=relu
    
    [convolutional]
    filters=128
    size=3
    stride=1
    pad=1
    activation=relu
    
    [maxpool]
    size=2
    stride=2
    
    [convolutional]
    filters=256
    size=3
    stride=1
    pad=1
    activation=relu
    
    [convolutional]
    filters=256
    size=3
    stride=1
    pad=1
    activation=relu
    
    [convolutional]
    filters=256
    size=3
    stride=1
    pad=1
    activation=relu
    
    [maxpool]
    size=2
    stride=2
    
    [convolutional]
    filters=512
    size=3
    stride=1
    pad=1
    activation=relu
    
    [convolutional]
    filters=512
    size=3
    stride=1
    pad=1
    activation=relu
    
    [convolutional]
    filters=512
    size=3
    stride=1
    pad=1
    activation=relu
    
    [maxpool]
    size=2
    stride=2
    
    [convolutional]
    filters=512
    size=3
    stride=1
    pad=1
    activation=relu
    
    [convolutional]
    filters=512
    size=3
    stride=1
    pad=1
    activation=relu
    
    [convolutional]
    filters=512
    size=3
    stride=1
    pad=1
    activation=relu
    
    [maxpool]
    size=2
    stride=2
    
    [connected]
    output=4096
    activation=relu
    
    [dropout]
    probability=.5
    
    [connected]
    output=4096
    activation=relu
    
    [dropout]
    probability=.5
    
    [connected]
    output=1000
    activation=linear
    
    [softmax]
    groups=1
    
    
    
    

    数据集准备与处理

    • Darknet分类训练的数据集需要固定的组织格式。我们通过如下4类图像来进行处理。
    训练的图像数据集
    • 数据集与数据描述文件的对应关系
    数据描述文件与数据集的对应关系
    • 为了偷懒,我这类的测试集与训练集完全一样,如果愿意也可以准备一些测试集

      • shortname描述在训练的时候没有使用,在预测作为最终输出使用。
    • 实际上,上面描述文件可以使用python写个工具程序来完成

      • 规则清楚,代码的逻辑就很简单。
    • 描述文件自动生成程序

    import os
    import cv2
    
    class_names = ["organ", "palace", "roll", "skirt"]
    dataset_dir = "./imagenet2012"
    
    # 1. 生成shortnames.list文件
    
    # ------遍历每个目录 ------
    # 创建两个文件
    yolo_dir = "yolo_desc"   #描述文件的目录
    train_filename = "train.list"
    val_filename = "val.list"
    
    labels_filename = "labels.list"
    shortname_filename ="classnames.list"
    
    # 判定目录是否存在,不存在就创建
    if not os.path.exists(yolo_dir):
        os.makedirs(yolo_dir)
    # 在目录下创建两个文件,并后面循环中写入数据
    train_filename = os.path.join(yolo_dir, train_filename)
    val_filename =  os.path.join(yolo_dir, val_filename)
    
    fd_train = open(train_filename, 'w') 
    fd_val = open(val_filename, 'w') 
    # 2. 每个文件前的_name作为label.list的内容
    # 3. 写图像清单到train.list与val.list(我们训练集作为验证集)
    all_labels = []   # 保存内别标签
    for sub in class_names:
        # 构建图像的路径
        sub_dir = os.path.join(dataset_dir, sub)
        if os.path.exists(sub_dir):
            # 列出文件(子目录不处理)
            all_files = os.listdir(sub_dir)
            for f in all_files:
                full_filename = os.path.join(sub_dir, f)
                # 保存文件名到描述文件
                fd_train.write(full_filename + "\n")
                fd_val.write(full_filename + "\n")
                if os.path.isfile(full_filename):
                    # 解析文件名_前的标签
                    label_name = f.split("_")[0]
                    if not label_name in all_labels:
                        all_labels.append(label_name)
    
    # 关闭清单文件
    fd_train.close()
    fd_val.close()
    # 保存标签名与类别
    labels_filename = os.path.join(yolo_dir, labels_filename)
    shortname_filename =  os.path.join(yolo_dir, shortname_filename)
    fd_labels = open(labels_filename, 'w') 
    fd_shortnames = open(shortname_filename, 'w') 
    
    for label in all_labels:
        fd_labels.write(label + "\n")
        
    for short_name in class_names:
        fd_shortnames.write(short_name + "\n")
        
    fd_labels.close()
    fd_shortnames.close()
    
    
    • 创建的描述文件
    创建的描述文件
    • 最后生成data文件
      • 文件名:darknet_vgg16.data
    classes = 4
    train  = yolo_desc/train.list
    valid  = yolo_desc/val.list
    backup = yolo_desc
    labels = yolo_desc/labels.list
    names  = yolo_desc/classnames.list
    top=1
    
    

    分类训练

    • 确保cfg文件冲参数与我们设置的参数一致:
      • 注意:分类类别一定一致。
    修改最后输出为4
    • 直接在命令行下执行命令
      • ./darknet classifier train darknet_vgg16.data yolo_desc/vgg-16.cfg -topk
    训练过程截图
    • 训练的批次最好保持合适的数字

      • 建议64-128
    • 技巧:

      • 如果批次过大,可以考虑多次计算,然后累计误差计算梯度并更新。

    使用分类训练集结果验证/分类

    • 验证指令
      • darknet classifier valid darknet_vgg16.data yolo_desc/vgg-16.cfg yolo_desc/vgg-16_last.weights
    • 预测指令
      • darknet classifier predict darknet_vgg16.data yolo_desc/vgg-16.cfg yolo_desc/vgg-16_last.weights imagenet2012\roll\n03887697_36.JPEG
    VGG预测结果很差,概率小
    • 数据应该打乱训练。
    • 使用AlexNet网络训练,收敛的速度很快。

    训练图像侦测

    • 因为牵涉标注工具等的使用,我们单独用一个文档说明。

    相关文章

      网友评论

          本文标题:TORCH03-08Darknet分类训练与使用

          本文链接:https://www.haomeiwen.com/subject/rcdeghtx.html