深度学习毕设项目 基于深度学习的植物识别算法 - cnn opencv python

news2024/10/6 4:07:42

文章目录

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


0 前言

🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。

为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是

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

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

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

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 最后

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

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

相关文章

CRM与ERP如何协同服务于企业

在当今的商业环境中&#xff0c;客户关系管理&#xff08;CRM&#xff09;和 Enterprise Resource Planning&#xff08;ERP&#xff09;是两个不可或缺的系统。它们各自独立&#xff0c;但也可以协同工作&#xff0c;以提供更高效、更全面的企业解决方案。这种协同作用可以在销…

使用功率MOSFET常见的一些问题(三)

使用功率MOSFET常见的一些问题&#xff08;三&#xff09; 1.体二极管2.封装和PCB布局注意事项3.MOS并联 1.体二极管 体二极管是 MOSFET 结构中的固有部分&#xff0c;由 p-body 层和 n-epi 层之间的 p-n 结形成&#xff0c;如图所示。功率MOSFET 是三端器件&#xff0c;其本体…

精进Linux运维:从基础到高级技巧

Linux基础 1. Linux操作系统概述 Linux是一个开源的操作系统内核&#xff0c;由Linus Torvalds在1991年创建。它的灵活性和强大性使其成为服务器和嵌入式设备上的首选操作系统。Linux有许多不同的发行版&#xff08;例如Ubuntu、CentOS、Debian等&#xff09;&#xff0c;每个…

vr智慧党建展厅超强参与感增强党员群众认同感、归属感

党建教育与VR虚拟现实技术的结合&#xff0c;是顺应现代信息化发展趋势的要求&#xff0c;不仅打破了传统党建教育的束缚&#xff0c;还丰富了党建宣传教育的渠道&#xff0c;党建教育VR云课堂平台是基于深圳华锐视点自主研发的VR云课堂平台中去体验各种VR党建教育软件或者视频…

音频修复和增强软件iZotope RX 10 mac特点介绍

iZotope RX 10 mac是一款音频修复和增强软件&#xff0c;主要特点包括&#xff1a; 声音修复&#xff1a;iZotope RX 10可以去除不良噪音、杂音、吱吱声等&#xff0c;使音频变得更加清晰干净。 音频增强&#xff1a;iZotope RX 10支持对音频进行音量调节、均衡器、压缩器、限…

改进LiteOS中物理内存分配算法

一、实验要求 优化TLSF算法&#xff0c;将Best-fit策略优化为Good-fit策略&#xff0c;进一步降低时间复杂度至O(1)。 优化思路&#xff1a; 1.初始化时预先为每个桶挂上若干空闲块&#xff0c;在实际分配时避免分割&#xff08;split&#xff09;操作&#xff0c;加速分配过…

免费使用GPT的网站

登录ChatGPT系统 登录ChatGPT系统 登录ChatGPT系统

使用VScode通过内网穿透在公网环境下远程连接进行开发

文章目录 前言1、安装OpenSSH2、vscode配置ssh3. 局域网测试连接远程服务器4. 公网远程连接4.1 ubuntu安装cpolar内网穿透4.2 创建隧道映射4.3 测试公网远程连接 5. 配置固定TCP端口地址5.1 保留一个固定TCP端口地址5.2 配置固定TCP端口地址5.3 测试固定公网地址远程 前言 远程…

基础课15——语音合成

TTS是语音合成技术的简称&#xff0c;也称为文语转换或语音到文本。它是指将文本转换为语音信号&#xff0c;并通过语音合成器生成可听的语音。TTS技术可以用于多种应用&#xff0c;例如智能语音助手、语音邮件、语音新闻、有声读物等。 TTS技术通常包括以下步骤&#xff1a; …

ubuntu终端代理配置

ubuntu浏览器的无需手动设置,主要解决在终端中的配置问题,按照下面配置后可能会ping不通一些ip,但wget/git都是可以的,具体原因以后再分析 查找端口 首先要找到自己代理对应的HTTP端口,以QV2ray软件作为示例,我为8889 手动配置 # 配置系统proxy export http_proxy=1…

【腾讯云 HAI域探秘】使用高性能应用服务HAI快速开发一款赛博朋克风拼图游戏,化繁从简,低成本进入人工智能时代。

前言 人工智能&#xff08;AI&#xff09;是当今科技领域的热门话题&#xff0c;尤其是自然语言处理&#xff08;NLP&#xff09;技术&#xff0c;它可以让机器理解和生成自然语言。随着大型语言模型&#xff08;LLM&#xff09;的发展&#xff0c;如 GPT-3、DALL-E 等&#xf…

基于SSM医院住院管理系统

摘 要 随着时代的发展&#xff0c;医疗设备愈来愈完善&#xff0c;医院也变成人们生活中必不可少的场所。如今&#xff0c;已经2021年了&#xff0c;虽然医院的数量和设备愈加完善&#xff0c;但是老龄人口也越来越多。在如此大的人口压力下&#xff0c;医院住院就变成了一个问…

引领Serverless构建之路,亚马逊云科技re:Invent 2023首日主题演讲重磅发布

在每年的亚马逊云科技re:lnvent大会&#xff0c;由Peter DeSantis带来的《周一晚间直播》是re:lnvent大会的第一个并让人值得期待的主题演讲。作为亚马逊云科技高级副总裁&#xff0c;Peter发布了数据库和应用领域的三项Serverless创新&#xff0c;使客户能够更快、更轻松地扩展…

RT_Thread_msh_系统msh命令、使用msh时过滤ulog日志、添加msh命令(不带/带参)

1、msh配置 msh功能是自动开启的&#xff0c;配置如下&#xff0c;可以在“RT-Thread Settings”里去修改。 调试过程中遇到msh不能使用&#xff0c;理解msh也是一个线程&#xff0c;有自己的优先级20&#xff0c;高优先级的线程&#xff08;比如main是10&#xff09;如果一直…

自定义 element DatePicker组件指令 使选择器呈现为只读状态,用户无法直接编辑,但可以查看和选择日期

1.问题 现实中遇到列表的搜索条件使用DatePicker 组件进行开始结束时间筛选&#xff0c;但是手动修改input中的值&#xff0c;导致请求参数异常。比如讲clearable设置为false之后还是能手动清空输入框中的值。虽然组件提供了readonly 属性&#xff0c;但是也会让日期选择也无法…

java学习part22包装类

119-面向对象(高级)-包装类的理解_基本数据类型与包装类间的转换_哔哩哔哩_bilibili 1.包装类 2.基本转包装方式 2.1new方式 源码 2.2valueof&#xff08;&#xff09; 3.包装转基本 4.基本类型和包装类型的默认值不一样 比如boolean默认false Boolean默认null&#xff08;对…

电子学会 2023年9月 青少年软件编程Python编程等级考试二级真题解析(选择题+判断题+编程题)

青少年编程Python编程等级考试二级真题解析(选择题+判断题+编程题) 2023年9月 一、选择题(共25题,共50分) 以下代码运行结果是?( ) A. 宸宸 B. 杭杭 C. 玉玉 D. 州州 答案选:A 考点分析:考察python 列表操作 jxw=yyh[2][0],jxw的值是“拱宸桥”,jxw[1]的值是“宸”…

QT QGraphicsItem 图元覆盖导致鼠标点击事件不能传递到被覆盖图元

一、概述 在日常开发中&#xff0c;遇到这样一个问题&#xff0c;线图元和引脚图元重叠&#xff0c;导致点击引脚图元&#xff0c;没有进入引脚图元的鼠标点击事件中。 二、产生原因 如果您的 QGraphicsItem 上有一个图元覆盖了它&#xff0c;可能会导致鼠标事件无法正常触发…

软件设计之原型模式

原型模式是从一个对象再创建另一个可定制的对象&#xff0c;而且不需要知道任何创建的细节。拷贝分浅拷贝和深拷贝。浅拷贝无法拷贝引用对象。在面试的时候&#xff0c;我们会投多家公司&#xff0c;根据岗位的不同我们会适当调整。使用原型模式可以快速达到需求&#xff0c;下…

抖音直播招聘报白如何提高求职者体验?

为了提升抖音直播招聘报白中求职者的体验&#xff0c;以下是一些建议&#xff1a; 提供清晰的招聘流程和信息。在直播招聘开始之前&#xff0c;企业或人力资源公司应提供清晰的流程和信息&#xff0c;包括直播时间和直播平台&#xff0c; 职位信息&#xff0c;招聘要求等&…