基于深度学习FasterRCNN模型Restnet50 的生活垃圾智能分类(准确率达84%)-含python工程全源码

news2024/11/19 7:31:43

目录

  • 前言
  • 总体设计
    • 系统整体结构图
    • 系统流程图
  • 运行环境
    • 1. 硬件环境
    • 2. Python 环境
  • 模块实现
    • 1. 数据预处理
    • 2. 数据加载
    • 3. 模型构建
    • 4. 模型训练及保存
    • 5. 模型加载与调用
  • 系统测试
    • 1. 模型准确率
    • 2. 分类别准确率
  • 工程源代码下载
  • 其它资料下载

在这里插入图片描述

前言

本项目基于Faster R-CNN模型,通过RPN网络(Region Proposal Network)获取图片中的候选区域,并利用RestNet50模型提取特征,旨在实现对生活垃圾的智能分拣。

在该项目中,我们使用Faster R-CNN模型,它是一种经典的目标检测算法,能够同时进行物体检测和区域提议。通过RPN网络,我们能够在输入图片中快速识别出潜在的候选区域,这些区域可能包含生活垃圾物品。

接下来,我们使用RestNet50模型进行特征提取。RestNet50是一种深度卷积神经网络,具有较强的特征提取能力。我们将候选区域输入RestNet50模型,提取出高维特征表示,以捕捉垃圾物品的关键信息。

通过将候选区域和其对应的特征输入到后续的分类器中,我们可以对生活垃圾进行智能分拣。分类器可以根据特征表示判断每个候选区域属于哪一类垃圾,例如可回收物、厨余垃圾、有害垃圾等,实现智能化的垃圾分类过程。

本项目的目标是利用Faster R-CNN模型和RestNet50模型的结合,通过智能化的图片分析和特征提取,实现对生活垃圾的智慧分拣。这项技术有助于提高垃圾处理的效率和准确性,为环境保护和资源回收做出贡献。

总体设计

本部分包括系统整体结构图和系统流程图。

系统整体结构图

系统整体结构如图所示。

在这里插入图片描述

系统流程图

系统流程如图所示。

在这里插入图片描述

运行环境

本部分包括硬件环境和 Python 环境。

1. 硬件环境

FasterRCNN 对计算要求较高,有一部分是 Restnet50 的卷积层。必须使用较大内存的GPU 才可以完成训练。在本项目中,用华为云提供的模型训练服务(GPU tesla P100)实现,链接:https://www.hwtelcloud.com/products/mts。

2. Python 环境

使用软件的主要版本如下:

Python==3.6
TensorFlow==1.13.1
Keras==2.0.3
CV2
naie(是华为针对器模型训练服务所设计的库)

模块实现

本项目包括 5 个模块:数据预处理、数据加载、模型构建、模型保存及训练、模型加载及调用,下面分别给出各模块的功能介绍及相关代码。

1. 数据预处理

数据下载地址: https://pan.baidu.com/s/1ZAbzYMLv0fcLFJsu64u0iw,提取码:yba3

数据信息被存储在 json 文件中,使用 python 和 jupyter notebook 对 json 文件进行解析,并进行数据探索。经过分析,获取的垃圾数据集中单类垃圾共有 80000 张训练集图片,204种分类。且每种分类的垃圾图片数量基本相同,约为 300 张左右。由于时间短,仅使用了10种类别的单类图片用于训练和验证,这 10 种类别分别是瓜子壳、核桃、花生壳、面包、饼干、菌菇类、菜叶、菜根、甘蔗皮、中药材、枣核。其中训练集有 3000 张,测试集有843张,如图所示。

在这里插入图片描述

垃圾图片频数直方图

由于 FasterRCNN 使用 anchor 机制,即锚框。需要获取样本尺寸信息作为先验信息,设计锚框。因此,使用 matplotlib 绘制出关于样本尺寸的散点图和直方图。如图1~图 3 所示。

在这里插入图片描述

图1 宽-长散点图

在这里插入图片描述

图2 垃圾目标宽度直方图

在这里插入图片描述

图3 垃圾目标长度直方图

锚框机制,需要预先提供九个不同尺寸的锚框,应尽量贴合目标的尺寸。使用 K-means算法进行聚类,获得合适的锚框,如下图所示。

#使用KMeans确定anchor的长宽
from sklearn.cluster import KMeans
from sklearn.externals import joblib
data=np.hstack((np.array(widths).reshape((-1,1)),np.array(heights).reshape((-1,1))))
clf = KMeans(n_clusters=9)
s = clf.fit(data)
centers=clf.cluster_centers_
plt.scatter(widths,heights,alpha=0.2)
plt.scatter([i[0] for i in centers ],[i[1] for i in centers ],c='r')

在这里插入图片描述

聚类结果

结合Kmeans结果,并进行手动调整,可以设计锚框尺寸。

#锚框尺寸
     self.anchor_box_scales = [150, 300, 435]
     #锚框比例
     self.anchor_box_ratios = [[1, 1], [1, 0.91], [1, 1.25]]

2. 数据加载

本项目使用 biendata(https://biendata.com/)的一个比赛,2020 海华 AI 挑战赛垃圾分类。这个比赛,与华为模型训练服务合作,可以直接在华为模型训练平台上下载、读取训练比赛数据。

使用 github 上提供基于 Keras 的 FasterRCNN 模型。该模型需要将图片信息以 VOC2012数据集的格式进行存储,将图片信息转为该格式,代码写在 garbage_dataset.py 中。

  def w_voc(self):#将目标的信息写入voc格式数据集中
        data_path = 'VOC2012'
        print("将目标的信息写入voc格式数据集中")
        #annot_path是存放目标信息xml文件的文件夹
        annot_path = os.path.join(data_path, 'Annotations_single')
        #imgs_path是存放图片的文件夹位置
        #imgs_path = os.path.join(data_path, 'JPEGImages')
        #imgset_path是存放图片名的文件夹
        imgsets_path_trainval = os.path.join(data_path, 'ImageSets', 'single', 'trainval.txt')
        annot_indexs=0#用来标记新图片的起始目标信息位置
        if os.listdir(annot_path) != None:
            os.system('rm -f '+annot_path+'/*')
        with open(self.json_dir,'r',encoding='utf-8') as fp:
            self.json_dict = json.load(fp)
        with open(imgsets_path_trainval,'w') as fp:#将图片名存入imgsets中
            for img in self.json_dict['images']:
                fp.write(img['file_name'].split('/')[1]+'\n')
        for img in self.json_dict['images']:
            annots=[]
            file_name=img['file_name'].split('/')[1]
            xml_name=file_name.split('.')[0]+'.xml'
            for annot in self.json_dict['annotations'][annot_indexs:]:
#获取每张图片下的目标信息
                if str(annot['image_id'])==file_name.split('.')[0]:
                    annots.append(annot)
                    annot_indexs+=1#更新目标信息索引
                else:
                    break
            #将图片信息与目标信息写入xml文件中,并存入annotations文件夹

在 FasterRCNN 中对 VOC 格式数据读取代码存在 keras_frcnn/pascal_voc_parser.py。再通 过 keras_frcnn/data_augment.py 读 取 每 一 张 图 片 信 息 和 相 应 目 标 信 息 ,keras_frcnn/data_generators.py 作为发生器。

3. 模型构建

数据加载进模型之后,需要定义模型结构,并优化损失函数。

1)定义模型结构

keras_frcnn/resnet.py 调用相关的模型层。

from keras_frcnn import resnet as nn
#定义基本网络(此处为Resnet,可以是VGG,Inception等)
shared_layers = nn.nn_base(img_input, trainable=True)
#定义RPN,建立在基础层上
num_anchors=len(cfg.anchor_box_scales)* len(cfg.anchor_box_ratios)
rpn = nn.rpn(shared_layers, num_anchors)
classifier = nn.classifier(shared_layers, roi_input, cfg.num_rois, 	nb_classes=len(classes_count), trainable=True)
model_rpn = Model(img_input, rpn[:2])
model_classifier = Model([img_input, roi_input], classifier)
#这是一个同时包含RPN和分类器的模型,用于加载/保存模型的权重
model_all = Model([img_input, roi_input], rpn[:2] + classifier)

2. 损失函数及模型优化

#优化器
optimizer = Adam(lr=1e-5)
optimizer_classifier = Adam(lr=1e-5)
model_rpn.compile(optimizer=optimizer,
loss=[losses_fn.rpn_loss_cls(num_anchors), 			losses_fn.rpn_loss_regr(num_anchors)])
model_classifier.compile(optimizer=optimizer_classifier,
loss=[losses_fn.class_loss_cls, 			losses_fn.class_loss_regr(len(classes_count)-1)],                           
metrics={'dense_class_{}'.format(len(classes_count)):'accuracy'})
model_all.compile(optimizer='sgd', loss='mae')

4. 模型训练及保存

本部分包括模型训练和模型保存。

1)模型训练

#相关参数
epoch_length = 1000
num_epochs = int(cfg.num_epochs)
iter_num = 0
#调用模型进行训练
 X, Y, img_data = next(data_gen_train)
 loss_rpn = model_rpn.train_on_batch(X, Y)             
 P_rpn = model_rpn.predict_on_batch(X)

2)模型保存

model_all.save_weights(cfg.model_path)
mox.file.copy(cfg.model_path, 	os.path.join(Context.get_model_path(), 'model_frcnn.vgg.hdf5'))

5. 模型加载与调用

Keras 需要先将网络定义好,才能加载模型。相关代码在 test_frcnn_kitti.py

1)模型加载

#定义RPN,建立在基础层上		num_anchors=len(cfg.anchor_box_scales)*len(cfg.anchor_box_ratios)
rpn_layers = nn.rpn(shared_layers, num_anchors)
classifier=nn.classifier(feature_map_input,roi_input, cfg.num_rois, 	nb_classes=len(class_mapping),trainable=True)
model_rpn = Model(img_input, rpn_layers)
model_classifier_only=Model([feature_map_input,roi_input],classifier)
model_classifier= Model([feature_map_input, roi_input], classifier)
print('Loading weights from {}'.format(cfg.model_path))
model_rpn.load_weights(cfg.model_path, by_name=True)
model_classifier.load_weights(cfg.model_path, by_name=True)
model_rpn.compile(optimizer='sgd', loss='mse')
model_classifier.compile(optimizer='sgd', loss='mse')

2)模型测试

def predict_single_image(img_path, model_rpn, model_classifier_only, cfg, class_mapping):
    #将空间金字塔池应用于建议的区域
    boxes = dict()
    for jk in range(result.shape[0] // cfg.num_rois + 1):
        rois = np.expand_dims(result[cfg.num_rois * jk:cfg.num_rois * (jk + 1), :], axis=0)
        if rois.shape[1] == 0:
            break
        if jk == result.shape[0] // cfg.num_rois:
            curr_shape = rois.shape
            target_shape = (curr_shape[0], cfg.num_rois, curr_shape[2])
            rois_padded = np.zeros(target_shape).astype(rois.dtype)
            rois_padded[:, :curr_shape[1], :] = rois
            rois_padded[0, curr_shape[1]:, :] = rois[0, 0, :]
            rois = rois_padded
        [p_cls, p_regr] = model_classifier_only.predict([F, rois])
            for ii in range(p_cls.shape[1]):
            if np.max(p_cls[0, ii, :]) < bbox_threshold or np.argmax(p_cls[0, ii, :]) == (p_cls.shape[2] - 1):
                continue
            cls_num = np.argmax(p_cls[0, ii, :])
            if cls_num not in boxes.keys():
                boxes[cls_num] = []
            (x, y, w, h) = rois[0, ii, :]
            try:
                (tx, ty, tw, th) = p_regr[0, ii, 4 * cls_num:4 * (cls_num + 1)]
                tx /= cfg.classifier_regr_std[0]
                ty /= cfg.classifier_regr_std[1]
                tw /= cfg.classifier_regr_std[2]
                th /= cfg.classifier_regr_std[3]
                x, y, w, h = roi_helpers.apply_regr(x, y, w, h, tx, ty, tw, th)

系统测试

本部分包括模型准确率和分类别准确率。

1. 模型准确率

通过华为模型训练平台对模型进行测试,并写入result.txt文件中存储,相关代码如下:

true_count=0#使用测试集进行准确度的测试,并存入文件中
with open('./val_single.txt','r') as f:
val_data=f.readlines()
img_count=len(val_data)
  for index,val in enumerate(val_data):
     if index%50 ==0:
        K.clear_session()
        test_cls=predict(val.split()[0])
        if int(test_cls)==int(val.split()[1]):
            true_count+=1
        with open('/cache/result.txt','a') as f: 
f.write("%s %s %s\n"%(val.split()[0],val.split()[1],test_cls))    accuray=true_count/img_count
with open('/cache/result.txt','a') as f:
    f.write("val_lenght:%s,accruray:%s"%(img_count,accuray))  

数据属性,分别是图片地址,真实标签,识别标签,共有843条数据。以下是部分结果数据,总体准确率为0.840,识别效果比较理想。

/cache/train/images_withoutrect/24726.png 63 63
/cache/train/images_withoutrect/12114.png 3 3
/cache/train/images_withoutrect/24671.png 63 63
/cache/train/images_withoutrect/13764.png 51 51
/cache/train/images_withoutrect/12759.png 19 19
/cache/train/images_withoutrect/11339.png 2 2
/cache/train/images_withoutrect/11451.png 2 2
/cache/train/images_withoutrect/14072.png 50 0
......
val_lenght:843,accruray:0.8398576512455516

2. 分类别准确率

FasterRcnn 模型使用 anchor 机制,anchor 的设置和不同类别识别的准确率息息相关。在这里对分类别准确率进行分析,并计算它们的真实边框和锚点边框的差距。

相关代码如下:

#对结果按类别计算准确度
for category_name in message['categories']:
    categories_name.append([category_name['id'],category_name['name']])
for category in categorys:
    print(categories_name[category-1],category) 
labels=[]
categorys_accuray={}
with open('result.txt','r') as f:
    results=f.readlines()[:-1]
for result in results:
    path,true_label,test_label=result.split()
    true_label=int(true_label)
    test_label=int(test_label)
    if true_label not in labels:
        labels.append(true_label)
for label in labels:
    categorys_img_count=0
    categorys_true_count=0
    for result in results:
        path,true_label,test_label=result.split()
        true_label=int(true_label)
        test_label=int(test_label)
        if true_label==label:
            categorys_img_count+=1
            if true_label==test_label:
                categorys_true_count+=1    categorys_accuray[categories_name[label-1][1]]=categorys_true_count/categorys_img_count
print(categorys_accuray)

结果:

{‘中药材’: 0.9878048780487805, ‘花生壳’: 1.0, ‘菌菇类’: 0.8901098901098901,
‘面包’: 0.6593406593406593, ‘核桃’: 1.0, ‘菜叶’: 0.8055555555555556,
‘菜根’:0.5409836065573771, ‘甘蔗皮’: 0.9761904761904762,
‘瓜子壳’:0.5106382978723404,‘饼干’: 0.9690721649484536}

面包、菜根、瓜子壳的准确率较低。下面将三种类别的真实边框与锚点进行可视化比较,如图 4 和图 5 所示。

在这里插入图片描述

真实边框与锚框尺寸散点

在这里插入图片描述

混淆矩阵

图 4 中可以看到左下角圆点,偏离较远,由参数知道此点为瓜子壳。偏离 anchor 较远的点容易出现无法识别的现象,例如瓜子壳、菜根等容易无法识别。图 5 中瓜子壳和花生壳容易混淆,面包和中药材容易混淆,菜根和菜叶容易混淆。正是由于无法识别混淆的情况,使得瓜子壳、菜根、面包准确率较低。

工程源代码下载

详见本人博客资源下载页

其它资料下载

如果大家想继续了解人工智能相关学习路线和知识体系,欢迎大家翻阅我的另外一篇博客《重磅 | 完备的人工智能AI 学习——基础知识学习路线,所有资料免关注免套路直接网盘下载》
这篇博客参考了Github知名开源平台,AI技术平台以及相关领域专家:Datawhale,ApacheCN,AI有道和黄海广博士等约有近100G相关资料,希望能帮助到所有小伙伴们。

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

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

相关文章

mmrotate框架基本使用

1、如何将类交给mmrotate框架容器管理 容器&#xff1a;框架中现有基本容器包括DATASETS, BACKBONES, LOSSES, DETECTORS。初始化容器&#xff1a;Registry(‘backbone’)中’backbone’为容器初始化配置文件。#/mmdet/models/builder.py 部分代码 from mmcv.utils import Re…

【Lisp】【Python】在CAD中用插件获取选中字块的文字,在rhino中批量生成图层

文章目录 1 get_selected_text.lsp1.1 使用方法LISP代码解析1.2 动图 2 Rhino中使用PythonScript批量建立图层.py2.1 直接生成2.2 带颜色生成 2.3 动图展示 1 get_selected_text.lsp 1.1 使用方法 用记事本复制以下代码&#xff0c;改文件名为get_selected_text.lsp (defun c:…

springboot高校宿舍报修管理系统-计算机毕设 附源码83946

springboot高校宿舍报修管理系统 摘 要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。在现实…

【AI绘图 丨 Stable_diffusion 系列教程四】— Window 环境 | Stable Diffusion入门教程 及安装(全篇)

&#x1f449;腾小云导读 最近&#xff0c;AI图像生成引人注目&#xff0c;它能够根据文字描述生成精美图像&#xff0c;这极大地改变了人们的图像创作方式。Stable Diffusion作为一款高性能模型&#xff0c;它生成的图像质量更高、运行速度更快、消耗的资源以及内存占用更小&a…

MATLAB+JAVA的混合开发

近期项目中需要使用matlab跟java做混合开发。主要记录一下&#xff0c;此次开发遇到的问题点。 环境&#xff1a;使用的matlab版本是 R2018b。 当前状况&#xff1a;MATLAB代码已经编写好&#xff0c;且运行成功。需要打成jar包才可以被java调用。 步骤一&#xff1a; 按照…

OpenJdk 和 oracleJdk

OpenJDK的网站&#xff08;https://jdk.java.net/&#xff09;通常仅显示最新的几个版本&#xff0c;对于更早的版本&#xff0c;可能不再在主页面上列出。这是因为随着时间的推移&#xff0c;Java社区通常会专注于支持和维护最新的版本&#xff0c;并鼓励开发者尽可能地使用最…

开源软件介绍——国内和国际主要开源社区

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天我们来看一看国内和国际上有哪些主要开源社区。 开源社区的定义 开源社区又称为开放源代码社区&#xff0c;一般由拥有共同兴趣爱好的人组成。根据相应的开源软件许可证协议公布软件源代码的网络平台&a…

【深度学习】5-2 与学习相关的技巧 - 权重的初始值

在神经网络的学习中&#xff0c;权重的初始值特别重要。实际上&#xff0c;设定什么样的权重初始值&#xff0c;经常关系到神经网络的学习能否成功。本节将介绍权重初始值的推荐值&#xff0c;并通过实验确认神经网络的学习是否会快速进行。 可以将权重初始值设为0吗 后面我们…

搜索引擎的个性化搜索:为何搜索结果因人而异

&#x1f482; 个人网站:【海拥】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 目录 前言搜索引擎的工作原理…

uniapp uView2 字体加载错误提示处理(字体离线方案)

最近老是收到有人反馈 uView2的字体图标报错&#xff0c;具体错误提示如下图 这个报错的原因有2种情况 at.licdn.com 网站维护&#xff0c;无法加载&#xff1b;国内这些小程序平台的开发工具日常抽风&#xff0c;代码能跑&#xff0c;但就是报错&#xff0c;简直离谱&#x…

漏洞复现 D-Link DCS 密码泄露漏洞

0x01 漏洞描述 D-link DCS是一款网络摄像机&#xff0c;工作温度为0-50℃。D-link DCS系统存在密码泄露漏洞&#xff0c;攻击者通过漏洞可以获取后台权限。 0x02 漏洞复现 fofa&#xff1a;app“D_Link-DCS-4622” 1.使用poc进行账号密码查看&#xff0c;得到密码登录即可 …

网络安全是什么?怎么学

网络安全基础 安全的定义&#xff1a; 1&#xff09;一种能够识别和消除不安全因素的能力&#xff1b; 2&#xff09;安全是一个持续的过程网络安全是一门涉及计算机科学、网络技术、通信技术、密码技术、信息安全技术、应用数学、数论、信息论等多种学科的综合性科学。 网络…

Redis原理 - 数据结构的底层实现

原文首更地址&#xff0c;阅读效果更佳&#xff01; Redis原理 - 数据结构的底层实现 | CoderMast编程桅杆https://www.codermast.com/database/redis/redis-datastruct-underlying-implementation.html 动态字符串SDS #基本概念 Redis 中保存的 Key 是字符串&#xff0c;V…

C国演义 [第六章]

第六章 最长递增子序列题目理解步骤dp含义递推公式初始化遍历顺序 代码 最长连续递增序列题目理解步骤dp含义递推公式初始化遍历顺序 代码 最长递增子序列 力扣链接 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列&am…

什么是http代理504网关超时错误,怎么处理

HTTP代理504网关超时错误是指代理服务器在尝试连接目标服务器时&#xff0c;等待目标服务器响应的时间超过了预设的时间&#xff0c;导致代理服务器无法返回请求结果给客户端&#xff0c;从而出现网关超时。 为什么会遇到http代理504网关超时错误 我们遇到HTTP代理504网关超时…

CSPM项目管理专业人员能力评价证书报考条件与考试形势

2021年10月&#xff0c;中共中央、国务院发布的《国家标准化发展纲要》明确提出构建多层次从业人员培养培训体系&#xff0c;开展专业人才培养培训和国家质量基础设施综合教育。建立健全人才的职业能力评价和激励机制。由中国标准化协会&#xff08;CAS&#xff09;组织开展的项…

【人工智能概论】 Python标准库——dalib(领域自适应)

【人工智能概论】 Python标准库——dalib&#xff08;领域自适应&#xff09; 文章目录 【人工智能概论】 Python标准库——dalib&#xff08;领域自适应&#xff09;一. 领域鉴别器&#xff08;DomainDiscriminator&#xff09;二. 领域对抗损失&#xff08;DomainAdversarial…

【MongoDB】五、MongoDB分片集群的部署

【MongoDB】五、MongoDB分片集群的部署 实验目的实验内容实验步骤环境准备部署 Config server配置Config Server副本集部署Shard部署mongos启动分片功能查看分片信息 实验小结 实验目的 能够通过部署MongoDB分片集群熟悉MongoDB分片集群架构和基本操作&#xff0c;从而解决大数…

调用有道API实现语音翻译(汉译英)

目录 1. 作者介绍2. 相关介绍2.1 API介绍2.2 网易API介绍 3. 实验过程3.1 调用过程3.2 代码获取3.3 完整代码 1. 作者介绍 南旭东&#xff0c;男&#xff0c;西安工程大学电子信息学院&#xff0c;2022级研究生 研究方向&#xff1a;机器视觉与人工智能 电子邮件&#xff1a;1…

win10 搭建vue环境并运行项目

win10 搭建vue环境并运行项目 1、参考链接2、遇到的问题及解决 1、参考链接 https://blog.csdn.net/qq_44959735/article/details/128886550 2、遇到的问题及解决 运行的时候不要再git bash里&#xff0c;要在自带的powershell里&#xff0c;以管理员权限运行。 问题&#xf…