毕业设计——基于卷积神经网络的高速公路团雾智能识别系统设计与实现(数据集+源码+可视化+综述)

如需获取完整源码请联系博主

基于卷积神经网络的高速公路团雾智能识别系统设计与实现

一、引言

随着智能交通系统(ITS)的快速发展,高速公路的安全和效率问题越来越受到人们的关注。团雾作为一种常见的气象现象,具有突发性、局地性和消散迅速的特点,对高速公路的行车安全构成严重威胁。因此,开发一种能够准确、快速地识别高速公路团雾的智能系统具有重要的现实意义和应用价值。本文旨在综述基于卷积神经网络(CNN)的高速公路团雾智能识别系统的设计与实现。

二、卷积神经网络概述

卷积神经网络是一种深度学习模型,其灵感来源于生物神经网络的结构。它通过模拟人脑对图像信息的处理方式,实现对图像特征的自动提取和分类。卷积神经网络具有权值共享、局部连接和降采样等特点,使其在处理图像数据方面具有很高的效率和准确性。然而,卷积神经网络也存在一些不足,如训练时间较长、需要大量的数据等。

三、高速公路团雾智能识别系统设计

本文设计的高速公路团雾智能识别系统主要包括图像采集、预处理、特征提取和分类识别四个部分。

图像采集:通过安装在高速公路沿线的摄像头实时采集道路图像,确保图像数据的实时性和准确性。
预处理:对采集到的图像进行去噪、增强等预处理操作,以提高图像质量,降低后续处理的难度。
特征提取:利用卷积神经网络对预处理后的图像进行特征提取。通过设计合适的网络结构,如增加卷积层、池化层等,实现对图像中团雾特征的自动学习和提取。
分类识别:将提取到的特征输入到分类器中进行识别。可以采用多种分类算法,如支持向量机(SVM)、随机森林等,实现对团雾的准确识别。

四、系统实现与实验

在系统实现过程中,首先构建了一个包含大量团雾和非团雾图像的数据集,用于训练和测试卷积神经网络模型。通过调整网络结构、优化算法等参数,不断提高模型的识别准确率和泛化能力。在实验阶段,将训练好的模型应用于实际道路图像中,测试其在不同天气、光照等条件下的识别性能。实验结果表明,该系统能够实现对高速公路团雾的准确、快速识别,为高速公路的安全运行提供了有力保障。

五、结论与展望

本文基于卷积神经网络设计并实现了一种高速公路团雾智能识别系统。该系统能够实时采集道路图像,并通过预处理、特征提取和分类识别等步骤实现对团雾的准确识别。实验结果表明,该系统具有较高的识别准确率和泛化能力,为高速公路的安全运行提供了有力支持。未来,可以进一步优化网络结构、提高模型性能,并探索将系统应用于更多场景的可能性。同时,也可以结合其他技术,如雷达、红外传感器等,实现多源信息的融合与协同处理,提高系统的可靠性和稳定性。

数据集介绍
整体数据集约包含一千张图像,其中高速公路正常照片图像、产生团雾场景的照片图像各约500张
正常图像如下:
在这里插入图片描述产生团雾的图像如下:
在这里插入图片描述

核心源码介绍

模型训练部分:

#导入工具包
import numpy
import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt
from torch.utils.data import dataset
from torchvision import transforms, datasets
from model import CNN

读取数据,使用pytorch框架对原始图像数据进行预处理

    # 数据转换
    data_transform = transforms.Compose([
        transforms.RandomHorizontalFlip(),  # 随机水平翻转,数据增强
        # transforms.Grayscale(num_output_channels=1),    # 灰度图通道设为1,彩色图不要这句话
        transforms.ToTensor(),              # 这个必须要有,转化为tensor。(会自动归一化数据)
        transforms.Normalize(mean=[0.17], std=[0.05])   # 标准化(训练集图片归一化后的均值大概是0.17,标准差0.05),加快收敛,不要影响也不大
    ])

读取数据,随机分为训练集和验证集

 # random_spilt随机划分数据集
    train_data, val_data = torch.utils.data.random_split(full_dataset, [train_size, val_size])

    # DataLoder把dataset按batchsize打包,我们训练才能从里面逐个取数据,
    # batch_size是一次计算的图片数,一般为2,4,8,16,24,32..因为我们图片不多,尺寸小,模型小,所以运算量很小,我就直接取全部
    # 你自己做其他任务不要这样搞,不然算不动的
    train_loader = torch.utils.data.DataLoader(train_data, batch_size=train_size, shuffle=False)
    val_loader = torch.utils.data.DataLoader(val_data, batch_size=val_size, shuffle=False)

    # iter(dataloader)返回的是一个迭代器,然后可以使用next()访问。
    # 获取验证集图像和标签用于验证正确率
    val_data_iter = iter(val_loader)
    val_image, val_label = next(val_data_iter, None)

定义模型

 # val_data_iter.next()

    # 定义模型,.cuda()表示用GPU计算
    # model = CNN().cuda()
    model = CNN()

    # 损失函数,分类任务一般是交叉熵
    loss_function = nn.CrossEntropyLoss()

    # 优化器,Adam,它考虑了动量和自适应学习率,优化器有很多你可以自己了解了解
    # Aadm和SGD比较常用,有时候SGD效果还好一些
    optimizer = optim.Adam(model.parameters(), lr=0.001)
    # 迭代次数
    epoch = 200
    # 保存数据
    train_set_loss = []
    val_set_loss = []
    train_set_acc = []
    val_set_acc = []

模型训练部分

model.train()
    for ep in range(epoch):  # loop over the dataset multiple times
        running_loss = 0
        trainset_right = 0
        for step, (x, y) in enumerate(train_loader, start=0):
            # 取出的数据也要转到gpu
            # inputs = x.cuda()
            # labels = y.cuda()
            inputs = x.cpu()
            labels = y.cpu()
            # 优化器梯度清零
            optimizer.zero_grad()
            # 前向传播
            outputs1 = model(inputs)
            # 统计训练集分类正确个数,用于验证训练集的正确率
            # ouputs1维度为[batchsize,2],取第1维(类别)最大的索引为类别(0或1)
            predict_y1 = torch.max(outputs1, dim=1)[1]
            trainset_right += torch.eq(predict_y1, labels).sum().item()
            # 计算损失
            train_loss = loss_function(outputs1, labels)
            # 反向传播
            train_loss.backward()
            # 更新优化器
            optimizer.step()

            # 如果你不验证的话,那么至此训练过程就写完了,很简单吧
            # 不管你做什么任务都是这几步,梯度清零,预测结果计算损失,反向传播

            # validation,这里本来是每n个step输出一次数据,因为通常来讲训练集是成千上万张
            # 但是我们的训练集非常小,我就直接一个step输出一次,这里验证集batchsize=val_size
            # 如果你的验证集数量特别多,建议编写一个evaluate函数用于验证
            running_loss += train_loss.item()
            with torch.no_grad():
                # 数据要取回cpu才能绘图
                # outputs2 = model(val_image.cuda()).cpu()
                outputs2 = model(val_image).cpu()
                predict_y2 = torch.max(outputs2, dim=1)[1]
                val_loss = loss_function(outputs2, predict_y2)
                accuracy = torch.eq(predict_y2, val_label).sum().item() / val_label.size(0)
                print('epoch:[%d/%d] step:[%d/%d]  train_loss: %.3f  val_loss: %.3f  val_accuracy: %.3f' %
                        (ep + 1, epoch, step + 1, len(train_loader), val_loss.item(), train_loss.item(), accuracy))

        train_set_acc.append(trainset_right/train_size)
        loss_per_epoch = running_loss / len(train_loader)
        train_set_loss.append(loss_per_epoch)

        val_set_acc.append(accuracy)
        val_set_loss.append(val_loss)

    print('Finished Training')

模型结构
采用卷积神经网络

class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.covn1 = nn.Sequential(       # 原始图片为(1,224,224)
            nn.Conv2d(3, 8, 5, 2),        # 卷积,卷积核5×5,步长2, (8,110,110)
            nn.ReLU(),                    # ReLU激活函数
            nn.MaxPool2d(2),              # 最大池化,池化核2×2,步长2, (8,55,55)
        )
        self.conv2 = nn.Sequential(
            nn.Conv2d(8, 16, 3, 1),        # (16,53,53)
            nn.ReLU(),
            nn.MaxPool2d(2),               # (16,26,26)
        )
        self.conv3 = nn.Sequential(
            nn.Conv2d(16, 32, 3, 1),       # (32,24,24)
            nn.ReLU(),
            nn.MaxPool2d(2),               # (32,12,12)
        )
        self.conv4 = nn.Sequential(
            nn.Conv2d(32, 64, 3, 1),       # (64,10,10)
            nn.ReLU(),
            nn.MaxPool2d(2),               # (64,5,5)
        )
        self.conv5 = nn.Sequential(
            nn.Conv2d(64, 64, 5, 1),       # (64,1,1)
        )
        self.layer1 = nn.Linear(64*1*1, 2)  # 全连接层将它展平  2类
        # initial weights
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight, mode="fan_out")
                if m.bias is not None:
                    nn.init.zeros_(m.bias)
            elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)):
                nn.init.ones_(m.weight)
                nn.init.zeros_(m.bias)
            elif isinstance(m, nn.Linear):
                nn.init.normal_(m.weight, 0, 0.01)
                nn.init.zeros_(m.bias)
#前向传播
    def forward(self, x):
        x = self.covn1(x)
        x = self.conv2(x)
        x = self.conv3(x)
        x = self.conv4(x)
        x = self.conv5(x)
        x = x.view(x.size(0), -1)
        output = self.layer1(x)
        return output

模型训练曲线:
在这里插入图片描述

可视化效果展示,采用Pyqt构建软件界面

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

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

毕业小助手

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值