Py学习  »  机器学习算法

使用Keras和深度学习进行火灾和烟雾检测(一)

Python程序员 • 4 年前 • 692 次点击  

先上源代码:

https://www.pyimagesearch.com/2019/11/18/fire-and-smoke-detection-with-keras-and-deep-learning/#post_downloads


在本教程中,您将学习如何使用Computer Vision,OpenCV和Keras深度学习库来检测火灾和烟雾。


今天的教程的灵感来自我上周从PyImageSearch读者Daniel收到的一封电子邮件。


Daniel写到:

    嗨,阿德里安,不知道您是否看过这个消息,但是过去几周来,我的家乡加利福尼亚州遭到了野火的肆虐。

    我的家人住在洛杉矶地区,离盖蒂大火不远。很难不担心我们的房屋和我们的安全。

    这是一个可怕的情况,这让我开始思考:

    您认为计算机视觉可用于检测野火吗?那在人们家中起火怎么办?

    如果您可以撰写有关该主题的教程,我将不胜感激。我很乐意从中学习,并尽我所能帮助他人。

    

简洁地回答,是的,计算机视觉和深度学习可用于检测野火:

    配备摄像机的IoT / Edge设备可以策略性地部署在整个山坡,山脊和高海拔地区,自动监视烟雾或火灾的迹象。

    无人机和四轴飞行器可以在容易发生野火的区域上空飞行,有策略地扫描烟雾。

    卫星可用于拍摄大面积区域的照片,而计算机视觉和深度学习算法可处理这些图像,以寻找冒烟的迹象。

    

    这对预防野火很有效--但是,如果您想监视自己的房屋是否冒烟或起火怎么办?

    答案是使用传感器以帮助火灾/烟雾检测:

    现有的烟雾探测器利用光电传感器和光源来检测光源是否被散射(表明存在烟雾)。

    然后,您可以在房屋周围分布温度传感器以监视每个房间的温度。

    摄像机也可以放置在可能会着火的区域(厨房,车库等)。

    每个单独的传感器都可以用来触发警报,也可以将传感器信息中继到中央集线器,该集线器汇总并分析传感器数据,计算出发生火灾的可能性。

    不幸的是,这说起来容易做起来难。


尽管全世界有数百位计算机视觉/深度学习从业人员积极从事火灾和烟雾检测工作(包括PyImageSearch Gurus成员David Bonn),但这仍然是一个悬而未决的问题。


就是说,今天,我将帮助您开始烟雾和火灾检测-到本教程结束时,您将拥有一个能够检测图像中火灾的深度学习模型(我甚至提供了经过预先训练的模型 能让您立即运行)。


要学习如何使用计算机视觉,深度学习和Keras创建自己的火灾和烟雾探测器,请继续阅读!


使用Keras和深度学习进行火灾和烟雾检测


图1:野火可能很快变得无法控制,并危及世界上许多地方的生命。在本文中,我们将学习使用Keras和深度学习进行火灾和烟雾检测。


在本教程的第一部分中,我们将讨论用于火灾和烟雾检测的两个数据集。

        

我们将检查项目的目录结构,然后实现FireDetectionNet,这是我们将用来检测图像/视频中的火灾和烟雾的CNN体系结构。

        

接下来,我们将训练我们的火灾探测模型并分析分类的准确性和结果。

        

我们将通过讨论该方法的一些局限和缺点来总结本教程,包括如何改进和扩展该方法。


我们的火灾和烟雾数据集

图2:今天的火灾探测数据集由Gautam Kumar精心准备,并由David Bonn(均为PyImageSearch读者)整理。我们将数据集与Keras和深度学习一起使用,以创建火灾/烟雾探测器。


我们将用于火灾和烟雾示例的数据集由PyImageSearch读者Gautam Kumar精心策划。

        

Guatam通过在Google图片中搜索与“火”,“烟”等词语相关的查询,总共收集了1,315张图片。

        

但是,原始数据集尚未清除与火和烟无关的无关图像(例如,发生火灾前著名建筑物的示例)。

        

PyImageSearch的资深读者David Bonn花了一些时间来手动浏览火/烟图像,并识别不应该包含的图像。

        

注意:我获取了由David标识的无关图像的列表,然后创建了一个Shell脚本以将其从数据集中删除。可以在本教程的“下载”部分中找到Shell脚本。


8场景数据集

图3:我们将Gautam的fire数据集与8场景自然图像数据集结合起来,以便我们可以使用Keras和深度学习将Fire与非fire进行分类。


我们将用于非开火示例的数据集称为8场景,因为它包含属于8个自然场景类别(全部没有火)的2688个图像示例:

  • 海岸


  • 森林

  • 野外


  • 内城

  • 高的建筑

  • 高速公路

                                                

该数据集最初由Oliva和Torralba在2001年的论文《场景的建模:空间包络的整体表示》中提供。

        

8场景数据集是对我们的火/烟数据集的自然补充,因为它描绘了自然场景,它们看起来应该没有火或烟。

        

尽管此数据集有8个唯一的类,但将其与Gautam的Fire数据集结合使用时,我们会将其视为单个“火无关”类。

        

项目结构

图4:使用Keras / TensorFlow框架进行深度学习的火灾和烟雾检测教程的项目结构。


继续阅读并通过博客文章的“下载”部分,从源代码和经过预先训练的模型中获取今天的.zip文件。

        

之后可以将其解压缩到您的计算机上,并且您的项目将如图4所示。有一个例外:数据集.zip(白色箭头)都不会出现。我们将在下一部分中下载,提取和修剪数据集。

        

我们的output /目录包含:

    我们的序列化火灾探测模型。今天,我们将通过Keras和深度学习来训练模型。

    在训练之前,将生成学习率查找器图并进行检查以获取最佳学习率。

    训练过程完成后将生成训练历史图。

    examples /子目录将由predict_fire.py填充示例图像,并对其进行注释,以供演示和验证之用。

    我们的pyimagesearch模块包含:

       config.py:我们的配置。

       FireDetectionNet:我们的Keras卷积神经网络类,专门用于检测火灾和烟雾。

       LearningRateFinder:Keras类,用于协助寻找深度学习训练的最佳学习率的过程。

                

   项目的根目录包含三个脚本:

       prune.sh:一个简单的bash脚本,可从Gautam的fire数据集中删除不相关的图像。

       train.py:我们的Keras深度学习培训脚本。该脚本有两种操作模式:(1)学习率查找器模式和(2)训练模式。

       predict_fire.py:一个快速而粗略的脚本,它从我们的数据集中采样图像,生成带注释的Fire / Non-fire图像进行验证。

              

在下一节中,我们继续准备我们的火灾/非火灾数据集。


准备我们的火灾和非火灾合并数据集


准备我们的火灾和非火灾数据集涉及四个步骤:

    步骤1:确保您按照上一节中的说明从“下载”部分中获取并解压缩了今天的文件。

    步骤2:下载火灾/烟雾数据集并将其提取到项目中。

    步骤#3:修剪火/烟数据集以获取无关的无关文件。

    步骤#4:下载8场景数据集并将其提取到项目中。

    步骤2-4的结果将是一个包含两个类的数据集:火、无火


合并数据集是我经常使用的策略。这样可以节省宝贵的时间,并且通常可以得到一个很好的模型。


让我们开始将合并后的数据集放在一起。


步骤2:下载火灾/烟雾数据集并将其提取到项目中。


使用此链接下载火/烟数据集。将.zip存储在上一部分中提取的keras-fire-detection /项目目录中。


下载后,解压缩数据集:        


步骤3:修剪数据集以获取无关的无关文件。


执行prune.sh脚本从fire数据集中删除无火的无关文件:       

现在我们有了获得数据,我们还需要无火的数据来解决二元问题。

                

步骤#4:下载8场景数据集并将其提取到项目中。


使用此链接下载8场景数据集。将.zip存储在Fire数据集旁边的keras-fire-detection /项目目录中。

                       

下载后,导航到项目文件夹并解压数据集:          


审查项目+数据集结构


现在,该再次检查目录结构了。您的应与我的相同:               

确保修剪您的数据集(即Fire /目录应完全包含1,315个条目,而不是之前的1,405个条目)。


我们的配置文件


这个项目涵盖了多个需要执行的Python文件,因此让我们将所有重要的变量储存在一个config.py文件中。


立即打开config.py并插入以下代码              

我们将使用os模块来组合路径(第2行)。

                        

第5-7行包含指向我们的(1)火灾图像和(2)非火灾图像的路径。

                        

第10行是我们两个类名称的列表。

                        

让我们设置一些训练参数:                   

第13和14行定义了我们的训练和测试数据集分割的大小。

                        

第17-19行包含三个超参数-初始学习率,批处理大小和要训练的周期数。


在这里,我们将定义一些路径:                 


第22-27行包括以下路径:

    我们尚未训练的序列化火灾探测模型。

    学习率查找器图,我们将对其进行分析以设置初始学习率。

    训练准确性/损失历史记录图。

    在结束的地方,我们将定义用于预测抽查的设置:                 


我们的预测脚本将使用我们的模型对图像进行采样和注释。

                    

第32和33行包括输出目录的路径,我们将在其中存储输出分类结果和要采样的图像数。

                    

实现我们的火灾探测卷积神经网络

                        

图5:FireDetectionNet是使用Keras深度学习框架构建的深度学习火/烟分类网络。


在本部分中,我们将实现FireDetectionNet,这是一种用于检测图像中烟雾和火灾的卷积神经网络。


该网络利用深度可分离卷积而不是标准卷积作为深度可分离卷积:

  • 效率更高,因为Edge / IoT设备将具有有限的CPU和功耗。

  • 需要更少的内存,同样,Edge / IoT设备的RAM有限。

  • 由于我们的CPU能力有限,因此需要较少的计算。

  • 在某些情况下,其性能可能比标准卷积更好,这可能会导致更好的火灾/烟雾探测器。

            

现在就开始实现FireDetectioNet吧-立即打开firedetectionnet.py文件并插入以下代码:  

我们的TensorFlow 2.0 Keras入口为2-9行。我们将使用Keras的顺序API构建我们的火灾检测CNN。

                        

第11行定义了我们的FireDetectionNet类。我们首先在第13行定义构建方法。

                        

构建方法接受的参数包括图像的尺寸(width,height,depth)以及我们将训练模型进行识别的类数(即此参数影响softmax分类器的形状)。

                        

然后,我们初始化model和inputShape(第16-18行)。


在这里,我们将定义第一组CONV => RELU => POOL层:     

这些层使用较大的内核大小,以(1)更快地减小输入体积的空间尺寸,以及


(2)检测包含火的较大颜色斑点。

然后,我们将定义更多CONV => RELU => POOL图层集:

第34-40行允许我们的模型通过在应用POOL之前叠加两组CONV => RELU来学习更丰富的功能。

                            

从这里,我们将创建我们完全连接的网络:                         

第43-53行添加了两组FC => RELU层。

第56和57行在第60行返回模型之前附加我们的Softmax分类器。


创建我们的训练脚本


我们的训练脚本将负责:

  • 从磁盘加载Fire和Non-fire组合数据集。

  • 实例化我们的FireDetectionNet架构。

  • 通过使用LearningRateFinder类找到我们的最佳学习率。

  • 以最佳的学习速度在整个过程中训练我们的网络。

让我们开始吧!


在目录结构中打开train.py文件,并插入以下代码:               

1-19行处理我们的导入:

  • matplotlib:用于使用Python生成图。第3行设置了后台,因此我们可以将绘图保存为图像文件。

  • tensorflow.keras:我们的TensorFlow 2.0导入包括数据增强,随机梯度下降优化器和一键式标签编码器。

  • sklearn:两个导入,用于数据集拆分和分类报告。

  • LearningRateFinder:我们将在训练之前使用该类来查找最佳学习率。当我们在此模式下操作脚本时,它将为我们生成一个图,以(1)人工检查和(2)将最佳学习率插入到我们的配置文件中。

  • FireDetectionNet:我们在上一节中构建的火/烟卷积神经网络(CNN)。

  • config:我们用于此训练脚本的设置的配置文件(还包含我们的预测脚本的设置)。

  • path:包含来自我的imutils包的函数,用于在目录树中列出图像。

  • argparse:用于解析命令行参数标志。

  • cv2:OpenCV用于加载和预处理图像。

                

现在,我们已经导入了程序包,让我们定义一个可重用的函数来加载数据集:       

我们的load_dataset帮助函数可帮助加载,预处理和准备Fire和Non-fire数据集。

                                

第21行定义了接受数据集路径的函数。

第24行抓取数据集中的所有图像路径。

第28-35行在imagePaths上循环。图像被加载,调整为128×128尺寸,并添加到数据列表中。

第38行以NumPy数组格式返回数据。

 

现在,我们将分析一个命令行参数:

    --lr-find标志设置脚本的模式。如果该标记设置为1,那么我们将进入学习率查找器模式,并生成一个学习率图供我们检查。否则,我们的脚本将在训练模式下运行并为整个过程训练网络(即当--lr-find标志不存在时)。


让我们继续并立即加载数据:                                

第48和49行会加载Fire和Non-fire图像并调整其大小。

第52和53行为这两个类构造标签(1表示“火”,0表示“非火”)。

随后,我们通过第57和58行将数据和标签堆叠到单个NumPy数组中(即合并数据集)。

第59行将像素强度缩放到[0,1]范围。

                                

我们还有另外三个步骤来准备数据:                    

首先,我们对标签执行单次编码(第63行)。

                                

然后,我们在数据集中考虑了偏斜(第64和65行)。为此,我们计算classWeight以在梯度更新期间对非火力图像加权比非火力图像更多(因为火力图像比非火力图像多2倍)。

 

第68行和第69行根据我们的配置构建了训练和测试单元(在我的配置中,我将单元设置为75%训练/ 25%测试)。


接下来,我们将初始化数据扩充并编译我们的FireDetectionNet模型:

74-79行实例化了我们的数据增强对象。


然后,我们构建并编译FireDetectionNet模型(第83-88行)。请注意,我们在初始化SGD优化器时会设置初始学习速率和衰减。


让我们来处理学习率查找器模式:                     


第92行检查我们是否应该尝试找到最佳学习率。假设如此,我们:

初始化LearningRateFinder(第96行)。

开始以1e-10的学习率进行训练,然后成倍增加直到我们达到1e + 1(第97-103行)。

绘制损失与学习率的关系曲线,并保存结果图(107和108行)。

在向用户打印了几条消息后(第115行),正常退出脚本。                            执行此代码后,我们现在需要:

  • 步骤1:手动检查生成的学习率图。

  • 步骤2:使用INIT_LR更新config.py(即我们通过分析图确定的最佳学习率)。

  • 步骤3:在完整的数据集上训练网络。

                    

假设我们已经完成了步骤1和步骤2,现在让我们处理步骤3,该步骤已在配置中确定并更新了我们的初始学习率。在这种情况下,是时候在脚本中处理训练模式了:

119-125行使用数据扩充和偏斜的数据集类别加权来训练我们的火灾探测模型。请务必查看我的.fit_generator教程。


最后,我们将评估模型,将其序列化到磁盘上,并绘制训练历史记录:

第129-131行对测试数据进行预测,并在我们的终端上打印分类报告。

第135行将模型序列化并将其保存到磁盘。我们将在预测脚本中调用该模型。

线138-149会在训练期间生成准确性/损耗曲线的历史图。我们将检查该图是否过度拟合或拟合不足。

                           

用Keras训练火灾探测模型


训练我们的火灾探测模型分为三个步骤:

步骤#1:使用--lr-find命令行参数运行train.py脚本,以找到我们的最佳学习率。

步骤#2:更新配置文件(config.py)的第17行,将INIT_LR值设置为最佳学习率。

 步骤#3:再次执行train.py脚本,但是这次让它针对整个时期进行训练。


首先,使用本教程的“下载”部分将源代码下载到本教程。


英文原文:https://www.pyimagesearch.com/2019/11/18/fire-and-smoke-detection-with-keras-and-deep-learning/ 
译者:QL

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/53109
 
692 次点击