精华内容
下载资源
问答
  • Intellij idea 报错:Error : java 不支持发行版本5

    万次阅读 多人点赞 2018-09-04 23:47:31
    在Intellij idea中新建了一个Maven项目,运行时报错如下:Error : java 不支持发行版本5 本地运行用的是JDK9,测试Java的Stream操作,报错应该是项目编译配置使用的Java版本不对,需要检查一下项目及环境使用的...

    推荐解决方式:感谢评论区另一位博友 Fumoon 提供的方案:https://blog.csdn.net/qq_42583206/article/details/108375173   

    如按上述方式解决了问题,下文可以忽略。   

    -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

         在Intellij idea中新建了一个Maven项目,运行时报错如下:Error : java 不支持发行版本5

           本地运行用的是JDK9,测试Java的Stream操作,报错应该是项目编译配置使用的Java版本不对,需要检查一下项目及环境使用的Java编译版本配置。

           《1》在Intellij中点击“File” -->“Project Structure”,看一下“Project”和“Module”栏目中Java版本是否与本地一致:

     

    如果不一致,改成本地使用的Java版本。

          《2》点击“Settings”-->“Bulid, Execution,Deployment”-->“Java Compiler”,Target bytecode version设为本地Java版本。(可以在Default Settings中把Project bytecode version 一劳永逸地配置成本地Java版本)

    Default Settings

           以上两步都配置好之后,重新运行应该就不会报上述错误了。

     

    一劳永逸的改法:

    感谢评论区另一位博友 Fumoon 提供的方案:https://blog.csdn.net/qq_42583206/article/details/108375173

    展开全文
  • /// <summary> /// 不可逆加密 ... /// MD5加密,和动网上的16/32位MD5加密结果相同, /// 使用的UTF8编码 /// </summary> /// <param name="source">待加密字串</param>
  • PyQt5(designer)入门教程

    万次阅读 多人点赞 2019-05-19 08:39:36
    PyQt5入门教程 注:这是当时闲着无聊写到github page的,在CSDN上也看了大佬们各种各样的教程跟疑难杂症解答,感觉我这个不放出来也有点可惜,希望各位能够从中收益吧。 在网上看了不少关于PyQt5的中文教程,但是无...

    PyQt5入门教程

    2019/12/11更新:我平时不看CSDN的,之前一时兴起发了过来,没想到反响还不错。这次就顺便把后来新增的一个小节放上来,并且在文末增加了我的GitHub(一看GitHub就知道我是个菜鸡,大家都是互相学习啦~)

    注:这是当时闲着无聊写到github page的,在CSDN上也看了大佬们各种各样的教程跟疑难杂症解答,感觉我这个不放出来也有点可惜,希望各位能够从中收益吧。

    在网上看了不少关于PyQt5的中文教程,但是无外乎是过时了,讲解不清晰易懂,或者资料不完整。Youtube上面倒是有不少视频,但是不少Youtuber居然还在手写ui而不是利用方便快捷的Qt Designer。仅有的几个视频虽然利用了Qt Designer来设计UI,但是他们并没有将UI跟逻辑分离,这种行为并不是我期望的。

    为此,我花费了不少时间在网上寻找各种资料。于是乎,我最终还是下定决心把自己的学习过程给记录下来。记录下来是给我自己复习跟参考的,如果有人能够从中受益,那也挺好,不用浪费时间去到处找答案。

    0x00 安装环境清单

    我使用的环境如下:

    • Windows 10 (Build 17763)
    • Python 3.7.2
    • VSCode 1.33.0
    • PyQt5
    • Qt Designer

    如果你使用的是OSX或者Linux,请自行替换教程中的一些操作。

    本文并不讨论Python和VSCode的安装,如果没有VSCode,你可以用各种同类IDE替代或者安装它。

    本文不讨论多Python共存,毕竟Python2.7在2020年就要退役了,而且我本人也没这需求。

    0x01 安装PyQt5

    下面直接使用pip来安装PyQt5,此处可能是pip/pip3,或者两者皆可,后面不再重复

    直接pip安装PyQt5

    pip install PyQt5
    

    由于Qt Designer已经在Python3.5版本从PyQt5转移到了tools,因此我们还需要安装pyqt5-tools

    pip install pyqt5-tools
    

    到这一步,PyQt5就安装完成了,你可以通过下面若干可选的操作来检查是否已经安装成功:

    • Win+S呼出Cornata主面板(搜索框),输入designer,如果看到跟下图类似的结果说明PyQt Designer已经被安装

    designer_install

    • 在cmd中输入pyuic5,如果返回“Error: one input ui-file must be specified”说明安装成功。

    0x02 初识Qt Designer

    注:Qt Designer的界面是全英文的,幸运的是有汉化方法,不过因为我本人用不上,所以如果有这方面需求可以自行搜索。

    我比较习惯用Win+S呼出Cornata主面板(搜索框)来启动各种应用,那么这里就是在搜索框中输入designer并敲回车,就能够启动Qt Designer了。

    初次启动会弹出这个“New Form”窗口,一般来说选择“Main Window”然后点击“Create”就可以了。下方有个“Show this Dialogue on Startup”的checkbox,如果不想每次启动都看到这个“New Form”窗口,可以取消勾选。

    new_form
    创建“Main Window”之后,我们会看到如下画面

    designer_ui
    下面就来简单介绍下整个画面的构成:

    • 左侧的“Widget Box”就是各种可以自由拖动的组件

    • 中间的“MainWindow - untitled”窗体就是画布

    • 右上方的"Object Inspector"可以查看当前ui的结构

    • 右侧中部的"Property Editor"可以设置当前选中组件的属性

    • 右下方的"Resource Browser"可以添加各种素材,比如图片,背景等等,目前可以不管

    大致了解了每个板块之后,就可以正式开始编写第一个UI了

    0x03 HelloWorld!

    注:从这里开始,相关代码可以在/assets/code/pyqt5中找到

    注:本文用到的代码都在我github,就不在CSDN这里上传了

    通常来说,编写GUI有两种方法:第一种就是直接使用方便快捷的Qt Designer,第二种就是写代码。在有Qt Designer的情况下,是完全不推荐费时费力去手写GUI代码的。Qt Designer可以所见即所得,并且可以方便的修改并做出各种调整。

    按照惯例,我们先来实现一个能够显示HelloWorld的窗口。

    1)添加文本

    在左侧的“Widget Box”栏目中找到“Display Widgets”分类,将“Label”拖拽到屏幕中间的“MainWindow”画布上,你就获得了一个仅用于显示文字的文本框,如下图所示。

    designer_create_label

    2)编辑文本

    双击上图中的“TextLabel”,就可以对文本进行编辑,这里我们将其改成“HelloWorld!”,如下图所示。如果文字没有完全展示出来,可以自行拖拽空间改变尺寸。

    特别提醒,编辑完文本之后记得敲击回车令其生效!

    designer_change_label_text

    3)添加按钮

    使用同样的方法添加一个按钮(PushButton)并将其显示的文本改成“HelloWorld!”,如下图所示。

    designer_create_pushbutton

    4)修改窗口标题

    下面修改窗口标题。选中右上方的"Object Inspector"中的“MainWindow”,然后在右侧中部的"Property Editor"中找到“windowTitle”这个属性,在Value这一栏进行修改,修改完记得敲击回车。

    5)编辑菜单栏

    注意到画布的左上方有个“Type Here”,双击它即可开始编辑菜单栏。菜单栏支持创建多级菜单以及分割线(separator)。我随意创建了一些菜单项目,如下图所示。

    designer_create_menu

    6)预览

    使用快捷键Ctrl+R预览当前编写的GUI(或者从菜单栏的Form > Preview / Preview in进入)

    designer_preview

    7)保存

    如果觉得完成了,那就可以保存成*.ui的文件,这里我们保存为HelloWorld.ui。为了方便演示,我将文件保存到D盘。

    8)生成Python代码

    使用cmd将目录切到D盘并执行下面的命令。请自行将下面命令中的name替换成文件名,比如本例中的“HelloWorld.ui”

    pyuic5 -o name.py name.ui
    

    生成的代码应该类似下图所示

    designer_code_helloworld

    9)运行Python代码

    此时尝试运行刚刚生成的“HelloWorld.py”是没用的,因为生成的文件并没有程序入口。因此我们在同一个目录下另外创建一个程序叫做“main.py”,并输入如下内容。在本例中,gui_file_name就是HelloWorld,请自行替换。

    import sys
    from PyQt5.QtWidgets import QApplication, QMainWindow
    
    import gui_file_name
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        MainWindow = QMainWindow()
        ui = gui_file_name.Ui_MainWindow()
        ui.setupUi(MainWindow)
        MainWindow.show()
        sys.exit(app.exec_())
    

    然后运行“main.py”,你就能看到刚刚编写的GUI了!

    designer_run_helloworld

    10)组件自适应

    如果你刚刚尝试去缩放窗口,会发现组件并不会自适应缩放,因此我们需要回到Qt Designer中进行一些额外的设置。

    点击画布空白处,然后在上方工具栏找到grid layout或者form layout,在本例中我们使用grid layout。两种layout的图标如下图所示。

    designer_layout_helloworld

    顺带一提,上图中layout的左边有三条横线以及三条竖线的图标,这两个是用于对齐组件,非常实用。

    设置grid layout后,我们使用Ctrl+R预览,这次组件可以自适应了!因为我们已经将UI(HelloWorld.py/HelloWorld.ui)跟逻辑(main.py)分离,因此直接重复步骤7-8即可完成UI的更新,无需改动逻辑(main.py)部分。

    0x04 Interaction

    刚刚写的HelloWorld中,我们设置的按钮(PushButton)是没有实际作用的,因为我们并没有告诉这个按钮应该做什么。实际上,要让这个按钮做点什么只需要增加一行代码就可以了。

    1)获取按钮id

    打开HelloWorld.ui,在designer中选中对应的按钮,从“Property Editor”中可以得知这个按钮的“objectName”叫做“pushButton”,如下图所示。

    designer_pushbutton_id

    2)设置触发

    Qt中有“信号和槽(signal and slot)”这个概念,不过目前无需深究,也无需在Designer中去设置对应按钮的“信号和槽”,直接在“main.py”中“MainWindow.show()”的后面加入下面这样的一行代码

    ui.pushButton.clicked.connect(click_success)
    

    下面简单解释下这行代码

    • pushButton就是刚刚获取的按钮id
    • clicked就是信号,因为是点击,所以我们这里用clicked
    • click_success就是对应要调用的槽,注意这里函数并不写成click_success()

    3)设置函数

    既然刚刚设置了按钮的触发并绑定了一个函数click_success,我们就要在“main.py”中实现它。示例如下

    def click_success():
        print("啊哈哈哈我终于成功了!")
    

    4)运行!

    UI跟逻辑分离的好处就在这里,我们这次不用去管“HelloWorld.py”了,直接运行修改完的“main.py”。点击按钮,这次你会发现在控制台中有了我们预设的输出。

    0x05 Conversion

    这次我们来进行实战演练,编写一个带GUI的汇率转换器。

    1)设计UI

    conversion_ui

    通过上面的讲解,你应该能够毫无压力的设计上面这样的UI并获得对应的代码。如果不行,那么不建议继续往下阅读,应当回头复习。

    2)传参

    现在我们有了GUI的代码以及上一节中使用的“main.py”,我们可以开始编写这个汇率转换器的逻辑部分。

    在上一节,我们介绍了如何让按钮响应点击操作,但是并没有接受任何参数,而且只是在控制台输出。但是,上一节中说明了并不能通过正常的方式进行传参。因此,对于传参,有两种解决方案,一种是使用lambda,还有一种是使用functool.partial。在接下来的环节中我们会使用partial。

    partial的用法如下所示:

    partial(function, arg1, arg2, ......)
    

    既然使用partial传参,那么我们就要在程序(main.py)的头部加上下面这行。

    from functools import partial
    

    然后我们把上一节中的按钮触发那行代码修改成下面这样。

    ui.pushButton.clicked.connect(partial(convert, ui))
    

    3)编写convert函数

    首先,我们要获取用户输入的数字。为了使得教程简洁易懂,我们这次只讲解单向的汇率转换。既然是单项的转换,那么我们只需要获取左侧的文本框id。在本例中,左侧的文本框id为lineEdit。如果你对此感到一头雾水,请停下并回头复习。

    获取文本使用的是text()方法,因此读取用户输入的代码如下

    input = ui.lineEdit.text()
    

    接着我们进行汇率转换,注意这里要进行类型转换

    result = float(input) * 6.7
    

    最后我们让右边的文本框显示结果

    ui.lineEdit_2.setText(str(result))
    

    下面是convert函数的代码

    def convert(ui):
        input = ui.lineEdit.text()
        result = float(input) * 6.7
        ui.lineEdit_2.setText(str(result))
    

    一个简单的汇率转换器就这样诞生了!

    那么,如何知道一个组件都有什么方法呢?直接去Qt官方文档查看就可以了。本节使用到的lineEdit的相关方法在这里

    0x06 threading

    1)前言

    这几天在用PyQt5写东西的时候遇到这样一个问题,网上资料也特别少,我感觉值得拿出来说一说。

    我的程序中使用了threading模块,GUI作为主线程去启动负责逻辑处理的子线程。其中,我设计的GUI里头有一个日志框,用来代替终端显示各种日志输出。既然子线程是负责逻辑处理,那么想当然的就会直接在子线程操作GUI的显示。

    都说了想当然,那当然不行咯,在子线程对GUI操作的时候,终端会出现下面这个错误,但是程序又不会马上闪退。

    QObject::connect: Cannot queue arguments of type 'QTextCursor'
    (Make sure 'QTextCursor' is registered using qRegisterMetaType().)
    

    更让人摸不着头脑的是,过一阵子闪退的时候,会出现下面这句话:

    段错误,核心已转储
    

    这啥玩意儿?能说人话么?一番搜索之后,发现这个原来英语叫做“Segmentation fault (core dumped)”。

    "Segmentation fault"用人话来说大概就是“你尝试访问你无法访问的内存”。

    然后我把上面的报错信息搜索了下,发现之前有人在StackOverflow问过,但是答案牛头不对马嘴,不过倒是在评论区发现了大佬的留言。

    It is likely that the asker was not actually directly using QTextCursor, but rather using GUI code from a thread that was not the GUI thread. Attempting this seems to result in this error arising from Qt-internal code, e.g. for QTextEdit.append()
    

    简而言之,就是说虽然报错显示QTextCursor,但是实际上是在其它线程通过Qt内部的方法间接调用了这个东西。

    热心大佬还留了个链接,我跟过去看了,收获不少。

    It appears you're trying to access QtGui classes from a thread other than the main thread. Like in some other GUI toolkits (e.g. Java Swing), that's not allowed.
    
    Although QObject is reentrant, the GUI classes, notably QWidget and all its subclasses, are not reentrant. They can only be used from the main thread.
    

    这个终于说到点子上了,一句话总结就是子线程不能调用主线程的QtGui类。

    所以大佬给出的方案如下:

    A solution is to use signals and slots for communication between the main thread (where the GUI objects live) and your secondary thread(s). Basically, you emit signals in one thread that get delivered to the QObjects via the other thread.
    

    大概翻译下,就是说可以通过信号和槽来完成子线程跟GUI所在的主线程的通信,就是通过在子线程释放信号,传递到主线程的槽来完成。

    可惜的是,大佬并没有给出示例代码,那接下来就是动手实践了。

    2)实践

    首先我们在子线程的代码中创建一个对象,并且继承QObject(因为需要释放信号)。

    class UpdateLog(QObject):
        update_signal = pyqtSignal()
     
        def __init__(self):
            QObject.__init__(self)
     
        def update(self):
            self.update_signal.emit()
    

    update_signal = pyqtSignal()就是使用Signal类来创建一个自定义的信号。

    self.update_signal.emit()就是当条件满足的时候,子线程可以调用UpdateLog类的update方法,就会发出信号。

    做完这些之后,主线程中别忘了连击信号和槽,比如self.afk.utils.logger.update_signal.connect(self.write_log)。然后现在再尝试运行程序,就没有任何问题了。

    不仅如此,其实其它需要共享的信息,也可以通过自定义信号和槽来传递。

    那么,现在就可以愉快的在PyQt程序中使用threading模块了。

    0x0? 小结

    本文只是抛砖引玉,上面这些只是PyQt5的入门内容。不过学会了简单的交互方法,其它的也差不多能依葫芦画瓢做出来。

    本文中设计的程序在/assets/code/pyqt5中。

    那么,就先写到这里了!

    0xff Info

    我不是大佬,不是CS专业的,水平相对比较菜,只是一个对计算机感兴趣的业余爱好者,在这方面基本上是自学成才,毕竟兴趣是第一生产力嘛~

    我的GitHub

    其中这个tree项目的GitHub Page就放了些乱七八糟的自学笔记,有到处搜刮的也有原创的。有帮助的话不如给我这个tree项目点个星呗(手动滑稽)。

    展开全文
  • 深入浅出Yolo系列之Yolov5核心基础知识完整讲解

    万次阅读 多人点赞 2020-08-10 15:21:33
    对Yolov4的相关基础知识做了比较系统的梳理,但Yolov4后不久,又出现了Yolov5,虽然作者没有放上和Yolov4的直接测试对比,但在COCO数据集的测试效果还是很可观的。 很多人考虑到Yolov5的创新性不足,对算法是否能够...

    大白在之前写过《深入浅出Yolo系列之Yolov3&Yolov4核心基础知识完整讲解》点击即可查看

    Yolov4的相关基础知识做了比较系统的梳理,但Yolov4后不久,又出现了Yolov5,虽然作者没有放上和Yolov4的直接测试对比,但在COCO数据集的测试效果还是很可观的。

    很多人考虑到Yolov5创新性不足,对算法是否能够进化,称得上Yolov5而议论纷纷。

    但既然称之为Yolov5,也有很多非常不错的地方值得我们学习。不过因为Yolov5的网络结构和Yolov3、Yolov4相比,不好可视化,导致很多同学看Yolov5看的云里雾里。

    因此本文,大白主要对Yolov5四种网络结构的各个细节做一个深入浅出的分析总结,和大家一些探讨学习。

    同时,大白每周会整理几十个人工智能公众号的精华文章,并系统的分类,让大家对于人工智能行业每周的内容动态可以一目了然,点击查看

    版权申明:本文包含图片,都为大白使用PPT所绘制的,如需网络结构高清图模型权重,可点击查看下载

    PS:原创不易,编辑上传文字2小时,为了便于大家查看,排版8小时,欢迎大家点赞收藏。

    更新提醒(2021.05.20):Yolov3&Yolov4的相关视频,已经更新上传,可点击查看

    求职跳槽福利:为了便于大家求职、跳槽的准备,大白将45家大厂3500篇面经,按照知识框架,整理成700多页的《人工智能算法岗江湖武林秘籍》,限时开放下载,点击查看下载


    1 Yolov5四种网络模型

    Yolov5官方代码中,给出的目标检测网络中一共有4个版本,分别是Yolov5s、Yolov5m、Yolov5l、Yolov5x四个模型。
    学习一个新的算法,最好在脑海中对算法网络的整体架构有一个清晰的理解。
    比较尴尬的是,Yolov5代码中给出的网络文件是yaml格式,和原本Yolov3、Yolov4中的cfg不同。
    因此无法用netron工具直接可视化的查看网络结构,造成有的同学不知道如何去学习这样的网络。
    比如下载了Yolov5的四个pt格式的权重模型:

    在这里插入图片描述
    大白在《深入浅出Yolo系列之Yolov3&Yolov4核心基础知识完整讲解》中讲到,可以使用netron工具打开查看网络模型。
    但因为netron对pt格式的文件兼容性并不好,直接使用netron工具打开,会发现,根本无法显示全部网络。
    因此可以采用pt->onnx->netron的折中方式,先使用Yolov5代码中models/export.py脚本将pt文件转换为onnx格式,再用netron工具打开,这样就可以看全网络的整体架构了。

    在这里插入图片描述
    如果有同学对netron工具还不是很熟悉,这里还是放上安装netron工具的详解,如果需要安装,可以移步大白的另一篇文章:《网络可视化工具netron详细安装流程》
    如需下载Yolov5整体的4个网络pt文件及onnx文件,也可点击链接查看下载,便于直观的学习。

    1.1 Yolov5网络结构图

    安装好netron工具,就可以可视化的打开Yolov5的网络结构,这里大白也和之前讲解Yolov3&Yolov4同样的方式,绘制了Yolov5s整体的网络结构图,配合netron的可视化网络结构查看,脑海中的架构会更加清晰。

    在这里插入图片描述

    本文也会以Yolov5s的网络结构为主线,讲解与其他三个模型(Yolov5m、Yolov5l、Yolov5x)的不同点,让大家对于Yolov5有一个深入浅出的了解

    1.2 网络结构可视化

    四种模型的pt文件转换成对应的onnx文件后,即可使用netron工具查看。
    但是,有些同学可能不方便,使用脚本转换查看。
    因此,大白也上传了每个网络结构图的图片,也可以直接点击查看。虽然没有netron工具更直观,但是也可以学习了解

    1.2.1 Yolov5s网络结构

    Yolov5s网络是Yolov5系列中深度最小,特征图的宽度最小的网络。
    后面的3种都是在此基础上不断加深,不断加宽。
    上图绘制出的网络结构图也是Yolov5s的结构,大家也可直接点击查看,Yolov5s的网络结构可视化的图片。

    1.2.2 Yolov5m网络结构

    此处也放上netron打开的Yolov5m网络结构可视图,点击即可查看,后面第二版块会详细说明不同模型的不同点。

    1.2.3 Yolov5l网络结构

    此处也放上netronx打开的Yolov5l网络结构可视图,点击即可查看

    1.2.4 Yolov5x网络结构

    此处也放上netronx打开的Yolov5x网络结构可视图,点击即可查看

    2 核心基础内容

    2.1 Yolov3&Yolov4网络结构图

    2.1.1 Yolov3网络结构图

    Yolov3网络结构是比较经典的one-stage结构,分为输入端BackboneNeckPrediction四个部分。
    大白在之前的《深入浅出Yolo系列之Yolov3&Yolov4核心基础完整讲解》中讲了很多,这里不多说,还是放上绘制的Yolov3网络结构图

    在这里插入图片描述

    2.1.2 Yolov4网络结构图

    Yolov4Yolov3的基础上进行了很多的创新。
    比如输入端采用mosaic数据增强,
    Backbone上采用了CSPDarknet53、Mish激活函数、Dropblock等方式,
    Neck中采用了SPP、FPN+PAN的结构,
    输出端则采用CIOU_Loss、DIOU_nms操作。
    因此Yolov4Yolov3的各个部分都进行了很多的整合创新,
    关于Yolov4如果有不清楚的可以参照大白之前写的《深入浅出Yolo系列之Yolov3&Yolov4核心基础知识完整讲解》,写的比较详细。

    在这里插入图片描述

    2.2 Yolov5核心基础内容

    Yolov5的结构和Yolov4很相似,但也有一些不同,大白还是按照从整体细节的方式,对每个板块进行讲解。
    在这里插入图片描述

    上图即Yolov5的网络结构图,可以看出,还是分为输入端、Backbone、Neck、Prediction四个部分。
    大家可能对Yolov3比较熟悉,因此大白列举它和Yolov3的一些主要的不同点,并和Yolov4进行比较。
    (1)输入端Mosaic数据增强、自适应锚框计算
    (2)BackboneFocus结构,CSP结构
    (3)NeckFPN+PAN结构
    (4)PredictionGIOU_Loss

    下面丢上Yolov5作者的算法性能测试图:
    在这里插入图片描述

    Yolov5作者也是在COCO数据集上进行的测试。
    大白在之前的文章讲过,COCO数据集的小目标占比
    因此最终的四种网络结构,性能上来说各有千秋。
    Yolov5s网络最小,速度最少,AP精度也最低。
    但如果检测的以大目标为主,追求速度,倒也是个不错的选择。
    其他的三种网络,在此基础上,不断加深加宽网络AP精度也不断提升,但速度的消耗也在不断增加

    2.2.1 输入端

    (1)Mosaic数据增强
    Yolov5的输入端采用了和Yolov4一样的Mosaic数据增强的方式。
    Mosaic数据增强提出的作者也是来自Yolov5团队的成员,不过,随机缩放随机裁剪随机排布的方式进行拼接,对于小目标的检测效果还是很不错的。
    在这里插入图片描述

    Mosaic数据增强的内容在之前《深入浅出Yolo系列之Yolov3&Yolov4核心基础知识完整讲解》文章中写的很详细,详情可以查看之前的内容。

    (2)自适应锚框计算
    Yolo算法中,针对不同的数据集,都会有初始设定长宽的锚框。
    在网络训练中,网络在初始锚框的基础上输出预测框,进而和真实框groundtruth进行比对,计算两者差距,再反向更新,迭代网络参数。
    因此初始锚框也是比较重要的一部分,比如Yolov5Coco数据集上初始设定的锚框:
    在这里插入图片描述

    Yolov3、Yolov4中,训练不同的数据集时,计算初始锚框的值是通过单独的程序运行的。
    Yolov5中将此功能嵌入到代码中,每次训练时,自适应的计算不同训练集中的最佳锚框值
    当然,如果觉得计算的锚框效果不是很好,也可以在代码中将自动计算锚框功能关闭
    在这里插入图片描述

    控制的代码即train.py中上面一行代码,设置成False,每次训练时,不会自动计算。

    (3)自适应图片缩放
    在常用的目标检测算法中,不同的图片长宽都不相同,因此常用的方式是将原始图片统一缩放到一个标准尺寸,再送入检测网络中。
    比如Yolo算法中常用416×416,608×608等尺寸,比如对下面800*600的图像进行变换。
    在这里插入图片描述

    Yolov5代码中对此进行了改进,也是Yolov5推理速度能够很快的一个不错的trick
    作者认为,在项目实际使用时,很多图片的长宽比不同。
    因此缩放填充后,两端的黑边大小都不同,而如果填充的比较多,则存在信息冗余,影响推理速度。
    因此在Yolov5代码datasets.py的letterbox函数中进行了修改,对原始图像自适应的添加最少的黑边

    在这里插入图片描述

    图像高度上两端的黑边变少了,在推理时,计算量也会减少,即目标检测速度会得到提升。
    这种方式在之前github上Yolov3中也进行了讨论:https://github.com/ultralytics/yolov3/issues/232
    在讨论中,通过这种简单的改进,推理速度得到了37%的提升,可以说效果很明显。
    但是有的同学可能会有大大的问号??如何进行计算的呢?
    大白按照Yolov5中的思路详细的讲解一下,在datasets.py的letterbox函数中也有详细的代码。

    第一步:计算缩放比例

    在这里插入图片描述

    原始缩放尺寸是416×416,都除以原始图像的尺寸后,可以得到0.52,和0.69两个缩放系数,选择小的缩放系数0.52

    第二步:计算缩放后的尺寸

    在这里插入图片描述
    原始图片的长宽都乘以最小的缩放系数0.52,宽变成了416,而高变成了312

    第三步:计算黑边填充数值

    在这里插入图片描述

    416-312=104,得到原本需要填充的高度。再采用numpy中np.mod取余数的方式,得到8个像素,再除以2,即得到图片高度两端需要填充的数值。
    此外,需要注意的是:
    a.这里大白填充的是黑色,即(0,0,0),而Yolov5中填充的是灰色,即(114,114,114),都是一样的效果。
    b.训练时没有采用缩减黑边的方式,还是采用传统填充的方式,即缩放到416×416大小。
    只是在测试,使用模型推理时,才采用缩减黑边的方式,提高目标检测,推理的速度。
    c.为什么np.mod函数的后面用32?因为Yolov5的网络经过5次下采样,而2的5次方,等于32。所以至少要去掉32的倍数,再进行取余。

    2.2.2 Backbone

    (1)Focus结构
    在这里插入图片描述

    Focus结构,Yolov3&Yolov4中并没有这个结构,其中比较关键是切片操作。
    比如右图的切片示意图,4×4×3的图像切片后变成2×2×12的特征图。
    Yolov5s的结构为例,原始608×608×3的图像输入Focus结构,采用切片操作,先变成304×304×12的特征图,再经过一次32个卷积核的卷积操作,最终变成304×304×32的特征图。
    需要注意的是:Yolov5s的Focus结构最后使用了32个卷积核,而其他三种结构,使用的数量有所增加,先注意下,后面会讲解到四种结构的不同点。

    (2)CSP结构
    Yolov4网络结构中,借鉴了CSPNet的设计思路,在主干网络中设计了CSP结构。

    在这里插入图片描述

    Yolov5Yolov4不同点在于,Yolov4中只有主干网络使用了CSP结构,Yolov5中设计了两种CSP结构,Yolov5s网络为例,以CSP1_X结构应用于Backbone主干网络,另一种CSP2_X结构则应用于Neck中

    在这里插入图片描述

    这里关于CSPNet的内容,也可以查看大白之前的《深入浅出Yolo系列之Yolov3&Yolov4核心基础知识完整讲解》

    2.2.3 Neck

    Yolov5现在的NeckYolov4中一样,都采用FPN+PAN的结构,但在Yolov5刚出来时,只使用了FPN结构,后面才增加了PAN结构,此外网络中其他部分也进行了调整。
    因此,大白在Yolov5刚提出时,画的很多结构图又都重新进行了调整
    在这里插入图片描述

    这里关于FPN+PAN的结构,大白在《深入浅出Yolo之Yolov3&Yolov4核心基础知识完整讲解》中,讲的很多,大家应该都有理解。
    但如上面CSPNet中讲到,Yolov5Yolov4的不同点在于,Yolov4Neck中,采用的都是普通的卷积操作。
    Yolov5Neck结构中,采用借鉴CSPNet设计的CSP2结构加强网络特征融合的能力

    在这里插入图片描述

    2.2.4 输出端

    (1)Bounding box损失函数
    《深入浅出Yolo系列之Yolov3&Yolov4核心基础完整讲解》中,大白详细的讲解了IOU_Loss,以及进化版的GIOU_LossDIOU_Loss,以及CIOU_Loss
    Yolov5中采用其中的GIOU_LossBounding box损失函数
    在这里插入图片描述

    Yolov4中采用CIOU_Loss作为目标Bounding box的损失函数。

    在这里插入图片描述

    (2)nms非极大值抑制
    在目标检测的后处理过程中,针对很多目标框的筛选,通常需要nms操作
    Yolov4DIOU_Loss的基础上采用DIOU_nms的方式,而Yolov5中仍然采用加权nms的方式。
    可以看出,采用DIOU_nms,下方中间箭头的黄色部分,原本被遮挡的摩托车也可以检出。

    在这里插入图片描述

    大白在项目中,也采用了DIOU_nms的方式,在同样的参数情况下,将nmsIOU修改成DIOU_nms。对于一些遮挡重叠的目标,确实会有一些改进
    比如下面黄色箭头部分,原本两个人重叠的部分,在参数和普通的IOU_nms一致的情况下,修改成DIOU_nms,可以将两个目标检出
    虽然大多数状态下效果差不多,但在不增加计算成本的情况下,有稍微的改进也是好的。

    在这里插入图片描述

    2.3 Yolov5四种网络结构的不同点

    Yolov5代码中的四种网络,和之前的Yolov3Yolov4中的cfg文件不同,都是以yaml的形式来呈现。
    而且四个文件的内容基本上都是一样的,只有最上方的depth_multiplewidth_multiple两个参数不同,很多同学看的一脸懵逼,不知道只通过两个参数是如何控制四种结构的

    2.3.1 四种结构的参数

    大白先取出Yolov5代码中,每个网络结构的两个参数:

    (1)Yolov5s.yaml
    在这里插入图片描述

    (2)Yolov5m.yaml
    在这里插入图片描述

    (3)Yolov5l.yaml
    在这里插入图片描述

    (4)Yolov5x.yaml
    在这里插入图片描述

    四种结构就是通过上面的两个参数,来进行控制网络的深度和宽度。其中depth_multiple控制网络的深度width_multiple控制网络的宽度

    2.3.2 Yolov5网络结构

    四种结构的yaml文件中,下方的网络架构代码都是一样的。
    为了便于讲解,大白将其中的Backbon部分提取出来,讲解如何控制网络的宽度和深度yaml文件中的Head部分也是同样的原理。

    在这里插入图片描述

    在对网络结构进行解析时,yolo.py中下方的这一行代码将四种结构的depth_multiplewidth_multiple提取出,赋值给gdgw。后面主要对这gdgw这两个参数进行讲解。
    在这里插入图片描述

    下面再细致的剖析下,看是如何控制每种结构,深度和宽度的

    2.3.3 Yolov5四种网络的深度

    在这里插入图片描述

    (1)不同网络的深度
    在上图中,大白画了两种CSP结构CSP1CSP2,其中CSP1结构主要应用于Backbone中,CSP2结构主要应用于Neck中。
    需要注意的是,四种网络结构中每个CSP结构的深度都是不同的
    a. Yolov5s为例,第一个CSP1中,使用了1个残差组件,因此是CSP1_1
    而在Yolov5m中,则增加了网络的深度,在第一个CSP1中,使用了2个残差组件,因此是CSP1_2
    Yolov5l中,同样的位置,则使用了3个残差组件Yolov5x中,使用了4个残差组件。
    其余的第二个CSP1和第三个CSP1也是同样的原理。
    b. 在第二种CSP2结构中也是同样的方式,以第一个CSP2结构为例。
    Yolov5s组件中使用了2×X=2×1=2个卷积,因为X=1,所以使用了1组卷积,因此是CSP2_1
    Yolov5m中使用了2组,Yolov5l中使用了3组Yolov5x中使用了4组。其他的四个CSP2结构,也是同理。
    Yolov5中,网络的不断加深,也在不断增加网络特征提取特征融合的能力。
    (2)控制深度的代码
    控制四种网络结构的核心代码是yolo.py中下面的代码,存在两个变量,ngd
    我们再将ngd带入计算,看每种网络的变化结果。

    在这里插入图片描述

    (3)验证控制深度的有效性
    我们选择最小的yolov5s.yaml和中间的yolov5l.yaml两个网络结构,将gd(height_multiple)系数带入,看是否正确。

    在这里插入图片描述

    a. yolov5s.yaml
    其中height_multiple=0.33,即gd=0.33,而n则由上面红色框中的信息获得。
    以上面网络框图中的第一个CSP1为例,即上面的第一个红色框。n等于第二个数值3
    gd=0.33,带入(2)中的计算代码,结果n=1。因此第一个CSP1结构内只有1个残差组件,即CSP1_1
    第二个CSP1结构中,n等于第二个数值9,而gd=0.33,带入(2)中计算,结果n=3,因此第二个CSP1结构中有3个残差组件,即CSP1_3
    第三个CSP1结构也是同理,这里不多说。
    b. yolov5l.xml
    其中height_multiple=1,即gd=1
    和上面的计算方式相同,第一个CSP1结构中,n=3,带入代码中,结果n=3,因此为CSP1_3
    下面第二个CSP1结构和第三个CSP1结构都是同样的原理。

    2.3.4 Yolov5四种网络的宽度

    在这里插入图片描述
    (1)不同网络的宽度
    上图表格中所示,四种Yolov5结构不同阶段的卷积核的数量都是不一样的。
    因此也直接影响卷积后特征图第三维度,即厚度,大白这里表示为网络的宽度
    a. Yolov5s结构为例,第一个Focus结构中,最后卷积操作时,卷积核的数量是32个,因此经过Focus结构,特征图的大小变成304×304×32
    Yolov5mFocus结构中的卷积操作使用了48个卷积核,因此Focus结构后的特征图变成304×304×48Yolov5lYolov5x也是同样的原理。
    b. 第二个卷积操作时,Yolov5s使用了64个卷积核,因此得到的特征图是152×152×64。而Yolov5m使用96个特征图,因此得到的特征图是152×152×96Yolov5lYolov5x也是同理。
    c. 后面三个卷积下采样操作也是同样的原理,这样大白不过多讲解。
    四种不同结构的卷积核的数量不同,这也直接影响网络中比如CSP1结构CSP2等结构,以及各个普通卷积,卷积操作时的卷积核数量也同步在调整,影响整体网络的计算量
    大家最好可以将结构图和前面第一部分四个网络的特征图链接,对应查看,思路会更加清晰
    当然卷积核的数量越多,特征图的厚度,即宽度越宽,网络提取特征的学习能力也越强
    (2)控制宽度的代码
    Yolov5的代码中,控制宽度的核心代码是yolo.py文件里面的这一行:
    在这里插入图片描述

    它所调用的子函数make_divisible的功能是:
    在这里插入图片描述

    (3)验证控制宽度的有效性
    我们还是选择最小的Yolov5s和中间的Yolov5l两个网络结构,将width_multiple系数带入,看是否正确。
    在这里插入图片描述

    a. yolov5s.yaml
    其中width_multiple=0.5,即gw=0.5

    在这里插入图片描述

    第一个卷积下采样为例,即Focus结构中下面的卷积操作。
    按照上面Backbone的信息,我们知道Focus中,标准的c2=64,而gw=0.5,代入(2)中的计算公式,最后的结果=32。即Yolov5sFocus结构中,卷积下采样操作的卷积核数量为32个
    再计算后面的第二个卷积下采样操作,标准c2的值=128gw=0.5,代入(2)中公式,最后的结果=64,也是正确的。
    b. yolov5l.yaml
    其中width_multiple=1,即gw=1,而标准的c2=64,代入上面(2)的计算公式中,可以得到Yolov5lFocus结构中,卷积下采样操作的卷积核的数量为64个,而第二个卷积下采样的卷积核数量是128个
    另外的三个卷积下采样操作,以及Yolov5mYolov5x结构也是同样的计算方式,大白这里不过多解释。

    3 Yolov5相关论文及代码

    3.1 代码

    Yolov5的作者并没有发表论文,因此只能从代码角度进行分析。
    Yolov5代码:https://github.com/ultralytics/yolov5
    大家可以根据网页的说明,下载训练,及测试,流程还是比较简单的。

    3.2 相关论文

    另外一篇论文,PP-Yolo,在Yolov3的原理上,采用了很多的tricks调参方式,也挺有意思。
    感兴趣的话可以参照另一个博主的文章:点击查看

    4 小目标分割检测

    目标检测发展很快,但对于小目标的检测还是有一定的瓶颈,特别是大分辨率图像小目标检测。比如7920×2160,甚至16000×16000像素的图像。

    在这里插入图片描述

    图像的分辨率很大,但又有很多小的目标需要检测。但是如果直接输入检测网络,比如Yolov3检出效果并不好
    主要原因是:
    (1)小目标尺寸
    以网络的输入608×608为例,Yolov3Yolov4Yolov5中下采样都使用了5次,因此最后的特征图大小是19×1938×3876×76
    三个特征图中,最大的76×76负责检测小目标,而对应到608×608上,每格特征图的感受野608/76=8×8大小。

    在这里插入图片描述

    再将608×608对应到7680×2160上,以最长边7680为例,7680/608×8=101
    即如果原始图像中目标的宽或高小于101像素,网络很难学习到目标的特征信息。
    (PS:这里忽略多尺度训练的因素及增加网络检测分支的情况)
    (2)高分辨率
    而在很多遥感图像中,长宽比的分辨率比7680×2160更大,比如上面的16000×16000
    如果采用直接输入原图的方式,很多小目标都无法检测出。
    (3)显卡爆炸
    很多图像分辨率很大,如果简单的进行下采样,下采样的倍数太大,容易丢失数据信息。
    但是倍数太小,网络前向传播需要在内存中保存大量的特征图,极大耗尽GPU资源,很容易发生显卡爆炸显存爆炸,无法正常的训练及推理。
    因此可以借鉴2018年YOLT算法的方式,改变一下思维,对大分辨率图片先进行分割,变成一张张小图,再进行检测
    需要注意的是:
    为了避免两张小图之间,一些目标正好被分割截断,所以两个小图之间设置overlap重叠区域,比如分割的小图是960×960像素大小,则overlap可以设置为960×20%=192像素

    在这里插入图片描述

    每个小图检测完成后,再将所有的框放到大图上,对大图整体做一次nms操作,将重叠区域的很多重复框去除。
    这样操作,可以将很多小目标检出,比如16000×16000像素的遥感图像。

    注意:这里关于小图检测后,放到大图上的方法,发现评论中,很多的同学可能想的过于复杂了,采用的方式,其实按照在大图上裁剪的位置,直接回归到大图即可。

    此外,国内还有一个10亿像素图像目标检测的比赛,也是用的这样的方式,大白将其中一个讲解不错的视频,也放到这个,大家可以点击查看
    在这里插入图片描述

    无人机视角下,也有很多小的目标。大白也进行了测试,效果还是不错的。
    比如下图是将原始大图->416×416大小,直接使用目标检测网络输出的效果:

    在这里插入图片描述

    可以看到中间黄色框区域,很多汽车检测漏掉。
    再使用分割的方式,将大图先分割成小图,再对每个小图检测,可以看出中间区域很多的汽车都被检测出来:

    在这里插入图片描述

    不过这样的方式有中间黄色框区域优点也有中间黄色框区域缺点:
    优点
    (1) 准确性
    分割后的小图,再输入目标检测网络中,对于最小目标像素的下限大大降低
    比如分割成608×608大小,送入输入图像大小608×608的网络中,按照上面的计算方式,原始图片上,长宽大于8个像素的小目标都可以学习到特征。
    (2)检测方式
    在大分辨率图像,比如遥感图像,或者无人机图像,如果无需考虑实时性的检测,且对小目标检测也有需求的项目,可以尝试此种方式。
    缺点:
    (1) 增加计算量
    比如原本7680×2160的图像,如果使用直接大图检测的方式,一次即可检测完。
    但采用分割的方式,切分成N张608×608大小的图像,再进行N次检测,会大大增加检测时间。
    借鉴Yolov5的四种网络方式,我们可以采用尽量轻的网络,比如Yolov5s网络结构或者更轻的网络。
    当然Yolov4Yolov5的网络各有优势,我们也可以借鉴Yolov5的设计方式,对Yolov4进行轻量化改造,或者进行剪枝

    5 后语

    综合而言,在实际测试中,Yolov4的准确性有不错的优势,但Yolov5的多种网络结构使用起来更加灵活,我们可以根据不同的项目需求,取长补短,发挥不同检测网络的优势。
    希望在人工智能的道路上,和大家共同进步

    在这里插入图片描述

    展开全文
  • YOLOV5测试及训练自己的数据集

    万次阅读 多人点赞 2020-06-17 17:33:30
    YOLOV5项目复现一、YOLOv5 实现检测1.1 下载源码1.2 下载官方模型(.pt文件)1.3 配置虚拟环境1.4 进行测试二、YOLOV5 实现训练 首先说一下软硬件配置这一块:win10 + pycharm + i7-9700kf + rtx2070Super + cuda10.2 ...

    首先说一下软硬件配置这一块:win10 + i7-9700kf + rtx2070Super + cuda10.2 + anaconda

    官方模型
    Yolov5检测流程:
    yolov5源码
    .pt
    自己训练的模型
    实现检测

    一、YOLOv5 实现检测

    1.1 下载源码

    进入官方地址,进行源码下载   https://github.com/ultralytics/yolov5[大概4M左右]

    1.2 下载官方模型(.pt文件)

    文中作者是把模型都放到了谷歌网盘里了,如果没有梯子,访问会很慢–>>作者给的模型地址
    如果你实在是下载不下来,并且如果你也还有积分的话–>>CSDN下载模型【可怜可怜孩子吧】
    再如果你没有积分,好吧,好吧,那就,那就,那就留邮箱吧,但别忘了给卑微的我点个赞呦、、、额额额额
    2020.10.21更: 想要模型文件的直接私信我,我一开始设置的5积分,但是积分自己涨的太多了,花那么多积分下载不值当
    2021.04.03更:yolov5官方pt模型文件【点我,我是模型地址】如果链接失效,请及时评论区给我反馈,我及时更新

    1.3 配置虚拟环境

    虚拟环境的优点不再阐述
    创建虚拟环境:conda create -n yolov5 python==3.7在yolov5中尽量用python3.7
    进  入  环  境 :conda activate yolov5
    再安装所需库:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt(使用清华镜像源)
    在pip install的时候,可能会出现read timeout的情况,你需要更换镜像源,或者多执行几次pip install,如果还有其他报错,请留言评论区,我会及时回复,因为我在安装的时候也报了一些错,但是都没有记录下来
    在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

    1.4 进行测试

    进入到yolov5根目录下,我这里是用的powershell,你也可以在控制台,都是一样的。在这里插入图片描述
    运行测试文件:   python detect.py --source 0 【0:是指定的本机摄像头】PS:我特么的竟然一次运行成功,多少是挺失望

    ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓雷霆嘎巴↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
    ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ZBC↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

    在这里插入图片描述

    在这里插入图片描述在这里插入图片描述

    二、YOLOV5 实现训练

    2.1 首先是准备数据集

    ★    数据集的准备工作,我以前的博客有细写过,—>>传送门
    ★    数据集准备好后,一定先确保label和JPEGImages这两个文件夹在同一目录里
    在这里插入图片描述

    2.2 文件修改

    2.2.1 修改数据集方面的yaml文件

    作者是把以前用的.data、.names文件合并到了data/coco.yaml中,打开coco.yaml进行修改

    # COCO 2017 dataset http://cocodataset.org
    # Download command: bash yolov5/data/get_coco2017.sh
    # Train command: python train.py --data ./data/coco.yaml
    # Dataset should be placed next to yolov5 folder:
    #   /parent_folder
    #     /coco
    #     /yolov5
    
    
    # 这些是生成的图片的路径文件,这里是我自己的路径,需要修改成你自己的路径,绝对路径也ok
    train: ../coco/2007_train.txt  # 118k images
    val: ../coco/2007_val.txt  # 5k images
    test: ../coco/2007_test.txt  # 20k images for submission to https://competitions.codalab.org/competitions/20794
    
    # 你数据集的类别数
    nc: 1
    
    # 类别的名称
    names: ['cell phone']
    
    # Print classes
    # with open('data/coco.yaml') as f:
    #   d = yaml.load(f, Loader=yaml.FullLoader)  # dict
    #   for i, x in enumerate(d['names']):
    #     print(i, x)
    

    2.2.2 修改网络参数方面的yaml文件

    这个相当于以前版本的.cfg文件,在models/yolov3-spp.yaml【当然,你想用哪个模型就去修改对应的yaml文件】

    # parameters
    nc: 1  # 数据集类别数
    depth_multiple: 1.0  # expand model depth
    width_multiple: 1.0  # expand layer channels
    
    # anchors【你也可以使用k-means去产出你自己数据集的anchors】
    anchors:
      - [10,13, 16,30, 33,23]  # P3/8
      - [30,61, 62,45, 59,119]  # P4/16
      - [116,90, 156,198, 373,326]  # P5/32
    
    # darknet53 backbone
    backbone:
      # [from, number, module, args]
      [[-1, 1, Conv, [32, 3, 1]],  # 0
       [-1, 1, Conv, [64, 3, 2]],  # 1-P1/2
       [-1, 1, Bottleneck, [64]],
       [-1, 1, Conv, [128, 3, 2]],  # 3-P2/4
       [-1, 2, Bottleneck, [128]],
       [-1, 1, Conv, [256, 3, 2]],  # 5-P3/8
       [-1, 8, Bottleneck, [256]],
       [-1, 1, Conv, [512, 3, 2]],  # 7-P4/16
       [-1, 8, Bottleneck, [512]],
       [-1, 1, Conv, [1024, 3, 2]], # 9-P5/32
       [-1, 4, Bottleneck, [1024]],  # 10
      ]
    
    # yolov3-spp head
    # na = len(anchors[0])
    head:
      [[-1, 1, Bottleneck, [1024, False]],  # 11
       [-1, 1, SPP, [512, [5, 9, 13]]],
       [-1, 1, Conv, [1024, 3, 1]],
       [-1, 1, Conv, [512, 1, 1]],
       [-1, 1, Conv, [1024, 3, 1]],
       [-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1]],  # 16 (P5/32-large)
    
       [-3, 1, Conv, [256, 1, 1]],
       [-1, 1, nn.Upsample, [None, 2, 'nearest']],
       [[-1, 8], 1, Concat, [1]],  # cat backbone P4
       [-1, 1, Bottleneck, [512, False]],
       [-1, 1, Bottleneck, [512, False]],
       [-1, 1, Conv, [256, 1, 1]],
       [-1, 1, Conv, [512, 3, 1]],
       [-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1]],  # 24 (P4/16-medium)
    
       [-3, 1, Conv, [128, 1, 1]],
       [-1, 1, nn.Upsample, [None, 2, 'nearest']],
       [[-1, 6], 1, Concat, [1]],  # cat backbone P3
       [-1, 1, Bottleneck, [256, False]],
       [-1, 2, Bottleneck, [256, False]],
       [-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1]],  # 30 (P3/8-small)
    
       [[], 1, Detect, [nc, anchors]],   # Detect(P3, P4, P5)
      ]
    
    

    2.2.3 修改train.py中的一些参数

    train.py在根目录里,修改一些主要的参数,奥利给
    在这里插入图片描述

    parser.add_argument('--epochs', type=int, default=200)  # 训练的epoch
    parser.add_argument('--batch-size', type=int, default=16)  # batch_size 显卡垃圾的话,就调小点
    parser.add_argument('--cfg', type=str, default='models/yolov5s.yaml', help='*.cfg path')
    parser.add_argument('--data', type=str, default='data/coco.yaml', help='*.data path')
    parser.add_argument('--img-size', nargs='+', type=int, default=[640, 640], help='train,test sizes')
    

    2.3开始训练

    直接 python train.py 就Ok了

    成功训练如图所示
    在这里插入图片描述
    ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓无情哈拉少↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

    在这里插入图片描述
    在这里插入图片描述

    2.4 ?

    都已经在训练了,你接下来还有最重要的一步,就是看个日本特产电影啥的,或者是吃个瓜啥的,拉个屎啥的,反正我是去拉屎了🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵在这里插入图片描述
    等它训练完就没问题了,但是还是要时不时看一眼,具体看什么,我也不知道呀,反正是看就完事儿了🐷🐷🐷🐷🐷🐷🐷🐷🐷🐷🐷🐷🐷🐷🐷🐷

    都训练完了,测试的话,就不用再说的吧,阿sir,

    三、个人对于yolov5的看法

    先说一个情况吧,我在复现yolov4时,使用1080p的摄像头进行测试的时候,检测的帧率只有1.7fps(在我的rtx2070s显卡上),不管我如何调整cfg文件里的宽高,基本都无济于事,然后我用480p的摄像头才可以达到20fps,不要搞我啊,阿sir,现在摄像头基本都是在1080p检测的啊,480p怎么能满足!!!!!我不知道为什么图像在相同的cfg参数下,分辨率对检测速度影响会这么大。但是,啊,但是,我在用yolov5的时候,用1080P就可以达到实时,最主要的是yolov5的模型非常小,比yolo的前几个系列小了大概4倍,非常适合做嵌入。对于yolov5,虽然是作者自封的,但是非常达到我心里的预期!!!,不吹不黑,yolov5是我遇到最牛啤的目标检测算法,你说呢,你是不是也这么感觉的呢

    在这里插入图片描述在这里插入图片描述在这里插入图片描述

    展开全文
  • Xshell 5 免费版本安装过程

    万次阅读 多人点赞 2018-03-28 16:05:55
    发现本机的Xshell 5过期了用不了。在百度里搜索,下载安装后还是不可以使用。需要购买注册,后寻的一方法,分享给大家。 1.官网 进入官网,然后点击Download下方的Free License菜单。 https://www.netsarang.com/...
  • yum -y install mdadm
  • keil5使用教程

    万次阅读 多人点赞 2019-08-28 20:57:15
    简单介绍keil5得使用教程。
  • // return后面的通过for...of不会输出 因为是done变为了true for...of 循环就会终止 function* gen(){ yield 1; yield 2; yield 3;... yield 5; return 6; } for(let v of gen()){ console.log(v); }
  • 2020年5月份编程语言排行榜

    万次阅读 多人点赞 2020-05-10 15:51:08
    这段时间一直在忙,都忘记更新这个排行榜了,今天重操旧业,给大家看一下5月份的编程语言排行榜 TIOBE排行榜5月份数据 2020年5月TIOBE指数 以下是官方说明 五月标题:编程语言C又回到了第一位 Java和C在4月份已经...
  • TIOBE 5月编程语言排行榜新鲜出炉。前十榜单中,C、Python、Java三大鳌头仍占据前三榜单。去年11月,Python短时间的挤掉Java跃居至榜单第二名;今年5月,Python再次挤掉Java,再度夺下榜二。 TIOBE排行榜是世界上...
  • YOLOv5学习总结(持续更新)

    万次阅读 多人点赞 2020-09-12 06:11:36
    YOLOv5学习总结训练效果(持续更新)前言网络结构可视化yolov3yolov4yolov5核心基础内容Mosaic数据增强自适应锚框计算自适应图片缩放 首先感谢江大白大佬的研究与分享,贴上链接 深入浅出Yolo系列之Yolov5核心基础...
  • HTML 5移动开发从入门到精通

    万人学习 2015-01-14 20:16:03
    本课程讲述了HTML 5移动开发的各种技术,通过本课程的学习,用户可以掌握HTML 5移动开发的技巧
  • YOLO系列可以说是单机目标检测框架中的潮流前线了,由于YOLOv5是在PyTorch中实现的,它受益于成熟的PyTorch生态系统,支持更简单,部署更容易,相对于YOLOv4,YOLOv5具有以下优点: 速度更快。在YOLOv5 Colab ...
  • 一支烟的功夫,GTA 5联机版终于打开了。 「7年了!GTA 5联机版加载还是这么慢??」 △Please wait forever to play Reddit、Steam、HackerNews上,无数玩家吐槽抱怨…… 进游戏少则等5、6分钟,多则20分钟。 ...
  • 1.使用HTML5来DIY彩虹播放器◆html5新增的语义化标签,多媒体盒子标签 figure,专门用来放视频标签、音频标签、图片标签等,&lt;figure&gt;&lt;figcaption&gt;视频&lt;/figcaption&gt;&...
  • QT5实现简单的TCP通信

    万次阅读 多人点赞 2017-04-11 00:43:20
    这段时间用到了QT的TCP通信,做了初步的学习与尝试,编写了...1、客户端的代码比服务器稍简单,总的来说,使用QT中的QTcpSocket类与服务器进行通信只需要以下5步: (1)创建QTcpSocket套接字对象 socket = new Q...
  • keil5 最新版注册机 下载

    万次阅读 多人点赞 2019-08-27 15:47:30
    虽然有很多注册机可供下载,然而都有KEIL5 在里面包含,导致某网盘中内存过大,下载速度,所以我推荐在一下博客下载,只有不到1MB https://blog.csdn.net/qq_22329595/article/details/83054499 推荐 希望你及早解决...
  • HTML5示例

    万次阅读 2018-06-06 23:26:44
    单选单列 1 2 3 4 5 下拉列表 多选单列 1 2 3 4 5 普通按钮 提交按钮 重置按钮 url 邮箱 时间 date datetime datetime-local month week time 数值 滚动控件 设置元素不能为空的属性required 上传对话框 表格 表格...
  • 12个优秀的 HTML5 网站设计案例欣赏

    万次阅读 多人点赞 2018-05-20 14:39:56
    12个优秀的 HTML5 网站设计案例欣赏 欣赏地址:12个优秀的 HTML5 网站设计案例欣赏
  • 教你玩转HTML(html5)h5网页设计,网站开
  • HTML5浪漫爱心表白动画在线演示程序

    万次下载 热门讨论 2014-02-12 23:50:10
    HTML5浪漫爱心表白动画在线演示.htm 修改一下情人节送女友
  • 这篇博文通过图文详细介绍在PyCharm中如何完整优雅地安装配置PyQt5的所有工具包,主要内容包括PyQt5、PyQt5-tools的依赖包安装和Qt Designer、PyUIC、PyRcc三个工具的设置。最后简单演示了PyQt5的调用方式及三个工具...
  • 2021年5月全国招收程序员429056人。2021年5月全国程序员平均工资14926元,工资中位数13000元,其中96%的人的工资介于1750元到75000元。 城市 排名 city 平均工资 最低工资 中位数 最高工资 招聘人数 百分比 ...
  • YOLOv5训练自己的数据集(超详细完整版)

    万次阅读 多人点赞 2020-10-16 11:38:18
    一.Requirements 本教程所用环境:代码版本V3.0,源码下载地址:...1.在yolov5目录下创建paper_data文件夹(名字可以自定义),目录结构如下,将之前labelImg标注好的xml文件和图片放到对应目录下 paper_
  • YoloV5实战:手把手教物体检测——YoloV5

    万次阅读 多人点赞 2020-10-24 07:35:53
    目录 摘要 训练 1、下载代码 2、配置环境 ...5、修改配置参数 ...YOLOv5并不是一个单独的模型,而是一个模型家族,包括了YOLOv5s、YOLOv5m、YOLOv5l、YOLOv5x、YOLOv5x+TTA,这点有点儿像EfficientDe..
  • KEIL 5 pack离线包 Stm32f1/f2/f3/f4

    万次阅读 多人点赞 2018-08-13 15:43:42
    keil5 pack 离线包安装:安装过keil5软件后,直接双击pack 离线包即可。 F1pack包https://keilpack.azureedge.net/pack/Keil.STM32F1xx_DFP.2.3.0.pack F2pack包...
  • Mysql实现查询5分钟之前的数据

    万次阅读 热门讨论 2019-09-24 14:18:24
    在做交易项目的时候需要一个定时补偿来把交易异常失败但是能继续跑的交易继续跑下去,要求是5分钟跑一次程序,逻辑比较简单,就贴一个查询语句吧 SELECT * FROM 表名 t WHERE 条件一 AND 条件二 AND t.时间 <= ...
  • 学习HTML5这一篇就够了

    万次阅读 多人点赞 2020-09-18 20:50:46
    目录第一章 HTML5概述1.1、什么是HTML1.2、什么是HTML51.3、本文重要说明1.4、浏览器的版本1.5、选择开发工具第二章 HTML5语法2.1、基本结构2.2、语法规范2.3、标签规范第三章 HTML5标签3.1、标题标签3.2、段落标签...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,489,023
精华内容 1,795,609
关键字:

5