基于深度学习的植物识别算法 - cnn opencv python 计算机竞赛

news2024/11/30 8:46:03

文章目录

  • 0 前言
  • 1 课题背景
  • 2 具体实现
  • 3 数据收集和处理
  • 3 MobileNetV2网络
  • 4 损失函数softmax 交叉熵
    • 4.1 softmax函数
    • 4.2 交叉熵损失函数
  • 5 优化器SGD
  • 6 最后

0 前言

🔥 优质竞赛项目系列,今天要分享的是

🚩 **基于深度学习的植物识别算法 **

该项目较为新颖,适合作为竞赛课题方向,学长非常推荐!

🥇学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:3分
  • 工作量:4分
  • 创新点:4分

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

1 课题背景

植物在地球上是一种非常广泛的生命形式,直接关系到人类的生活环境,目前,植物识别主要依靠相关行业从业人员及有经验专家实践经验,工作量大、效率低。近年来,随着社会科技及经济发展越来越快,计算机硬件进一步更新,性能也日渐提高,数字图像采集设备应用广泛,设备存储空间不断增大,这样大量植物信息可被数字化。同时,基于视频的目标检测在模式识别、机器学习等领域得到快速发展,进而基于图像集分类方法研究得到发展。
本项目基于深度学习实现图像植物识别。

2 具体实现

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

3 数据收集和处理

数据是深度学习的基石
数据的主要来源有: 百度图片, 必应图片, 新浪微博, 百度贴吧, 新浪博客和一些专业的植物网站等
爬虫爬取的图像的质量参差不齐, 标签可能有误, 且存在重复文件, 因此必须清洗。清洗方法包括自动化清洗, 半自动化清洗和手工清洗。
自动化清洗包括:

  • 滤除小尺寸图像.
  • 滤除宽高比很大或很小的图像.
  • 滤除灰度图像.
  • 图像去重: 根据图像感知哈希.

半自动化清洗包括:

  • 图像级别的清洗: 利用预先训练的植物/非植物图像分类器对图像文件进行打分, 非植物图像应该有较低的得分; 利用前一阶段的植物分类器对图像文件 (每个文件都有一个预标类别) 进行预测, 取预标类别的概率值为得分, 不属于原预标类别的图像应该有较低的得分. 可以设置阈值, 滤除很低得分的文件; 另外利用得分对图像文件进行重命名, 并在资源管理器选择按文件名排序, 以便于后续手工清洗掉非植物图像和不是预标类别的图像.
  • 类级别的清洗

手工清洗: 人工判断文件夹下图像是否属于文件夹名所标称的物种, 这需要相关的植物学专业知识, 是最耗时且枯燥的环节, 但也凭此认识了不少的植物.

3 MobileNetV2网络

简介

MobileNet网络是Google最近提出的一种小巧而高效的CNN模型,其在accuracy和latency之间做了折中。

主要改进点

相对于MobileNetV1,MobileNetV2 主要改进点:

  • 引入倒残差结构,先升维再降维,增强梯度的传播,显著减少推理期间所需的内存占用(Inverted Residuals)
  • 去掉 Narrow layer(low dimension or depth) 后的 ReLU,保留特征多样性,增强网络的表达能力(Linear Bottlenecks)
  • 网络为全卷积,使得模型可以适应不同尺寸的图像;使用 RELU6(最高输出为 6)激活函数,使得模型在低精度计算下具有更强的鲁棒性
  • MobileNetV2 Inverted residual block 如下所示,若需要下采样,可在 DW 时采用步长为 2 的卷积
  • 小网络使用小的扩张系数(expansion factor),大网络使用大一点的扩张系数(expansion factor),推荐是5~10,论文中 t = 6 t = 6t=6

倒残差结构(Inverted residual block

ResNet的Bottleneck结构是降维->卷积->升维,是两边细中间粗

而MobileNetV2是先升维(6倍)-> 卷积 -> 降维,是沙漏形。
在这里插入图片描述区别于MobileNetV1,
MobileNetV2的卷积结构如下:
在这里插入图片描述
因为DW卷积不改变通道数,所以如果上一层的通道数很低时,DW只能在低维空间提取特征,效果不好。所以V2版本在DW前面加了一层PW用来升维。

同时V2去除了第二个PW的激活函数改用线性激活,因为激活函数在高维空间能够有效地增加非线性,但在低维空间时会破坏特征。由于第二个PW主要的功能是降维,所以不宜再加ReLU6。
在这里插入图片描述
tensorflow相关实现代码



    import tensorflow as tf
    import numpy as np
    from tensorflow.keras import layers, Sequential, Model
    
    class ConvBNReLU(layers.Layer):
        def __init__(self, out_channel, kernel_size=3, strides=1, **kwargs):
            super(ConvBNReLU, self).__init__(**kwargs)
            self.conv = layers.Conv2D(filters=out_channel, 
                                      kernel_size=kernel_size, 
                                      strides=strides, 
                                      padding='SAME', 
                                      use_bias=False,
                                      name='Conv2d')
            self.bn = layers.BatchNormalization(momentum=0.9, epsilon=1e-5, name='BatchNorm')
            self.activation = layers.ReLU(max_value=6.0)   # ReLU6
            
        def call(self, inputs, training=False, **kargs):
            x = self.conv(inputs)
            x = self.bn(x, training=training)
            x = self.activation(x)
            
            return x


    class InvertedResidualBlock(layers.Layer):
        def __init__(self, in_channel, out_channel, strides, expand_ratio, **kwargs):
            super(InvertedResidualBlock, self).__init__(**kwargs)
            self.hidden_channel = in_channel * expand_ratio
            self.use_shortcut = (strides == 1) and (in_channel == out_channel)
            
            layer_list = []
            # first bottleneck does not need 1*1 conv
            if expand_ratio != 1:
                # 1x1 pointwise conv
                layer_list.append(ConvBNReLU(out_channel=self.hidden_channel, kernel_size=1, name='expand'))
            layer_list.extend([
                
                # 3x3 depthwise conv 
                layers.DepthwiseConv2D(kernel_size=3, padding='SAME', strides=strides, use_bias=False, name='depthwise'),
                layers.BatchNormalization(momentum=0.9, epsilon=1e-5, name='depthwise/BatchNorm'),
                layers.ReLU(max_value=6.0),
                
                #1x1 pointwise conv(linear) 
                # linear activation y = x -> no activation function
                layers.Conv2D(filters=out_channel, kernel_size=1, strides=1, padding='SAME', use_bias=False, name='project'),
                layers.BatchNormalization(momentum=0.9, epsilon=1e-5, name='project/BatchNorm')
            ])
            
            self.main_branch = Sequential(layer_list, name='expanded_conv')
        
        def call(self, inputs, **kargs):
            if self.use_shortcut:
                return inputs + self.main_branch(inputs)
            else:
                return self.main_branch(inputs)  




4 损失函数softmax 交叉熵

4.1 softmax函数

Softmax函数由下列公式定义
在这里插入图片描述
softmax 的作用是把 一个序列,变成概率。

在这里插入图片描述

softmax用于多分类过程中,它将多个神经元的输出,映射到(0,1)区间内,所有概率的和将等于1。

python实现

def softmax(x):
    shift_x = x - np.max(x)    # 防止输入增大时输出为nan
    exp_x = np.exp(shift_x)
    return exp_x / np.sum(exp_x)

PyTorch封装的Softmax()函数

dim参数:

  • dim为0时,对所有数据进行softmax计算

  • dim为1时,对某一个维度的列进行softmax计算

  • dim为-1 或者2 时,对某一个维度的行进行softmax计算

    import torch
    x = torch.tensor([2.0,1.0,0.1])
    x.cuda()
    outputs = torch.softmax(x,dim=0)
    print("输入:",x)
    print("输出:",outputs)
    print("输出之和:",outputs.sum())
    

4.2 交叉熵损失函数

定义如下:
在这里插入图片描述
python实现

def cross_entropy(a, y):
    return np.sum(np.nan_to_num(-y*np.log(a)-(1-y)*np.log(1-a)))
 
# tensorflow version
loss = tf.reduce_mean(-tf.reduce_sum(y_*tf.log(y), reduction_indices=[1]))
 
# numpy version
loss = np.mean(-np.sum(y_*np.log(y), axis=1))

PyTorch实现
交叉熵函数分为二分类(torch.nn.BCELoss())和多分类函数(torch.nn.CrossEntropyLoss()


    # 二分类 损失函数
    loss = torch.nn.BCELoss()
    l = loss(pred,real)


    # 多分类损失函数
    loss = torch.nn.CrossEntropyLoss()

5 优化器SGD

简介
SGD全称Stochastic Gradient Descent,随机梯度下降,1847年提出。每次选择一个mini-
batch,而不是全部样本,使用梯度下降来更新模型参数。它解决了随机小批量样本的问题,但仍然有自适应学习率、容易卡在梯度较小点等问题。
在这里插入图片描述
pytorch调用方法:

torch.optim.SGD(params, lr=<required parameter>, momentum=0, dampening=0, weight_decay=0, nesterov=False)

相关代码:

    def step(self, closure=None):
        """Performs a single optimization step.

        Arguments:
            closure (callable, optional): A closure that reevaluates the model
                and returns the loss.
        """
        loss = None
        if closure is not None:
            loss = closure()

        for group in self.param_groups:
            weight_decay = group['weight_decay'] # 权重衰减系数
            momentum = group['momentum'] # 动量因子,0.9或0.8
            dampening = group['dampening'] # 梯度抑制因子
            nesterov = group['nesterov'] # 是否使用nesterov动量

            for p in group['params']:
                if p.grad is None:
                    continue
                d_p = p.grad.data
                if weight_decay != 0: # 进行正则化
                	# add_表示原处改变,d_p = d_p + weight_decay*p.data
                    d_p.add_(weight_decay, p.data)
                if momentum != 0:
                    param_state = self.state[p] # 之前的累计的数据,v(t-1)
                    # 进行动量累计计算
                    if 'momentum_buffer' not in param_state:
                        buf = param_state['momentum_buffer'] = torch.clone(d_p).detach()
                    else:
                    	# 之前的动量
                        buf = param_state['momentum_buffer']
                        # buf= buf*momentum + (1-dampening)*d_p
                        buf.mul_(momentum).add_(1 - dampening, d_p)
                    if nesterov: # 使用neterov动量
                    	# d_p= d_p + momentum*buf
                        d_p = d_p.add(momentum, buf)
                    else:
                        d_p = buf
				# p = p - lr*d_p
                p.data.add_(-group['lr'], d_p)

        return loss

6 最后

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1159556.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

交叉编译tslib

交叉编译tslib 环境&#xff1a; ubuntu16.04(虚拟机) tslib 版本&#xff1a;1.4.0 交叉编译器&#xff1a;gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf 目标架构&#xff1a;ARM 野火imx6ull pro开发板 tslib的下载 tslib的下载地址 https://github.com/Mic…

Python数据分析(四)-- 操作Excel文件

1 操作Excel文件-多种实现方式 在实际生产中&#xff0c;经常会用到excel来处理数据&#xff0c;虽然excel有强大的公式&#xff0c;但是很多工作也只能半自动化&#xff0c;配合Python使用可以自动化部分日常工作&#xff0c;大大提升工作效率。 openpyxl&#xff1a;只允许读…

第一章 引言 【数据结构与算法】【精致版】

第一章 引言 【数据结构与算法】【精致版】 前言版权第一章 引言三个问题超市商品问题人机对弈问题多岔路口交通灯的管理问题 1.1 数据结构的概念1.2 数据结构的内容1.2.1 数据的逻辑结构1.2.2 数据的存储结构 1.3 算法1.3.1 算法的概念1.3.2 算法的评价标准1.3.3 算法的描述1.…

GAMP源码阅读:卫星位置钟差计算

原始 Markdown文档、Visio流程图、XMind思维导图见&#xff1a;https://github.com/LiZhengXiao99/Navigation-Learning 文章目录 1、satposs_rtklib()2、ephclk()1. eph2clk()&#xff1a;时钟校正参数&#xff08; a f 0 、 a f 1 、 a f 2 a_{f0}、a_{f1}、a_{f2} af0​、af…

【编程语言发展史】C语言的诞生及其影响

目录 一、C语言的历史背景 二、C语言的设计思想 三、C语言的语法特点 四、C语言的应用领域 五、C语言的影响 六、总结 C语言是一种高级计算机编程语言&#xff0c;它的诞生和发展对计算机科学和软件工程领域产生了深远的影响。本文将详细介绍C语言的诞生及其影响&#xf…

【原创】java+swing+mysql个人理财管理系统设计与实现

摘要&#xff1a; 个人理财管理系统是一款帮助用户有效管理个人财务的软件&#xff0c;本文将详细介绍该系统的设计过程&#xff0c;包括功能模块、数据库设计、界面设计等&#xff0c;系统采用javaswingmysql技术组合。 功能分析&#xff1a; 系统主要提供给管理员、用户使…

C++数据结构算法篇Ⅰ

C数据结构算法篇Ⅰ &#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;C算法 &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 主要内容讲解数据结构中的链表结构 文章目录 C数据…

项目管理之项目质量管理MoSCoW(莫斯科)优先级排序法

项目质量管理是项目管理中至关重要的一环&#xff0c;它贯穿于项目的整个生命周期&#xff0c;包括项目启动、规划、执行、监控和控制。为了确保项目工作的质量&#xff0c;我们需要从多个方面入手&#xff0c;以下是一些关于如何保障项目工作质量管理的内容。 项目产品质量检…

基于SSM的毕业设计项目管理系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

历年网规上午真题笔记(2016年)

解析:B 嵌入式系统的存储结构采用分级的方法设计,即寄存器组、高速缓冲存储器(Cache)、内存(包括Flash)和外存,它们在存取速度上依次递减,而在存储容量上逐级增加。 解析:C/A ERP是一种面向制作行业进行物质资源、资金资源和信息资源集成一体化管理的企业信息管理系…

poi兴趣点推荐数据集介绍

介绍 foursquare数据集包含2153471个用户&#xff0c;1143092个场所&#xff0c;1021970个签到&#xff0c;27098490个社交关系以及用户分配给场所的2809581评级&#xff0c;我们常用的是根据NYC和TKY都是从该数据集中抽取出来的。 下载地址&#xff1a;https://sites.google.…

橙河网络:海外问卷调查是什么项目?

大家好&#xff0c;我是橙河网络&#xff0c;今天聊一聊海外问卷调查是什么项目&#xff1f; 海外问卷调查并不是一个新行业&#xff0c;早在十几年前就已经有人在做了&#xff0c;但是因为项目的名字里带有“海外”“国外”的字眼&#xff0c;导致很多人直接从字面意思去理解…

敲敲云零代码平台超实用表单设计技巧推荐,分分钟玩转零代码

敲敲云是一个APaaS零代码云平台&#xff0c;帮助企业快速搭建个性化业务应用。用户不需要编码就能够搭建出用户体验上佳的销售、运营、人事、采购等核心业务应用&#xff0c;打通企业内部数据。平台拥有完善的表单引擎、流程引擎、仪表盘等。 有时我们在添加明细表时&#xff0…

【考研数学】概率论与数理统计 —— 第七章 | 参数估计(2,参数估计量的评价、正态总体的区间估计)

文章目录 一、参数估计量的评价标准1.1 无偏性1.2 有效性1.3 一致性 二、一个正态总体参数的双侧区间估计2.1 对参数 μ \mu μ 的双侧区间估计 三、一个正态总体的单侧置信区间四、两个正态总体的双侧置信区间写在最后 一、参数估计量的评价标准 1.1 无偏性 设 X X X 为总…

【银行测试】支付功能、支付平台、支持渠道如何测试?

有朋友提问&#xff1a;作为一个支付平台&#xff0c;接入了快钱、易宝或直连银行等多家的渠道&#xff0c;内在的产品流程是自己的。业内有什么比较好的测试办法&#xff0c;来测试各渠道及其支持的银行通道呢&#xff1f; 作为产品&#xff0c;我自己办了十几张银行卡方便测…

效率提升测试工具开发的思考

本文针对测试部效率提升测试工具开发、管理、维护暴露出来的问题的一些思考以及一些个人改进观点。 写在前面 本文提到的效率提升测试工具不是指的部门中固有的自动化测试工具&#xff0c;这里提到的测试工具统一指测试人员在工作之余自主开发用于期望替代重复、繁琐、耗时的手…

如何在MacOS使用homebrew安装Nginx

文章目录 Homebrew安装nginxbrew启动Nginxbrew关闭Nginx 参考文章地址 Homebrew安装nginx 在确保MacOS 安装Homebrew成功以后&#xff0c;执行如下命令 brew install nginx注意&#xff1a;Nginx安装成功后会提示目录位置&#xff1b;每个人的系统可能因为Homebrew的安装位置…

永宏(FATEK)PLC通讯协议

文章目录 背景说明通讯帧通讯数据地址16进制数据元和ASCII的转换永宏通讯协议举例命令码40&#xff08;PLC概略系统状态读取&#xff09;命令码41&#xff08;PLC的RUN/STOP控制&#xff09;命令码42&#xff08;单一个单点运作控制&#xff09;命令码43&#xff08;多个连续单…

【自用】vmware workstation建立主机window与虚拟机ubuntu之间的共享文件夹

1.在windows中建立1个文件夹 在vmware中设置为共享文件夹 参考博文&#xff1a; https://zhuanlan.zhihu.com/p/650638983 2.解决&#xff1a; &#xff08;1&#xff09;fuse: mountpoint is not empty &#xff08;2&#xff09;普通用户也能使用共享目录 参考博文&#x…

Unity Profiler 详细解析(二)

Profiler的主要参数详解 1. Memory Profiler Uesd Total : 当前帧的Unity内存&#xff0c;Mono内存&#xff0c;GfxDriver内存&#xff0c;Profiler内存以及额外内存的总和。 Reserved Total&#xff1a; 系统在当前帧申请的总体物理内存 Total System Memory Usage&#xff1…