计算机竞赛 深度学习卷积神经网络垃圾分类系统 - 深度学习 神经网络 图像识别 垃圾分类 算法 小程序

news2024/11/18 9:37:51

文章目录

  • 0 简介
  • 1 背景意义
  • 2 数据集
  • 3 数据探索
  • 4 数据增广(数据集补充)
  • 5 垃圾图像分类
    • 5.1 迁移学习
      • 5.1.1 什么是迁移学习?
      • 5.1.2 为什么要迁移学习?
    • 5.2 模型选择
    • 5.3 训练环境
      • 5.3.1 硬件配置
      • 5.3.2 软件配置
    • 5.4 训练过程
    • 5.5 模型分类效果(PC端)
  • 6 构建垃圾分类小程序
    • 6.1 小程序功能
    • 6.2 分类测试
    • 6.3 垃圾分类小提示
    • 6.4 答题模块
  • 7 关键代码
  • 8 最后

0 简介

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

深度学习卷积神经网络垃圾分类系统

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

🧿 更多资料, 项目分享:

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

1 背景意义

近年来,随着我国经济的快速发展,国家各项建设都蒸蒸日上,成绩显著。但与此同时,也让资源与环境受到了严重破坏。这种现象与垃圾分类投放时的不合理直接相关,而人们对于环境污染问题反映强烈却束手无策,这两者间的矛盾日益尖锐。人们日常生活中的垃圾主要包括有害垃圾、厨余垃圾、可回收垃圾以及其他垃圾这四类,对不同类别的垃圾应采取不同分类方法,如果投放不当,可能会导致各种环境污染问题。合理地进行垃圾分类是有效进行垃圾处理、减少环境污染与资源再利用中的关键举措,也是目前最合适最有效的科学管理方式,利用现有的生产水平将日常垃圾按类别处理、利用有效物质和能量、填埋无用垃圾等。这样既能够提高垃圾资源处理效率,又能缓解环境污染问题。

而对垃圾的分类首先是在图像识别的基础上的,因此本文想通过使用近几年来发展迅速的深度学习方法设计一个垃圾分类系统,从而实现对日常生活中常见垃圾进行智能识别分类,提高人们垃圾分类投放意识,同时避免人们错误投放而产生的环境污染。

2 数据集

数据集采用了中国发布的垃圾分类标准,该标准将人们日常生活中常见的垃圾分为了四大类。其中,将废弃的玻璃、织物、家具以及电器电子产品等适合回收同时可循环利用的废弃物归为可回收垃圾。将剩菜剩饭、果皮果壳、花卉绿植以及其他餐厨垃圾等容易腐烂的废弃物归为厨余垃圾。将废电池、废药品、废灯管等对人们身体健康和自然环境有害而且应当门处理的废弃物归为有害垃圾。除以上三类垃圾之外的废弃物都归为其他垃圾。

该数据集是图片数据,分为训练集85%(Train)和测试集15%(Test)。其中O代表Organic(有机垃圾),R代表Recycle(可回收)

在这里插入图片描述

在这里插入图片描述

3 数据探索

我们先简单的大致看看数据的情况

所得的垃圾图片数据集中有40个二级类别,图片数量合计
14802张。由图3-1可以看出,各个垃圾类别的图像数据量不均衡,其中图片数据量较少的类别有:类别0(一次性快餐盒)、类别3(牙签)、类别20(快递纸袋);数据量较多的类别是:类别11(菜叶根)、类别21(插头电线)、类别25(毛绒玩具)。

在这里插入图片描述

4 数据增广(数据集补充)

数据增广就是对基础数据集进行扩充,避免因为数据集太少导致在模型训练过程可能出现的过拟合现象,以此来提高模型泛化能力,达到更好的效果。根据扩充数据集的来源可分为两类:内部数据增广是对基础数据集进行水平翻转、垂直翻转、高斯噪声以及高斯模糊等变换操作,来产生新的特征;而外部数据增广是引入新的高质量外部数据来扩充数据集,包括数据爬取与数据筛选两个步骤。

数据爬取是通过网络爬虫技术来实现的,爬虫的流程是,首先向远程服务器端发送请求,获取目标网页的HTML文件;然后跟踪这个链接文件,获取文件数据。各种搜索引擎就是通过爬虫技术来实现网页数据更新,爬取的效率直接决定了搜索的效果。

在这里插入图片描述

根据流程图可以看到,爬虫的流程与用户浏览网页的过程相似,首先输入目标URL地址,向服务器发送请求,接着服务器端会返回包含大量链接的HTML文件,然后提取这些链接将其组成URL列表,通过串行或并行方式从服务器端中下载数据。

由于基础数据集中类别数量不均衡,所以本设计使用网络爬虫方式从百度图库对数量较少的类别进行数据扩充,首先输入想要爬取的图片名称关键字,然后输入想要爬取图片的数量以及存放的文件夹之后,进行图片爬取。

在这里插入图片描述

在这里插入图片描述

5 垃圾图像分类

5.1 迁移学习

5.1.1 什么是迁移学习?

迁移学习是指在一个数据集上,重新利用之前已经训练过的卷积神经网络,并将其迁移到另外的数据集上。

5.1.2 为什么要迁移学习?

卷积神经网络前面的层提取的是图像的纹理、色彩等特征,而越靠近网络后端,提取的特征就会越高级、抽象。所以常用的微调方法是,保持网络中其他参数不变,只修改预训练网络的最后几层,最后几层的参数在新数据集上重新训练得到。其他层的参数保持不变,作为特征提取器,之后再使用较小的学习率训练整个网络。因为从零开始训练整个卷积网络是非常困难的,而且要花费大量的时间以及计算资源,所以采取迁移学习的方式是一种有效策略。

通常在非常大的数据集上对ConvNet进行预训练,然后将ConvNet用作初始化或者是固定特征提取器,以下是两个主要的迁移学习方法:

1.微调卷积网络。使用预训练的网络来初始化网络而不使用随机初始化,比较常用的方法是使用在ImageNet数据集上训练好的模型参数进行初始化,然后训练自己的数据集。

2.将卷积网络作为固定特征提取器。冻结除了全连接层外的所有其他层的权重,将最后的那个全连接层替换为具有随机权重的层,然后只对该层进行训练。

要使用深度学习方法来解决垃圾图像识别分类问题,就需要大量的垃圾图片数据集,因为当数据集太小时,一旦加深模型结构,就很可能出现过拟合的情况,训练出的模型泛化能力不足,识别准确率不高。而基于迁移学习的方法,预训练模型已经具备了提取图像基本特征基的能力,这就能在一定程度上减缓过拟合发生的可能性,将预模型迁移到垃圾图像数据集上进行微调训练,提高识别准确率。

5.2 模型选择

采用迁移学习的方式导入预训练模型,冻结特征提取层,进行微调训练,选取了SeNet154、Se_ResNet50、Se_ResNext101、ResNext101_32x16d_WSL四种模型进行对比实验,选取结果较好的模型进行调优。其中,ResNext101_32x16d_WS预训练模型是由FaceBook在2019年开源的

SeNet154结构

在这里插入图片描述

学长采用的模型结构:

在这里插入图片描述

采用ResNext101_32x16d_WSL网络作为基本的网络结构进行迁移学习,将CBAM注意力机制模块添加在首层卷积层,来增强图像特征表征能力,关注图像的重要特征抑制不必要的特征,固定除全连接层之外的其他层的权重。为降低过拟合,在模型全连接层添加了Dropout层,损失函数采用交叉熵损失函数(CrossEntropyLoss),优化函数对比了SGD和Adam,Adam在起始收敛速度快,但最终SGD精度高,所以采用了SGD。

5.3 训练环境

5.3.1 硬件配置

在这里插入图片描述

5.3.2 软件配置

在这里插入图片描述

5.4 训练过程

构建好模型结构后,设置数据集加载路径,在搭建好的环境中进行模型训练,将训练过程中每轮迭代的Train Loss、Valid Loss、Train
Acc、Valid Acc等数据保存到log日志文件中,然后使用matplotlib库绘制在训练集和测试集上的Accuracy跟Loss的变化曲线。

目前模型训练集准确度83.8%,测试集准确度67.5%,仍有待提高。。

在这里插入图片描述

5.5 模型分类效果(PC端)

在这里插入图片描述

6 构建垃圾分类小程序

学长设计的垃圾分类系统的核心功能是从本地相册上传照片或拍照上传照片进行识别分类,除此之外,还引入了语音识别功能、文字搜索功能、垃圾分类答题功能等满足用户的不同需求。系统的模块设计如下图所示。

·在这里插入图片描述

其中识别模块是用户选择识别功能,包含拍照/相册识别,语音识别、文字搜索等功能,根据所选城市的不同展示相应的垃圾类别;指南功能模块是根据所选城市的不同介绍各种垃圾的种类以及投放要求;答题模块实现垃圾种类的选择答题功能。

6.1 小程序功能

识别模块的功能包括文字搜索、语音识别、拍照识别等,该模块界面设计如图所示:

在这里插入图片描述

首先选择用户所在城市,然后选择使用的搜索方式,当通过三种搜索方式搜索不到相应垃圾类别时,可以通过反馈功能将未识别的垃圾名称向后台反馈信息,以便进一步完善系统。系统核心功能为拍照识别功能,拍照识别功能即调用在前面已经部署在华为云Model
Arts平台上的垃圾分类识别模型,对用户从手机端提交的垃圾图片进行在线识别分类并返回识别结果,调用过程中用到了小程序的云函数功能。

6.2 分类测试

在这里插入图片描述

在这里插入图片描述

6.3 垃圾分类小提示

指南模块实现的功能是根据用户所选择的城市,将云数据库中的数据展示给用户,介绍目前不同城市发布的垃圾分类规则及投放的要求,如下图所示:

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

6.4 答题模块

答题模块也是根据用户所选城市的不同,测评用户对其所在城市垃圾分类规则了解的程度,以此来科普垃圾分类知识以及增强人们垃圾分类的意识,该界面如下图所示,在答完题后显示分数以及正确答案。

在这里插入图片描述

在这里插入图片描述

答题答案表


├─ 其他垃圾_PE塑料袋
├─ 其他垃圾_U型回形针
├─ 其他垃圾_一次性杯子
├─ 其他垃圾_一次性棉签
├─ 其他垃圾_串串竹签
├─ 其他垃圾_便利贴
├─ 其他垃圾_创可贴
├─ 其他垃圾_卫生纸
├─ 其他垃圾_厨房手套
├─ 其他垃圾_厨房抹布
├─ 其他垃圾_口罩
├─ 其他垃圾_唱片
├─ 其他垃圾_图钉
├─ 其他垃圾_大龙虾头
├─ 其他垃圾_奶茶杯
├─ 其他垃圾_干燥剂
├─ 其他垃圾_彩票
├─ 其他垃圾_打泡网
├─ 其他垃圾_打火机
├─ 其他垃圾_搓澡巾
├─ 其他垃圾_果壳
├─ 其他垃圾_毛巾
├─ 其他垃圾_涂改带
├─ 其他垃圾_湿纸巾
├─ 其他垃圾_烟蒂
├─ 其他垃圾_牙刷
├─ 其他垃圾_电影票
├─ 其他垃圾_电蚊香
├─ 其他垃圾_百洁布
├─ 其他垃圾_眼镜
├─ 其他垃圾_眼镜布
├─ 其他垃圾_空调滤芯
├─ 其他垃圾_笔
├─ 其他垃圾_胶带
├─ 其他垃圾_胶水废包装
├─ 其他垃圾_苍蝇拍
├─ 其他垃圾_茶壶碎片
├─ 其他垃圾_草帽
├─ 其他垃圾_菜板
├─ 其他垃圾_车票
├─ 其他垃圾_酒精棉
├─ 其他垃圾_防霉防蛀片
├─ 其他垃圾_除湿袋
├─ 其他垃圾_餐巾纸
├─ 其他垃圾_餐盒
├─ 其他垃圾_验孕棒
├─ 其他垃圾_鸡毛掸
├─ 厨余垃圾_八宝粥
├─ 厨余垃圾_冰激凌
├─ 厨余垃圾_冰糖葫芦
├─ 厨余垃圾_咖啡
├─ 厨余垃圾_圣女果
├─ 厨余垃圾_地瓜
├─ 厨余垃圾_坚果
├─ 厨余垃圾_壳
├─ 厨余垃圾_巧克力
├─ 厨余垃圾_果冻
├─ 厨余垃圾_果皮
├─ 厨余垃圾_核桃
├─ 厨余垃圾_梨
├─ 厨余垃圾_橙子
├─ 厨余垃圾_残渣剩饭
├─ 厨余垃圾_水果
├─ 厨余垃圾_泡菜
├─ 厨余垃圾_火腿
├─ 厨余垃圾_火龙果
├─ 厨余垃圾_烤鸡
├─ 厨余垃圾_瓜子
├─ 厨余垃圾_甘蔗
├─ 厨余垃圾_番茄
├─ 厨余垃圾_秸秆杯
├─ 厨余垃圾_秸秆碗
├─ 厨余垃圾_粉条
├─ 厨余垃圾_肉类
├─ 厨余垃圾_肠
├─ 厨余垃圾_苹果
├─ 厨余垃圾_茶叶
├─ 厨余垃圾_草莓
├─ 厨余垃圾_菠萝
├─ 厨余垃圾_菠萝蜜
├─ 厨余垃圾_萝卜
├─ 厨余垃圾_蒜
├─ 厨余垃圾_蔬菜
├─ 厨余垃圾_薯条
├─ 厨余垃圾_薯片
├─ 厨余垃圾_蘑菇
├─ 厨余垃圾_蛋
├─ 厨余垃圾_蛋挞
├─ 厨余垃圾_蛋糕
├─ 厨余垃圾_豆
├─ 厨余垃圾_豆腐
├─ 厨余垃圾_辣椒
├─ 厨余垃圾_面包
├─ 厨余垃圾_饼干
├─ 厨余垃圾_鸡翅
├─ 可回收物_不锈钢制品
├─ 可回收物_乒乓球拍
├─ 可回收物_书
├─ 可回收物_体重秤
├─ 可回收物_保温杯
├─ 可回收物_保鲜膜内芯
├─ 可回收物_信封
├─ 可回收物_充电头
├─ 可回收物_充电宝
├─ 可回收物_充电牙刷
├─ 可回收物_充电线
├─ 可回收物_凳子
├─ 可回收物_刀
├─ 可回收物_包
├─ 可回收物_单车
├─ 可回收物_卡
├─ 可回收物_台灯
├─ 可回收物_吊牌
├─ 可回收物_吹风机
├─ 可回收物_呼啦圈
├─ 可回收物_地球仪
├─ 可回收物_地铁票
├─ 可回收物_垫子
├─ 可回收物_塑料制品
├─ 可回收物_太阳能热水器
├─ 可回收物_奶粉桶
├─ 可回收物_尺子
├─ 可回收物_尼龙绳
├─ 可回收物_布制品
├─ 可回收物_帽子
├─ 可回收物_手机
├─ 可回收物_手电筒
├─ 可回收物_手表
├─ 可回收物_手链
├─ 可回收物_打包绳
├─ 可回收物_打印机
├─ 可回收物_打气筒
├─ 可回收物_扫地机器人
├─ 可回收物_护肤品空瓶
├─ 可回收物_拉杆箱
├─ 可回收物_拖鞋
├─ 可回收物_插线板
├─ 可回收物_搓衣板
├─ 可回收物_收音机
├─ 可回收物_放大镜
├─ 可回收物_日历
├─ 可回收物_暖宝宝
├─ 可回收物_望远镜
├─ 可回收物_木制切菜板
├─ 可回收物_木桶
├─ 可回收物_木棍
├─ 可回收物_木质梳子
├─ 可回收物_木质锅铲
├─ 可回收物_木雕
├─ 可回收物_枕头
├─ 可回收物_果冻杯
├─ 可回收物_桌子
├─ 可回收物_棋子
├─ 可回收物_模具
├─ 可回收物_毯子
├─ 可回收物_水壶
├─ 可回收物_水杯
├─ 可回收物_沙发
├─ 可回收物_泡沫板
├─ 可回收物_灭火器
├─ 可回收物_灯罩
├─ 可回收物_烟灰缸
├─ 可回收物_热水瓶
├─ 可回收物_燃气灶
├─ 可回收物_燃气瓶
├─ 可回收物_玩具
├─ 可回收物_玻璃制品
├─ 可回收物_玻璃器皿
├─ 可回收物_玻璃壶
├─ 可回收物_玻璃球
├─ 可回收物_瑜伽球
├─ 可回收物_电动剃须刀
├─ 可回收物_电动卷发棒
├─ 可回收物_电子秤
├─ 可回收物_电熨斗
├─ 可回收物_电磁炉
├─ 可回收物_电脑屏幕
├─ 可回收物_电视机
├─ 可回收物_电话
├─ 可回收物_电路板
├─ 可回收物_电风扇
├─ 可回收物_电饭煲
├─ 可回收物_登机牌
├─ 可回收物_盒子
├─ 可回收物_盖子
├─ 可回收物_盘子
├─ 可回收物_碗
├─ 可回收物_磁铁
├─ 可回收物_空气净化器
├─ 可回收物_空气加湿器
├─ 可回收物_笼子
├─ 可回收物_箱子
├─ 可回收物_纸制品
├─ 可回收物_纸牌
├─ 可回收物_罐子
├─ 可回收物_网卡
├─ 可回收物_耳套
├─ 可回收物_耳机
├─ 可回收物_衣架
├─ 可回收物_袋子
├─ 可回收物_袜子
├─ 可回收物_裙子
├─ 可回收物_裤子
├─ 可回收物_计算器
├─ 可回收物_订书机
├─ 可回收物_话筒
├─ 可回收物_豆浆机
├─ 可回收物_路由器
├─ 可回收物_轮胎
├─ 可回收物_过滤网
├─ 可回收物_遥控器
├─ 可回收物_量杯
├─ 可回收物_金属制品
├─ 可回收物_钉子
├─ 可回收物_钥匙
├─ 可回收物_铁丝球
├─ 可回收物_铅球
├─ 可回收物_铝制用品
├─ 可回收物_锅
├─ 可回收物_锅盖
├─ 可回收物_键盘
├─ 可回收物_镊子
├─ 可回收物_闹铃
├─ 可回收物_雨伞
├─ 可回收物_鞋
├─ 可回收物_音响
├─ 可回收物_餐具
├─ 可回收物_餐垫
├─ 可回收物_饰品
├─ 可回收物_鱼缸
├─ 可回收物_鼠标
├─ 有害垃圾_指甲油
├─ 有害垃圾_杀虫剂
├─ 有害垃圾_温度计
├─ 有害垃圾_灯
├─ 有害垃圾_电池
├─ 有害垃圾_电池板
├─ 有害垃圾_纽扣电池
├─ 有害垃圾_胶水
├─ 有害垃圾_药品包装
├─ 有害垃圾_药片
├─ 有害垃圾_药瓶
├─ 有害垃圾_药膏
├─ 有害垃圾_蓄电池
└─ 有害垃圾_血压计

7 关键代码



    import tensorflow as tf
    import linecache
    import cv2
    import numpy as np
    import os
    
    from select_object import pretreatment_image
    
    train_images_path = 'D:/WorkSpace/Python/trash_classify_dataset/dataset/'
    train_labels_path = 'D:/WorkSpace/Python/trash_classify_dataset/train_label.txt'
    test_images_path = 'D:/WorkSpace/Python/trash_classify_dataset/dataset/'
    test_labels_path = 'D:/WorkSpace/Python/trash_classify_dataset/test_label.txt'
    
    classify_num = 50
    train_images_num = 29081
    test_images_num = 3232


    def load_train_dataset(index):  # 从1开始
        if index > train_images_num:
            if index % train_images_num == 0:
                index = train_images_num
            else:
                index %= train_images_num
        line_str = linecache.getline(train_labels_path, index)
        image_name, image_label = line_str.split(' ')
        image = cv2.imread(train_images_path + image_name)
        # cv2.imshow('pic',image)
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        image = cv2.resize(image, (224, 224))
        return image, image_label


    def combine_train_dataset(count, size):
        train_images_load = np.zeros(shape=(size, 224, 224, 3))
        train_labels_load = np.zeros(shape=(size, classify_num))
        for i in range(size):
            train_images_load[i], train_labels_index = load_train_dataset(count + i + 1)
            train_labels_load[i][int(train_labels_index) - 1] = 1.0
        count += size
        return train_images_load, train_labels_load, count


    def load_test_dataset(index):  # 从1开始
        if index > test_images_num:
            if index % test_images_num == 0:
                index = test_images_num
            else:
                index %= test_images_num
        line_str = linecache.getline(test_labels_path, index)
        image_name, image_label = line_str.split(' ')
        image = cv2.imread(test_images_path + image_name)
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        image = cv2.resize(image, (224, 224))
        return image, image_label


    def combine_test_dataset(count, size):
        test_images_load = np.zeros(shape=(size, 224, 224, 3))
        test_labels_load = np.zeros(shape=(size, classify_num))
        for i in range(size):
            test_images_load[i], test_labels_index = load_test_dataset(count + i + 1)
            test_labels_load[i][int(test_labels_index) - 1] = 1.0
        count += size
        return test_images_load, test_labels_load, count


    # # 通过L2正则化防止过拟合
    # def weight_variable_with_loss(shape, stddev, lam):
    #     weight = tf.Variable(tf.truncated_normal(shape, stddev=stddev))
    #     if lam is not None:
    #         weight_loss = tf.multiply(tf.nn.l2_loss(weight), lam, name='weight_loss')
    #         tf.add_to_collection('losses', weight_loss)
    #     return weight
    
    def weight_variable(shape, n, use_l2, lam):
        weight = tf.Variable(tf.truncated_normal(shape, stddev=1 / n))
        # L2正则化
        if use_l2 is True:
            weight_loss = tf.multiply(tf.nn.l2_loss(weight), lam, name='weight_loss')
            tf.add_to_collection('losses', weight_loss)
        return weight


    def bias_variable(shape):
        bias = tf.Variable(tf.constant(0.1, shape=shape))
        return bias


    def conv2d(x, w):
        return tf.nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME')


    def max_pool_2x2(x):
        return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
                              strides=[1, 2, 2, 1], padding='SAME')

    # 输入层
    with tf.name_scope('input_layer'):
        x_input = tf.placeholder(tf.float32, [None, 224, 224, 3])
        y_input = tf.placeholder(tf.float32, [None, classify_num])
        keep_prob = tf.placeholder(tf.float32)
        is_training = tf.placeholder(tf.bool)
        is_use_l2 = tf.placeholder(tf.bool)
        lam = tf.placeholder(tf.float32)
        learning_rate = tf.placeholder(tf.float32)
        # 数据集平均RGB值
        mean = tf.constant([159.780, 139.802, 119.047], dtype=tf.float32, shape=[1, 1, 1, 3])
        x_input = x_input - mean
    
    # 第一个卷积层 size:224
    # 卷积核1[3, 3, 3, 64]
    # 卷积核2[3, 3, 64, 64]
    with tf.name_scope('conv1_layer'):
        w_conv1 = weight_variable([3, 3, 3, 64], 64, use_l2=False, lam=0)
        b_conv1 = bias_variable([64])
        conv_kernel1 = conv2d(x_input, w_conv1)
        bn1 = tf.layers.batch_normalization(conv_kernel1, training=is_training)
        conv1 = tf.nn.relu(tf.nn.bias_add(bn1, b_conv1))
    
        w_conv2 = weight_variable([3, 3, 64, 64], 64, use_l2=False, lam=0)
        b_conv2 = bias_variable([64])
        conv_kernel2 = conv2d(conv1, w_conv2)
        bn2 = tf.layers.batch_normalization(conv_kernel2, training=is_training)
        conv2 = tf.nn.relu(tf.nn.bias_add(bn2, b_conv2))
    
        pool1 = max_pool_2x2(conv2)  # 224*224 -> 112*112
        result1 = pool1
    
    # 第二个卷积层 size:112
    # 卷积核3[3, 3, 64, 128]
    # 卷积核4[3, 3, 128, 128]
    with tf.name_scope('conv2_layer'):
        w_conv3 = weight_variable([3, 3, 64, 128], 128, use_l2=False, lam=0)
        b_conv3 = bias_variable([128])
        conv_kernel3 = conv2d(result1, w_conv3)
        bn3 = tf.layers.batch_normalization(conv_kernel3, training=is_training)
        conv3 = tf.nn.relu(tf.nn.bias_add(bn3, b_conv3))
    
        w_conv4 = weight_variable([3, 3, 128, 128], 128, use_l2=False, lam=0)
        b_conv4 = bias_variable([128])
        conv_kernel4 = conv2d(conv3, w_conv4)
        bn4 = tf.layers.batch_normalization(conv_kernel4, training=is_training)
        conv4 = tf.nn.relu(tf.nn.bias_add(bn4, b_conv4))
    
        pool2 = max_pool_2x2(conv4)  # 112*112 -> 56*56
        result2 = pool2
    
    # 第三个卷积层 size:56
    # 卷积核5[3, 3, 128, 256]
    # 卷积核6[3, 3, 256, 256]
    # 卷积核7[3, 3, 256, 256]
    with tf.name_scope('conv3_layer'):
        w_conv5 = weight_variable([3, 3, 128, 256], 256, use_l2=False, lam=0)
        b_conv5 = bias_variable([256])
        conv_kernel5 = conv2d(result2, w_conv5)
        bn5 = tf.layers.batch_normalization(conv_kernel5, training=is_training)
        conv5 = tf.nn.relu(tf.nn.bias_add(bn5, b_conv5))
    
        w_conv6 = weight_variable([3, 3, 256, 256], 256, use_l2=False, lam=0)
        b_conv6 = bias_variable([256])
        conv_kernel6 = conv2d(conv5, w_conv6)
        bn6 = tf.layers.batch_normalization(conv_kernel6, training=is_training)
        conv6 = tf.nn.relu(tf.nn.bias_add(bn6, b_conv6))
    
        w_conv7 = weight_variable([3, 3, 256, 256], 256, use_l2=False, lam=0)
        b_conv7 = bias_variable([256])
        conv_kernel7 = conv2d(conv6, w_conv7)
        bn7 = tf.layers.batch_normalization(conv_kernel7, training=is_training)
        conv7 = tf.nn.relu(tf.nn.bias_add(bn7, b_conv7))
    
        pool3 = max_pool_2x2(conv7)  # 56*56 -> 28*28
        result3 = pool3
    
    # 第四个卷积层 size:28
    # 卷积核8[3, 3, 256, 512]
    # 卷积核9[3, 3, 512, 512]
    # 卷积核10[3, 3, 512, 512]
    with tf.name_scope('conv4_layer'):
        w_conv8 = weight_variable([3, 3, 256, 512], 512, use_l2=False, lam=0)
        b_conv8 = bias_variable([512])
        conv_kernel8 = conv2d(result3, w_conv8)
        bn8 = tf.layers.batch_normalization(conv_kernel8, training=is_training)
        conv8 = tf.nn.relu(tf.nn.bias_add(bn8, b_conv8))
    
        w_conv9 = weight_variable([3, 3, 512, 512], 512, use_l2=False, lam=0)
        b_conv9 = bias_variable([512])
        conv_kernel9 = conv2d(conv8, w_conv9)
        bn9 = tf.layers.batch_normalization(conv_kernel9, training=is_training)
        conv9 = tf.nn.relu(tf.nn.bias_add(bn9, b_conv9))
    
        w_conv10 = weight_variable([3, 3, 512, 512], 512, use_l2=False, lam=0)
        b_conv10 = bias_variable([512])
        conv_kernel10 = conv2d(conv9, w_conv10)
        bn10 = tf.layers.batch_normalization(conv_kernel10, training=is_training)
        conv10 = tf.nn.relu(tf.nn.bias_add(bn10, b_conv10))
    
        pool4 = max_pool_2x2(conv10)  # 28*28 -> 14*14
        result4 = pool4
    
    # 第五个卷积层 size:14
    # 卷积核11[3, 3, 512, 512]
    # 卷积核12[3, 3, 512, 512]
    # 卷积核13[3, 3, 512, 512]
    with tf.name_scope('conv5_layer'):
        w_conv11 = weight_variable([3, 3, 512, 512], 512, use_l2=False, lam=0)
        b_conv11 = bias_variable([512])
        conv_kernel11 = conv2d(result4, w_conv11)
        bn11 = tf.layers.batch_normalization(conv_kernel11, training=is_training)
        conv11 = tf.nn.relu(tf.nn.bias_add(bn11, b_conv11))
    
        w_conv12 = weight_variable([3, 3, 512, 512], 512, use_l2=False, lam=0)
        b_conv12 = bias_variable([512])
        conv_kernel12 = conv2d(conv11, w_conv12)
        bn12 = tf.layers.batch_normalization(conv_kernel12, training=is_training)
        conv12 = tf.nn.relu(tf.nn.bias_add(bn12, b_conv12))
    
        w_conv13 = weight_variable([3, 3, 512, 512], 512, use_l2=False, lam=0)
        b_conv13 = bias_variable([512])
        conv_kernel13 = conv2d(conv12, w_conv13)
        bn13 = tf.layers.batch_normalization(conv_kernel13, training=is_training)
        conv13 = tf.nn.relu(tf.nn.bias_add(bn13, b_conv13))
    
        pool5 = max_pool_2x2(conv13)  # 14*14 -> 7*7
        result5 = pool5
    
    # 第一个全连接层 size:7
    # 隐藏层节点数 4096
    with tf.name_scope('fc1_layer'):
        w_fc14 = weight_variable([7 * 7 * 512, 4096], 4096, use_l2=is_use_l2, lam=lam)
        b_fc14 = bias_variable([4096])
        result5_flat = tf.reshape(result5, [-1, 7 * 7 * 512])
        fc14 = tf.nn.relu(tf.nn.bias_add(tf.matmul(result5_flat, w_fc14), b_fc14))
        # result6 = fc14
        result6 = tf.nn.dropout(fc14, keep_prob)
    
    # 第二个全连接层
    # 隐藏层节点数 4096
    with tf.name_scope('fc2_layer'):
        w_fc15 = weight_variable([4096, 4096], 4096, use_l2=is_use_l2, lam=lam)
        b_fc15 = bias_variable([4096])
        fc15 = tf.nn.relu(tf.nn.bias_add(tf.matmul(result6, w_fc15), b_fc15))
        # result7 = fc15
        result7 = tf.nn.dropout(fc15, keep_prob)
    
    # 输出层
    with tf.name_scope('output_layer'):
        w_fc16 = weight_variable([4096, classify_num], classify_num, use_l2=is_use_l2, lam=lam)
        b_fc16 = bias_variable([classify_num])
        fc16 = tf.matmul(result7, w_fc16) + b_fc16
        logits = tf.nn.softmax(fc16)
    
    # 损失函数
    with tf.name_scope('loss'):
        cross_entropy = tf.nn.softmax_cross_entropy_with_logits_v2(logits=fc16, labels=y_input)
        cross_entropy_mean = tf.reduce_mean(cross_entropy)
        tf.add_to_collection('losses', cross_entropy_mean)
        loss = tf.add_n(tf.get_collection('losses'))
        tf.summary.scalar('loss', loss)
    
    # 训练函数
    with tf.name_scope('train'):
        update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
        with tf.control_dependencies(update_ops):  # 保证train_op在update_ops执行之后再执行。
            train_step = tf.train.AdamOptimizer(learning_rate).minimize(loss)
    
    # 计算准确率
    with tf.name_scope('accuracy'):
        correct_prediction = tf.equal(tf.argmax(logits, 1), tf.argmax(y_input, 1))
        accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
        tf.summary.scalar('accuracy', accuracy)
    
    # 会话初始化
    # sess = tf.InteractiveSession()
    # tf.global_variables_initializer().run()
    saver = tf.train.Saver()
    save_dir = "classify_modles"
    checkpoint_name = "train.ckpt"
    merged = tf.summary.merge_all()  # 将图形、训练过程等数据合并在一起
    # writer_train = tf.summary.FileWriter('logs/train', sess.graph)  # 将训练日志写入到logs文件夹下
    # writer_test = tf.summary.FileWriter('logs/test', sess.graph)  # 将训练日志写入到logs文件夹下
    
    # 变量初始化
    training_steps = 25000
    display_step = 10
    batch_size = 20
    train_images_count = 0
    test_images_count = 0
    train_avg_accuracy = 0
    test_avg_accuracy = 0
    
    # # 训练
    # print("Training start...")
    #
    # # # 模型恢复
    # # sess = tf.InteractiveSession()
    # # saver.restore(sess, os.path.join(save_dir, checkpoint_name))
    # # print("Model restore success!")
    #
    # for step in range(training_steps):
    #     train_images, train_labels, train_images_count = combine_train_dataset(train_images_count, batch_size)
    #     test_images, test_labels, test_images_count = combine_test_dataset(test_images_count, batch_size)
    #
    #     # 训练
    #     if step < 10000:
    #         train_step.run(
    #             feed_dict={x_input: train_images, y_input: train_labels, keep_prob: 0.8, is_training: True, is_use_l2: True,
    #                        learning_rate: 0.0001, lam: 0.004})
    #     elif step < 20000:
    #         train_step.run(
    #             feed_dict={x_input: train_images, y_input: train_labels, keep_prob: 0.8, is_training: True, is_use_l2: True,
    #                        learning_rate: 0.0001, lam: 0.001})
    #     else:
    #         train_step.run(
    #             feed_dict={x_input: train_images, y_input: train_labels, keep_prob: 0.8, is_training: True, is_use_l2: True,
    #                        learning_rate: 0.00001, lam: 0.001})
    #
    #     # 每训练10步,输出显示训练过程
    #     if step % display_step == 0:
    #         train_accuracy = accuracy.eval(
    #             feed_dict={x_input: train_images, y_input: train_labels, keep_prob: 1.0, is_training: False,
    #                        is_use_l2: False})
    #         train_loss = sess.run(loss, feed_dict={x_input: train_images, y_input: train_labels, keep_prob: 1.0,
    #                                                is_training: False, is_use_l2: False})
    #         train_result = sess.run(tf.argmax(logits, 1),
    #                                 feed_dict={x_input: train_images, keep_prob: 1.0, is_training: False, is_use_l2: False})
    #         train_label = sess.run(tf.argmax(y_input, 1), feed_dict={y_input: train_labels})
    #
    #         test_accuracy = accuracy.eval(
    #             feed_dict={x_input: test_images, y_input: test_labels, keep_prob: 1.0, is_training: False,
    #                        is_use_l2: False})
    #         test_result = sess.run(tf.argmax(logits, 1),
    #                                feed_dict={x_input: test_images, keep_prob: 1.0, is_training: False, is_use_l2: False})
    #         test_label = sess.run(tf.argmax(y_input, 1), feed_dict={y_input: test_labels})
    #
    #         print("Training dataset:")
    #         print(train_result)
    #         print(train_label)
    #         print("Testing dataset:")
    #         print(test_result)
    #         print(test_label)
    #
    #         print("step {}\n training accuracy {}\n loss {}\n testing accuracy {}\n".format(step, train_accuracy, train_loss, test_accuracy))
    #         train_avg_accuracy += train_accuracy
    #         test_avg_accuracy += test_accuracy
    #         result_train = sess.run(merged, feed_dict={x_input: train_images, y_input: train_labels, keep_prob: 1.0,
    #                                                    is_training: False, is_use_l2: False})  # 计算需要写入的日志数据
    #         writer_train.add_summary(result_train, step)  # 将日志数据写入文件
    #
    #         result_test = sess.run(merged, feed_dict={x_input: test_images, y_input: test_labels, keep_prob: 1.0,
    #                                                is_training: False, is_use_l2: False})  # 计算需要写入的日志数据
    #         writer_test.add_summary(result_test, step)  # 将日志数据写入文件
    #
    #     # 每训练100步,显示输出训练平均准确度,保存模型
    #     if step % (display_step * 10) == 0 and step != 0:
    #         print("train_avg_accuracy {}".format(train_avg_accuracy / 10))
    #         train_avg_accuracy = 0
    #         print("test_avg_accuracy {}".format(test_avg_accuracy / 10))
    #         test_avg_accuracy = 0
    #
    #         saver.save(sess, os.path.join(save_dir, checkpoint_name))
    #         print("Model save success!\n")
    #
    # print("Training finish...")
    #
    # # 模型保存
    # saver.save(sess, os.path.join(save_dir, checkpoint_name))
    # print("\nModel save success!")
    #
    # # print("\nTesting start...")
    # # avg_accuracy = 0
    # # for i in range(int(test_images_num / 30) + 1):
    # #     test_images, test_labels, test_images_count = combine_test_dataset(test_images_count, 30)
    # #     test_accuracy = accuracy.eval(
    # #         feed_dict={x_input: test_images, y_input: test_labels, keep_prob: 1.0, is_training: False, is_use_l2: False})
    # #     test_result = sess.run(tf.argmax(logits, 1),
    # #                            feed_dict={x_input: test_images, keep_prob: 1.0, is_training: False, is_use_l2: False})
    # #     test_label = sess.run(tf.argmax(y_input, 1), feed_dict={y_input: test_labels})
    # #     print(test_result)
    # #     print(test_label)
    # #     print("test accuracy {}".format(test_accuracy))
    # #     avg_accuracy += test_accuracy
    # #
    # # print("\ntest_avg_accuracy {}".format(avg_accuracy / (int(test_images_num / 30) + 1)))
    #
    # sess.close()

    # 识别
    # 模型恢复
    sess = tf.InteractiveSession()
    saver.restore(sess, os.path.join(save_dir, checkpoint_name))
    print("Model restore success!")


    def predict_img(img_path):
        img = cv2.imread(img_path)
        image = np.reshape(img, [1, 224, 224, 3])
        classify_result = sess.run(tf.argmax(logits, 1),
                                   feed_dict={x_input: image, keep_prob: 1.0, is_training: False, is_use_l2: False})
        probability = sess.run(logits, feed_dict={x_input: image, keep_prob: 1.0, is_training: False,
                                                  is_use_l2: False}).flatten().tolist()[
            classify_result[0]]
        return classify_result[0], probability


    def trash_classify(img_path, img_name, upload_path):
        img_name = img_name.rsplit('.', 1)[0]
        # print(img_name)
        pretrian_img_path, selected_img_path = pretreatment_image(img_path, img_name, upload_path)
        predict_result, predict_probability = predict_img(pretrian_img_path)
        return predict_result, predict_probability



8 最后

🧿 更多资料, 项目分享:

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

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

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

相关文章

计算机网络-网络层总结

目录 网络层提供的两种服务 1、分组转发和路由选择 2、网络层提供的两种服务 网际协议IP 1、虚拟互联网 2、网际协议IP 3、异构网络互连 4、IPv4地址 概述 4.1分类编址的IPv4地址 4.2划分子网的IPv4地址 4.3无分类编址的IPv4地址 4.4IPv4地址的应用规划 4.5MAC地址…

使用 Spring Data Redis 访问 Redis 的 Spring Boot 应用

使用 Spring Data Redis 访问 Redis 的 Spring Boot 应用 Redis是一个高性能的内存键值存储数据库&#xff0c;常用于缓存、会话管理和消息队列等场景。Spring Boot通过Spring Data Redis提供了方便的方式来与Redis进行交互。在本文中&#xff0c;我们将详细介绍如何使用Sprin…

nodejs+vue 经典建筑网站elementui

第1章 项目概述 1 1.1 问题描述 1 1.2 项目目标 1 1.3 项目适用范围 2 1.4 项目应遵守的规范与标准 2 1.5 涉众 2 具有功能强大、支持跨平台、运行速度快、安全性高、成本低等优点。而对于后者我们使用 来完成它&#xff0c;使其网页功能完备&#xff0c;界面友好、易开发、易…

直方图投影法判断裂缝走势(裂缝类型)

裂缝类型 裂缝类型有很多种&#xff0c;这里我们仅仅判断线性裂缝与网状裂缝&#xff0c;线性裂缝按照其走势有可分为横向裂缝、纵向裂缝和斜向裂缝。 我觉得大家应当有这样的意识&#xff0c;面对网状裂缝&#xff0c;它的二维参数是否有意义&#xff1f;答案是没有&#xf…

宝塔Node部署nuxt3

宝塔Node部署nuxt3 1、首先本地执行打包 yarn build2、然后把目录中的这个文件压缩成zip 3、在宝塔文件处添加一个网站的文件目录&#xff0c;并把文件解压到里面 4、点击左侧的网站&#xff0c;然后选择node项目&#xff0c;选择node版本安装 5、安装完后&#xff0c;点击新…

【C语言】快速排序

文章目录 一、hoare版本二、挖坑法三、前后指针法四、非递归快排五、快速排序优化1、三数取中选key值2、小区间优化 六、代码测试 一、hoare版本 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法&#xff0c;其基本思想为&#xff1a;任取待排序元素序列中的某元素…

云中的网络Qos

在 Linux 下&#xff0c;可以通过 TC 控制网络的 QoS&#xff0c;主要就是通过队列的方式。 第一大类称为无类别排队规则&#xff08;Classless Queuing Disciplines&#xff09;。pfifo_fast 分为三个先入先出的队列&#xff0c;称为三个 Band。根据网络包里面 TOS&#xff0…

VScode调试复杂C/C++项目

以前都是用的VScode调试c/cpp的单个文件的编译和执行, 但是一遇到大型项目一般就用gdb了, gdb的调试效率和VScode差距还是比较大的, 但最近发现VScode其实也能调试复杂的cpp项目, 所以记录一下. 首先明确一下几点: 首先cpp文件需要经过编译, 生成可执行文件, 然后通过运行/调…

百度搜索逐步恢复优质网站权限

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 从9月25日开始&#xff0c;有越来越多的站长和卢松松反馈&#xff0c;说他们的站可以正常入驻百度搜索资源平台了。我也试了试卢松松博客&#xff0c;果然&#xff0c;可以正常提交了。还是以前的…

iTOP-3568开发板Ubuntu下安装ADB工具

在虚拟机 Ubuntu 使用以下命令安装 ADB&#xff0c;如下图所示&#xff1a; sudo apt install adb 接下来进行测试&#xff0c;执行如下命令&#xff0c;确认 adb 安装是否成功。 adb version 如上图所示&#xff0c;执行命令能成功获取到 adb 版本信息&#xff0c;说明 adb …

防火墙网络接口下面多个外网地址,只有第一地址可以访问通其他不通

环境&#xff1a; 主备防火墙 8.0.75 AF-2000-FH2130B-SC 问题描述&#xff1a; 两台防火墙双击热备&#xff0c;高可用防火墙虚拟网络接口Eth4下面有多个外网地址&#xff0c;只有第一地址可以访问通其他不通 解决方案&#xff1a; 1.检查防火墙路由设置&#xff08;未解决…

3D WEB轻量化引擎HOOPS助力3D测量应用蓬勃发展:效率、精度显著提升

在3D开发工具领域&#xff0c;Tech Soft 3D打造的HOOPS SDK已经崭露头角&#xff0c;成为了全球领先的3D领域开发工具提供商。HOOPS SDK包括四种不同的3D软件开发工具&#xff0c;已成为行业的翘楚。 其中&#xff0c;HOOPS Exchange以其CAD数据转换的能力脱颖而出&#xff0c…

5.wifi开发【智能家居:上】,开发准备:智能开关灯,智能采集温湿,智能调彩灯

一。wifi智能家居项目开发 【开发准备1】&#xff1a;继电器控制开发 1.智能开关 器件准备&#xff1a;wifi&#xff08;esp8266&#xff0c;使用CP2102&#xff09;继电器 结果&#xff1a; 2.继电器工作原理 &#xff08;1&#xff09;继电器是一种自动电气开关 &#xff…

Multisim14.0仿真(二十六)基于LM555定时器的施密特触发器

一、仿真原理图&#xff1a; 二、仿真效果图&#xff1a;

01-工具篇-windows与linux文件共享

一般来说绝大部分PC上装的系统均是windows&#xff0c;为了开发linux程序&#xff0c;会在PC上安装一个Vmware的虚拟机&#xff0c;在虚拟机上安装ubuntu18.04&#xff0c;由于windows上的代码查看软件、浏览器&#xff0c;通信软件更全&#xff0c;我们想只用ubuntu进行编译&a…

【VUE复习·5】插值语法(使用 计算属性 的插值语法)

总览 1.计算属性 2.使用 methods 的 插值语法 3.使用 computed 的 插值语法 一、计算属性 1.解释 首先&#xff0c;如果我们要写一个插值语法&#xff0c;而 {{ }} 内的内容&#xff0c;是一个经过计算的值&#xff0c;那么按照原本 JS 的写法&#xff0c;应该是这样的&…

目标检测YOLO实战应用案例100讲-区域卷积网络在阴影环境目标检测上的研究与应用(下)

目录 5.2 阴影检测模块与街景检测模块实验设置 5.2.1 实验环境与工具 5.2.3 损失函数 5.2.4 实验具体流程 5.3 实验评估与对比 5.3.1 两类实验的评估标准 5.3.2 两类实验结果对比 阴影环境下街景目标检测系统的实现 6.1 系统概述 6.2 系统软硬件环境 6.3 功能模块设计 6.4 系统…

嵌入式Linux应用开发-IMX6ULL板硬件资源及开发环境

嵌入式Linux应用开发-IMX6ULL板硬件资源及开发环境 第一章 硬件资源1.1 板上资源1.2 板外模块 第二章 准备开发环境2.1 IMX6ULL 开发板接线与启动1) 连接串口线和电源线2) 安装 USB 串口驱动3) 选择启动方式4) 设置串口工具&#xff0c;启动开发板 第一章 硬件资源 iMX6ULL板是…

vlc将本地文件推流成ts实时流

推流 打开vlc &#xff0c;打开 媒体----打开网络串流 选择文件选项卡&#xff0c;打开本地文件 点击添加&#xff0c;选择本地的mp3文件 选择串流 点击下拉框&#xff0c;选择udp&#xff0c;点击右边的【添加】按钮 输入媒体流输出地址&#xff0c;点击【下一个】 选择正确的…

《C++ Primer》第4章 表达式(一)

参考资料&#xff1a; 《C Primer》第5版《C Primer 习题集》第5版 4.1 基础&#xff08;P120&#xff09; 表达式由一个或多个运算对象组成&#xff0c;对表达式求值将得到一个结果。字面量和变量是最简单的表达式。 4.1.1 基本概念&#xff08;P120&#xff09; C 定义了…