计算机竞赛 基于深度学习的植物识别算法 - cnn opencv python
文章目录
- 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 tfimport numpy as npfrom tensorflow.keras import layers, Sequential, Modelclass 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) # ReLU6def call(self, inputs, training=False, **kargs):x = self.conv(inputs)x = self.bn(x, training=training)x = self.activation(x)return xclass 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_ratioself.use_shortcut = (strides == 1) and (in_channel == out_channel)layer_list = []# first bottleneck does not need 1*1 convif expand_ratio != 1:# 1x1 pointwise convlayer_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 functionlayers.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) # 防止输入增大时输出为nanexp_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 modeland returns the loss."""loss = Noneif closure is not None:loss = closure()for group in self.param_groups:weight_decay = group['weight_decay'] # 权重衰减系数momentum = group['momentum'] # 动量因子,0.9或0.8dampening = group['dampening'] # 梯度抑制因子nesterov = group['nesterov'] # 是否使用nesterov动量for p in group['params']:if p.grad is None:continued_p = p.grad.dataif weight_decay != 0: # 进行正则化# add_表示原处改变,d_p = d_p + weight_decay*p.datad_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_pbuf.mul_(momentum).add_(1 - dampening, d_p)if nesterov: # 使用neterov动量# d_p= d_p + momentum*bufd_p = d_p.add(momentum, buf)else:d_p = buf# p = p - lr*d_pp.data.add_(-group['lr'], d_p)return loss
6 最后
🧿 更多资料, 项目分享:
https://gitee.com/dancheng-senior/postgraduate
相关文章:
计算机竞赛 基于深度学习的植物识别算法 - cnn opencv python
文章目录 0 前言1 课题背景2 具体实现3 数据收集和处理3 MobileNetV2网络4 损失函数softmax 交叉熵4.1 softmax函数4.2 交叉熵损失函数 5 优化器SGD6 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 **基于深度学习的植物识别算法 ** …...
ChatGPT如何应对紧急情况和灾害应对?
ChatGPT是一个文本生成模型,它可以用于各种任务,但在处理紧急情况和灾害应对方面,它有一些潜在的用途和限制。在这篇文章中,我们将讨论ChatGPT在紧急情况和灾害应对中的应用,以及如何充分利用这一技术,并提…...
ElementUI浅尝辄止37:Select 选择器
当选项过多时,使用下拉菜单展示并选择内容。 1.如何使用?基础单选 v-model的值为当前被选中的el-option的 value 属性值 <template><el-select v-model"value" placeholder"请选择"><el-optionv-for"item in …...
PCL 基于任意四点计算球心坐标
文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 继续基于之前的思路PCL 基于三个点计算圆心坐标之二(二维),假设存在四个不共面的点, ( x 1 , y 1 ) (x_1,y_1)...
飞书即时消息无需API开发连接Cohere,打造飞书AI智能问答助手
飞书即时消息用户使用场景: 许多企业都在使用飞书系统进行协同办公,而现在有了Cohere大语言模型技术,能够根据用户的提问来自动产生回答,无需人为干预。对于企业负责人来说,他们认为如果将Cohere技术融入到飞书机器人中…...
FPGA实现Cordic算法——向量模式
FPGA实现Cordic算法——向量模式 FPGA实现Cordic算法——向量模式1.cordic算法基本原理2.FPGA实现cordic算法向量模式i、FPGA串行实现cordicii、FPGA流水线实现cordiciii、实验结果 FPGA实现Cordic算法——向量模式 1.cordic算法基本原理 FPGA中运算三角函数,浮点数…...
【常用代码14】el-input输入框内判断正则,只能输入数字,过滤汉字+字母。
问题描述: el-input输入框,只能输入数字,但是不能显示输入框最右边的上下箭头, <el-input v-model"input" type"number" placeholder"请输入内容" style"width: 200px;margin: 50px 0;&…...
[NLP]LLM--使用LLama2进行离线推理
一 模型下载 二 模型推理 本文基于Chinese-LLaMA-Alpaca-2项目代码介绍,使用原生的llama2-hf 克隆好了Chinese-LLaMA-Alpaca-2 项目之后,基于GPU的部署非常简单。下载完成以后的模型参数(Hugging Face 格式)如下: 简单说明一下各个文件的作…...
初始化一个Gin框架的Go-Web项目
使用到的第三方库 gin Gin 框架viper 配置文件管理cors 跨域资源请求配置gorm ORM 库zap 日志记录 main 包 Go 语言程序的入口点 main.go 文件 使用 flag 读取配置文件路径参数,默认当前目录下使用 viper 读取 config.ini 配置文件初始化初始数据初始化随机数种子初…...
Mybatis日期检索格式报错
问题复现 org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause: java.lang.IllegalArgumentException: invalid comparison: java.util.Date and java.lang.String ##…...
如何把Android Framework学彻底?一条龙学习
Framework通俗易懂 平时学习 Android 开发的第一步就是去学习各种各样的 API,如 Activity,Service,Notification 等。其实这些都是 Framework 提供给我们的。Framework 层为开发应用程序提供了非常多的API,我们通过调用这些 API …...
uview indexList 按字母跳转不了
点击字母跳转不到位的问题:在<u-index-list>添加方法select“clickSelect“ 锚点要加id,用对应的字母做为id值, <u-index-anchor :id"key" :index"key"/> <template><view><view class&qu…...
安全模型中的4个P
引言:在安全模型中,经常会碰到PDR,PPDR,IPDRR,CARTA-PPDR等模型,其中的P,是predict?是prevent?还是protect?还是policy呢? 一、4P字典意思解释 1、predict&a…...
网站优化搜索引擎与关键词
网站优化搜索引擎与关键词 人们不应该高估搜索引擎的智商。这不利于seo的研究,事实上,搜索引擎是非常愚蠢的,让我们举一个非常简单的例子,你在搜索引擎中输入“教师”这个词,搜索引擎就会给出一个准确的搜索列表。我们…...
aws-msk-托管kafka集群的简单使用(VPC内部访问:无验证和SASL认证)
1.使用控制台创建即可 根据实例类型创建需要至少15分以上,可以提前创建好ec2实例和Secrets Manager,一会会使用到 2. 创建Secrets Manager (使用无认证时请跳过) 官方文档:https://docs.aws.amazon.com/zh_cn/msk/latest/deve…...
Unity UGUI(二)核心组件
Unity Canvas相关知识学习 文章目录 Unity Canvas相关知识学习1. Canvas:1.1 Render Mode1.2 多个Canvas的显示顺序 2.Canvas Scaler:屏幕分辨率自适应2.1 UI Scale Mode 3. EventSystem4. Standalone Input Module5. Graphic Raycaster:图形…...
代码随想录二刷第二天(Python)
27. 移除元素 题目链接:https://leetcode.cn/problems/remove-element/ 题目描述:给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必…...
Mybatis学习笔记1 Mybatis入门
差不多根据mybatis中文文档:创建第一个mybatismaven项目,将它跑起来 入门_MyBatis中文网 新建库 建表 创建项目 重启之后 配置下Maven与encoding 成习惯了 新建模块 注意:这个GroupId和ArtifactId version是之后,你用Maven install时候后存放的包路径和包名 目录结构:虽然换…...
Spark 管理和更新Hadoop token 流程
Hadoop Token 管理 AM 通过 kerberos authenticationAM 获取 Yarn 和 HDFS TokenAM send tokens to containersContainers load tokens Enable debug message log4j.logger.org.apache.hadoop.securityDEBUG AM Generate tokens Logs: 23/09/07 22:38:50,375 INFO [main]…...
Android文件关联
用户需求:Android在系统文件夹找到一个文件想发送自己开发的app进行处理该怎么办? 这时候可以采用两个Activity,一个Activity用作Launcher,一个用于处理发送的文件;具体Activity intent-filter该怎么写了?可以参考下面的代码: <intent-filter><action androi…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
