深度学习小工程练习之垃圾分类详解


Posted in Python onApril 14, 2021

介绍

这是一个基于深度学习的垃圾分类小工程,用深度残差网络构建

软件架构

  1. 使用深度残差网络resnet50作为基石,在后续添加需要的层以适应不同的分类任务
  2. 模型的训练需要用生成器将数据集循环写入内存,同时图像增强以泛化模型
  3. 使用不包含网络输出部分的resnet50权重文件进行迁移学习,只训练我们在5个stage后增加的层

安装教程

  1. 需要的第三方库主要有tensorflow1.x,keras,opencv,Pillow,scikit-learn,numpy
  2. 安装方式很简单,打开terminal,例如:pip install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple
  3. 数据集与权重文件比较大,所以没有上传
  4. 如果环境配置方面有问题或者需要数据集与模型权重文件,可以在评论区说明您的问题,我将远程帮助您

使用说明

  1. 文件夹theory记录了我在本次深度学习中收获的笔记,与模型训练的控制台打印信息
  2. 迁移学习需要的初始权重与模型定义文件resnet50.py放在model
  3. 下训练运行trainNet.py,训练结束会创建models文件夹,并将结果权重garclass.h5写入该文件夹
  4. datagen文件夹下的genit.py用于进行图像预处理以及数据生成器接口
  5. 使用训练好的模型进行垃圾分类,运行Demo.py

结果演示

深度学习小工程练习之垃圾分类详解

cans易拉罐

深度学习小工程练习之垃圾分类详解

代码解释

在实际的模型中,我们只使用了resnet50的5个stage,后面的输出部分需要我们自己定制,网络的结构图如下:

深度学习小工程练习之垃圾分类详解

stage5后我们的定制网络如下:

"""定制resnet后面的层"""
def custom(input_size,num_classes,pretrain):
    # 引入初始化resnet50模型
    base_model = ResNet50(weights=pretrain,
                          include_top=False,
                          pooling=None,
                          input_shape=(input_size,input_size, 3),
                          classes=num_classes)
    #由于有预权重,前部分冻结,后面进行迁移学习
    for layer in base_model.layers:
        layer.trainable = False
    #添加后面的层
    x = base_model.output
    x = layers.GlobalAveragePooling2D(name='avg_pool')(x)
    x = layers.Dropout(0.5,name='dropout1')(x)
    #regularizers正则化层,正则化器允许在优化过程中对层的参数或层的激活情况进行惩罚
    #对损失函数进行最小化的同时,也需要让对参数添加限制,这个限制也就是正则化惩罚项,使用l2范数
    x = layers.Dense(512,activation='relu',kernel_regularizer= regularizers.l2(0.0001),name='fc2')(x)
    x = layers.BatchNormalization(name='bn_fc_01')(x)
    x = layers.Dropout(0.5,name='dropout2')(x)
    #40个分类
    x = layers.Dense(num_classes,activation='softmax')(x)
    model = Model(inputs=base_model.input,outputs=x)
    #模型编译
    model.compile(optimizer="adam",loss = 'categorical_crossentropy',metrics=['accuracy'])
    return model

网络的训练是迁移学习过程,使用已有的初始resnet50权重(5个stage已经训练过,卷积层已经能够提取特征),我们只训练后面的全连接层部分,4个epoch后再对较后面的层进行训练微调一下,获得更高准确率,训练过程如下:

class Net():
    def __init__(self,img_size,gar_num,data_dir,batch_size,pretrain):
        self.img_size=img_size
        self.gar_num=gar_num
        self.data_dir=data_dir
        self.batch_size=batch_size
        self.pretrain=pretrain
    def build_train(self):
        """迁移学习"""
        model = resnet.custom(self.img_size, self.gar_num, self.pretrain)
        model.summary()
        train_sequence, validation_sequence = genit.gendata(self.data_dir, self.batch_size, self.gar_num, self.img_size)
        epochs=4
        model.fit_generator(train_sequence,steps_per_epoch=len(train_sequence),epochs=epochs,verbose=1,validation_data=validation_sequence,
                                     max_queue_size=10,shuffle=True)
        #微调,在实际工程中,激活函数也被算进层里,所以总共181层,微调是为了重新训练部分卷积层,同时训练最后的全连接层
        layers=149
        learning_rate=1e-4
        for layer in model.layers[:layers]:
            layer.trainable = False
        for layer in model.layers[layers:]:
            layer.trainable = True
        Adam =adam(lr=learning_rate, decay=0.0005)
        model.compile(optimizer=Adam, loss='categorical_crossentropy', metrics=['accuracy'])
        model.fit_generator(train_sequence,steps_per_epoch=len(train_sequence),epochs=epochs * 2,verbose=1,
            callbacks=[
                callbacks.ModelCheckpoint('./models/garclass.h5',monitor='val_loss', save_best_only=True, mode='min'),
                callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.1,patience=10, mode='min'),
                callbacks.EarlyStopping(monitor='val_loss', patience=10),],
            validation_data=validation_sequence,max_queue_size=10,shuffle=True)
        print('finish train,look for garclass.h5')

训练结果如下:

"""
    loss: 0.7949 - acc: 0.9494 - val_loss: 0.9900 - val_acc: 0.8797
    训练用了9小时左右
    """

如果使用更好的显卡,可以更快完成训练

最后

希望大家可以体验到深度学习带来的收获,能和大家学习很开心,更多关于深度学习的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python缩进区别分析
Feb 15 Python
简单介绍Python中的struct模块
Apr 28 Python
windows下ipython的安装与使用详解
Oct 20 Python
Python读取MRI并显示为灰度图像实例代码
Jan 03 Python
python实现求解列表中元素的排列和组合问题
Mar 15 Python
利用python实现微信头像加红色数字功能
Mar 26 Python
python求最大值最小值方法总结
Jun 25 Python
python pygame实现挡板弹球游戏
Nov 25 Python
python实现矩阵和array数组之间的转换
Nov 29 Python
Python实现不规则图形填充的思路
Feb 02 Python
Python实现代码块儿折叠
Apr 15 Python
超级实用的8个Python列表技巧
Aug 24 Python
python3美化表格数据输出结果的实现代码
Apr 14 #Python
Python生成九宫格图片的示例代码
用Python写一个简易版弹球游戏
python urllib库的使用详解
Apr 13 #Python
用Python将库打包发布到pypi
python xlwt模块的使用解析
python 爬取豆瓣网页的示例
You might like
不用数据库的多用户文件自由上传投票系统(1)
2006/10/09 PHP
解析php中static,const与define的使用区别
2013/06/18 PHP
laravel 实现根据字段不同值做不同查询
2019/10/23 PHP
javascript的事件描述
2006/09/08 Javascript
javascript 拷贝节点cloneNode()使用介绍
2014/04/03 Javascript
JQuery中serialize()、serializeArray()和param()方法示例介绍
2014/07/31 Javascript
JavaScript操作select元素和option的实例代码
2016/01/29 Javascript
jQuery学习心得总结(必看篇)
2016/06/10 Javascript
基于SpringMVC+Bootstrap+DataTables实现表格服务端分页、模糊查询
2016/10/30 Javascript
判断横屏竖屏(三种)
2017/02/13 Javascript
详解angular中通过$location获取路径(参数)的写法
2017/03/21 Javascript
纯js实现画一棵树的示例
2017/09/05 Javascript
vue router demo详解
2017/10/13 Javascript
nodejs超出最大的调用栈错误问题
2017/12/27 NodeJs
react-navigation之动态修改title的内容
2018/09/26 Javascript
Vue 动态组件与 v-once 指令的实现
2019/02/12 Javascript
微信小程序项目总结之记账小程序功能的实现(包括后端)
2019/08/20 Javascript
VUE : vue-cli中去掉路由中的井号#操作
2020/09/04 Javascript
vue使用exif获取图片旋转,压缩的示例代码
2020/12/11 Vue.js
Vue实现简易购物车页面
2020/12/30 Vue.js
[03:46]显微镜下的DOTA2第七期——满血与残血
2014/06/20 DOTA
Python中的pprint折腾记
2015/01/21 Python
Python实现字符串反转的常用方法分析【4种方法】
2017/09/30 Python
pandas.DataFrame的pivot()和unstack()实现行转列
2019/07/06 Python
python如何将两个txt文件内容合并
2019/10/18 Python
python 基于dlib库的人脸检测的实现
2019/11/08 Python
浅谈keras使用预训练模型vgg16分类,损失和准确度不变
2020/07/02 Python
用python监控服务器的cpu,磁盘空间,内存,超过邮件报警
2021/01/29 Python
微信浏览器左上角返回按钮拦截功能
2017/11/21 HTML / CSS
HTML5 解析规则分析
2009/08/14 HTML / CSS
英国性能汽车零件和发动机配件在线:Maxpeedingrods
2019/11/05 全球购物
建筑毕业生自我鉴定
2013/10/18 职场文书
2014年六一儿童节演讲稿
2014/05/23 职场文书
2014年城管个人工作总结
2014/12/08 职场文书
贫困生助学金感谢信
2015/01/21 职场文书
2016年小学教师政治学习心得体会
2016/01/23 职场文书