基于Yolv5s的口罩检测
1.Yolov5算法原理和网络结构
YOLOv5按照网络深度和网络宽度的大小,可以分为YO-LOv5s、YOLOv5m、YOLOv5l、YOLOv5x。本文使用YOLOv5s,它的网络结构最为小巧,同时图像推理速度最快达0.007s。YO-LOv5的网络结构主要由四部分组成,分别是Input、Backbone、Neck、Head,其网络结构图如图所示。
Yolov5网络结构图
1.1Input端
Input使用了Mosaic数据增强、自适应锚框计算、图片尺寸处理。Mosaic数据增强把4张图片,采用随机缩放、随机裁剪、随机排布的方式进行拼接,极大地丰富了检测数据集,尤其是增加了很多小目标,让网络结构的鲁棒性更好。在YOLOv5算法中,不同的数据集,会设定不同初始长宽的锚框,在训练数据的时候,在初始锚框的基础上得到预测框,把它和真实框比较,算出两者差距,反向更新,迭代更新网络结构参数,自适应锚框计算可以得到最佳锚框值。在目标检测算法中,要训练图片的尺寸都不相同,要把原始图片统一缩放到一个固定尺寸,再输入到网络中进行训练,本文图片的尺寸为608×608×3。
1.2Backone
Backbone包含Focus、CSP和SPP。Focus不存在于其他YOLO算法中,主要是用来进行切片操作,例如608×608×3的图像在Focus结构中进行切片操作后,变成304×304×12大小,在进行32个卷集核的卷积操作,成为304×304×32的特征图。YOLOv4中只有一种CSP结构,而YOLOv5中有两种,CSP1_x和CSP2_x,它们分别应用于Backbone和Neck中,YOLOv4的CSP结构只存在Backbone中,CSP结构如图1所示,其中CSP1_x的x表示CSP1中有x个Resunit(残差组件),CSP2_x的x表示CSP2中有2x个CBL,x影响着网络结构的深度。在Backbone中,采用SPP(空间向量金字塔池化),对特征图做最大池化,将不同尺度的特征图拼接在一起。
(1)Focus结构
Focus结构中关键的是切片操作,切片操作演示过程,将4×4×3的特征图经过切片处理,变成2×2×12的特征图。将608×608×3的三通道图像输进Focus结构,经过切片操作,先变成304×304×12的特征图,之后,经过使用32个卷积核的卷积操作,最终变成304×304×32的特征图。需要注意的是,YOLOv5s网络结构中的Focus结构使用了32个卷积核,进行卷积操作,而其他三种网络结构,使用的卷积核数量有所增加。
Focus结构图
(2)CSP结构
YOLOv5中有两种结构的CSP,CSP1_X结构在Backbone主干网络中,另一种CSP2_X结构在Neck中。对于Backbone的主干网络结构,CSP模块中的卷积核大小都是3*3,步进值为2,假如输入的图像尺寸是608*608,那么它的特征图变化的规律是:608*608->304*304->152*152->76*76->38*38->19*19,最终得到了一个19*19大小的特征图。
使用CSP模块的优点:1.增强网络的学习能力,使得训练出来的模型既能保持轻量化,又能有较高的准确性。2.降低计算瓶颈。3.降低内存成本。
CSP结构图
(3)SPP结构
SPP结构详细介绍:https://www.cnblogs.com/zongfa/p/9076311.html
SPP结构图
1.3Neck
Neck中采用了FPN+PAN的结构,FPN是自上而下的,利用上采样的方式对信息进行传递融合,获得预测的特征图。PAN采用自底向上的特征金字塔。具体结构如图所示。
FPN+PAN结构图
1.4Prediction
Prediction包括Bounding box损失函数和非极大值抑制(NMS)。YOLOv5中使用GIOU_Loss作为损失函数,有效解决了边界框不重合时问题。在目标检测预测结果处理阶段,针对出现的众多目标框的筛选,采用加权NMS操作,获得最优目标框。
- GIOU_Loss损失函数
目标检测算法的损失函数一般由Classificition Loss(分类损失函数)以及Bounding Box Regeression Loss(回归损失函数)两大部分组成。回归损失函数在近几年的发展过程是:Smooth L1 Loss->IOU_Loss(2016)->GIOU_Loss(2019)->DIOU_Loss(2020)->CIOU_Loss(2020)。
IOU_Loss图
图是IOU_Loss,可以看出黄色框是预测框,蓝色框是真实框。假设预测框和真实框的交集为A,并集为B,IOU定义为交集A除以并集B,IOU的Loss为:
IOU的Loss比较简单,但存在两个问题。
问题1:预测框和真实框不相交的情况,如图(a)状态1所示,此时IOU为0,无法反应出预测框和真实框距离的远近,此时损失函数不能求导,IOU_Loss损失函数无法优化预测框和真实框不相交的情况
特殊状态的IOU_Loss图
问题2:当预测框和真实框大小相同,IOU也可能会相同,如上图(b)(c)的状态2和状态3的情况所示,此时IOU_Loss损失函数也不能区分这两种情况的不同。因此使用GIOU_Loss来进行改进。
GIOU_Loss图
如上图是GIOU_Loss,黄色框是预测框,蓝色框是真实框,令预测框和真实框的最小外接矩形为集合C,差集定义为集合C和并集B的差,则GIOU_Loss为:
GIOU_Loss损失函数提高了衡量相交尺度的方式,减少了单纯IOU_Loss时的不足。
2.实验及结果
2.1实验数据集及实验环境
2.1.1数据集
数据集采用Kaggle上的Face Mask Detection,数据集一共853张图片,划分为三个类,一种是戴口罩的,一种是不戴口罩的,还有一种是没有戴好口罩的。数据集链接:https://www.kaggle.com/andrewmvd/face-mask-detection
数据集展示:
下载下来后,这些数据集还不能直接使用。因为yolov5不支持xml文件处理,而是支持txt文件。所以首先将这些数据按照下图这样的目录格式整理好:
然后运行下面的代码,将该数据集转换成Yolov5能够使用的数据集:
import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
import random
from shutil import copyfileclasses = ["with_mask", "without_mask","mask_weared_incorrect"]
# classes=["ball"]TRAIN_RATIO = 80def clear_hidden_files(path):dir_list = os.listdir(path)for i in dir_list:abspath = os.path.join(os.path.abspath(path), i)if os.path.isfile(abspath):if i.startswith("._"):os.remove(abspath)else:clear_hidden_files(abspath)def convert(size, box):dw = 1. / size[0]dh = 1. / size[1]x = (box[0] + box[1]) / 2.0y = (box[2] + box[3]) / 2.0w = box[1] - box[0]h = box[3] - box[2]x = x * dww = w * dwy = y * dhh = h * dhreturn (x, y, w, h)def convert_annotation(image_id):in_file = open('VOCdevkit/VOC2007/Annotations/%s.xml' % image_id)out_file = open('VOCdevkit/VOC2007/YOLOLabels/%s.txt' % image_id, 'w')tree = ET.parse(in_file)root = tree.getroot()size = root.find('size')w = int(size.find('width').text)h = int(size.find('height').text)for obj in root.iter('object'):difficult = obj.find('difficult').textcls = obj.find('name').textif cls not in classes or int(difficult) == 1:continuecls_id = classes.index(cls)xmlbox = obj.find('bndbox')b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),float(xmlbox.find('ymax').text))bb = convert((w, h), b)out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')in_file.close()out_file.close()wd = os.getcwd()
wd = os.getcwd()
data_base_dir = os.path.join(wd, "VOCdevkit/")
if not os.path.isdir(data_base_dir):os.mkdir(data_base_dir)
work_sapce_dir = os.path.join(data_base_dir, "VOC2007/")
if not os.path.isdir(work_sapce_dir):os.mkdir(work_sapce_dir)
annotation_dir = os.path.join(work_sapce_dir, "Annotations/")
if not os.path.isdir(annotation_dir):os.mkdir(annotation_dir)
clear_hidden_files(annotation_dir)
image_dir = os.path.join(work_sapce_dir, "JPEGImages/")
if not os.path.isdir(image_dir):os.mkdir(image_dir)
clear_hidden_files(image_dir)
yolo_labels_dir = os.path.join(work_sapce_dir, "YOLOLabels/")
if not os.path.isdir(yolo_labels_dir):os.mkdir(yolo_labels_dir)
clear_hidden_files(yolo_labels_dir)
yolov5_images_dir = os.path.join(data_base_dir, "images/")
if not os.path.isdir(yolov5_images_dir):os.mkdir(yolov5_images_dir)clear_hidden_files(yolov5_images_dir)yolov5_labels_dir = os.path.join(data_base_dir, "labels/")if not os.path.isdir(yolov5_labels_dir):os.mkdir(yolov5_labels_dir)clear_hidden_files(yolov5_labels_dir)yolov5_images_train_dir = os.path.join(yolov5_images_dir, "train/")if not os.path.isdir(yolov5_images_train_dir):os.mkdir(yolov5_images_train_dir)clear_hidden_files(yolov5_images_train_dir)yolov5_images_test_dir = os.path.join(yolov5_images_dir, "val/")if not os.path.isdir(yolov5_images_test_dir):os.mkdir(yolov5_images_test_dir)clear_hidden_files(yolov5_images_test_dir)yolov5_labels_train_dir = os.path.join(yolov5_labels_dir, "train/")if not os.path.isdir(yolov5_labels_train_dir):os.mkdir(yolov5_labels_train_dir)clear_hidden_files(yolov5_labels_train_dir)yolov5_labels_test_dir = os.path.join(yolov5_labels_dir, "val/")if not os.path.isdir(yolov5_labels_test_dir):os.mkdir(yolov5_labels_test_dir)clear_hidden_files(yolov5_labels_test_dir)train_file = open(os.path.join(wd, "yolov5_train.txt"), 'w')test_file = open(os.path.join(wd, "yolov5_val.txt"), 'w')train_file.close()test_file.close()train_file = open(os.path.join(wd, "yolov5_train.txt"), 'a')test_file = open(os.path.join(wd, "yolov5_val.txt"), 'a')list_imgs = os.listdir(image_dir) # list image filesprob = random.randint(1, 100)print("Probability: %d" % prob)for i in range(0, len(list_imgs)):path = os.path.join(image_dir, list_imgs[i])if os.path.isfile(path):image_path = image_dir + list_imgs[i]voc_path = list_imgs[i](nameWithoutExtention, extention) = os.path.splitext(os.path.basename(image_path))(voc_nameWithoutExtention, voc_extention) = os.path.splitext(os.path.basename(voc_path))annotation_name = nameWithoutExtention + '.xml'annotation_path = os.path.join(annotation_dir, annotation_name)label_name = nameWithoutExtention + '.txt'label_path = os.path.join(yolo_labels_dir, label_name)prob = random.randint(1, 100)print("Probability: %d" % prob)if (prob < TRAIN_RATIO): # train datasetif os.path.exists(annotation_path):train_file.write(image_path + '\n')convert_annotation(nameWithoutExtention) # convert labelcopyfile(image_path, yolov5_images_train_dir + voc_path)copyfile(label_path, yolov5_labels_train_dir + label_name)else: # test datasetif os.path.exists(annotation_path):test_file.write(image_path + '\n')convert_annotation(nameWithoutExtention) # convert labelcopyfile(image_path, yolov5_images_test_dir + voc_path)copyfile(label_path, yolov5_labels_test_dir + label_name)
train_file.close()
test_file.close()
运行完上面的代码后,会生成下面的目录格式:
可以看到通过运行上面的代码,在VOCdevkit目录下生成了images和lables文件夹,这两个文件夹下又有train和val文件夹,这个就是需要的数据集了。其中train对应的就是训练集,val对应的就是测试集。
2.2.2数据集标注
因为数据集中已经给定了标注好的xml文件,这里就不再进行标注。数据集标注主要是通过labelimg进行标注。
2.2.3实验环境
实验环境采用Ubuntu 20.04.2+双路Intel 4110CPU+64G内存+RTX2080Ti显卡+Anaconda3进行实验。
2.2Yolov5网络训练
一般为了缩短网络的训练时间,并达到更好的精度,我们一般加载预训练权重进行网络的训练。而yolov5的5.0版本给我们提供了几个预训练权重,我们可以对应我们不同的需求选择不同的版本的预训练权重。通过如下的图可以获得权重的名字和大小信息,可以预料的到,预训练权重越大,训练出来的精度就会相对来说越高,但是其检测的速度就会越慢。预训练权重可以通过这个网址进行下载,本次训练自己的数据集用的预训练权重为yolov5s.pt。
我们先将Yolov5通过git将代码pull到本地,可以看到如下的目录格式:
然后我们将下载好的Yolov5.pt模型文件放在Yolov5的根目录下。将数据集文件也放在Yolov5根目录下:
现在来对代码的整体目录做一个介绍:
├── data:主要是存放一些超参数的配置文件(这些文件(yaml文件)是用来配置训练集和测试集还有验证集的路径的,其中还包括目标检测的种类数和种类的名称);还有一些官方提供测试的图片。如果是训练自己的数据集的话,那么就需要修改其中的yaml文件。但是自己的数据集不建议放在这个路径下面,而是建议把数据集放到yolov5项目的同级目录下面。
├── models:里面主要是一些网络构建的配置文件和函数,其中包含了该项目的四个不同的版本,分别为是s、m、l、x。从名字就可以看出,这几个版本的大小。他们的检测测度分别都是从快到慢,但是精确度分别是从低到高。这就是所谓的鱼和熊掌不可兼得。如果训练自己的数据集的话,就需要修改这里面相对应的yaml文件来训练自己模型。
├── utils:存放的是工具类的函数,里面有loss函数,metrics函数,plots函数等等。
├── weights:放置训练好的权重参数。
├── detect.py:利用训练好的权重参数进行目标检测,可以进行图像、视频和摄像头的检测。
├── train.py:训练自己的数据集的函数。
├── test.py:测试训练的结果的函数。
├──requirements.txt:这是一个文本文件,里面写着使用yolov5项目的环境依赖包的一些版本,可以利用该文本导入相应版本的包。
然后我们修改models/yolov5s.yaml文件将nc改成3,因为我们是个3分类问题。并且在data目录下创建一个biaoqing.yaml文件,其内容为:
train: Mask_Datas/images/train # train images (relative to 'path') 128 images
val: Mask_Datas/images/val # val images (relative to 'path') 128 images# Classes
nc: 3 # number of classes
names: ['with_mask', 'without_mask', 'mask_weared_incorrect'] # class names
里面指定了训练集和测试集的路径,以及分类的内容。
然后我们修改Yolov5根目录下的train.py文件,修改超参数如下图。其中—weights指定了预训练权重,--cfg指定预训练权重的配置文件,--data指定数据集的配置文件。还有一些参数比如—epochs指定了训练的轮数,默认是300轮,可以根据需要进行修改。还有--batch-size指定一次读取多少张照片,一般都是指定8的倍数张。根据自己的电脑性能进行修改。
修改完上面的参数后,我们将代码上传到了运行环境如下:
通过requirements.txt安装了所需要的库。直接运行python train.py即可开始进行训练,下面是训练图
经过200轮训练后,我们生成了一个best.pt,也就是在这200轮训练得出来的最后的权重文件。
2.3实验结果与分析
我们查看results.png文件如下图:
训练过程中随着迭代次数增加,各种数值变化,如上图所示,图中各个数值的含义如下:
GIo U:数值越接近0,目标框画的越准确。
Objectness:数值越接近0,对目标检测得越准确。
Classification:数值越接近0,目标分类越准确。
Precision:准确率,即标出的正确目标个数除以标出的目标总个数,越接近1,准确率越高。
Recall:召回率,即标出的正确目标个数除以需要标出的目标总个数,越接近1,准确率越高。
m AP@0.5和m AP@0.5:0.95:AP是用Precision和Recall作为两坐标轴作图后围成的面积,越接近1,准确率越高。
置信度图
P-R图
混淆矩阵
实验效果:
相关文章:

基于Yolv5s的口罩检测
1.Yolov5算法原理和网络结构 YOLOv5按照网络深度和网络宽度的大小,可以分为YO-LOv5s、YOLOv5m、YOLOv5l、YOLOv5x。本文使用YOLOv5s,它的网络结构最为小巧,同时图像推理速度最快达0.007s。YO-LOv5的网络结构主要由四部分组成,分别…...

Linux基本命令
Linux基本命令Linux的目录结构Linux命令入门目录切换相关命令(cd/pwd)相对路径、绝对路径和特殊路径符创建目录命令(mkdir)文件操作命令part1 (touch、cat、more)文件操作命令part2 (cp、mv、rm)查找命令 (which、find…...
云原生场景下的安全左移
本博客地址:https://security.blog.csdn.net/article/details/129430859 一、安全左移概述 安全左移需要考虑开发安全、软件供应链安全、镜像仓库、配置核查这四个部分。 首先是开发安全,安全团队需要关注代码漏洞,比如使用代码检查工具进…...
mysql面试经典问题
文章目录 1. 能说下myisam 和 innodb的区别吗?2. 说下mysql的索引有哪些吧,聚簇和非聚簇索引又是什么?3. 那你知道什么是覆盖索引和回表吗?4. 锁的类型有哪些呢5. 你能说下事务的基本特性和隔离级别吗?6. 那ACID靠什么保证的呢?7. 那你说说什么是幻读,什么是MVCC?幻读什…...

微信小程序|基于小程序+C#制作一个考试答题小程序
基于小程序+C#制作一个考试答题小程序打破传统线下考试答题的边界线问题,使考试不用再局限与某个统一的场所,只要有设备,哪里都能考试。 一、小程序...
【1605. 给定行和列的和求可行矩阵】
来源:力扣(LeetCode) 描述: 给你两个非负整数数组 rowSum 和 colSum ,其中 rowSum[i] 是二维矩阵中第 i 行元素的和, colSum[j] 是第 j 列元素的和。换言之你不知道矩阵里的每个元素,但是你知…...

Linux命令之nano命令
一、nano命令简介 nano是一个小型、免费、友好的编辑器,旨在取代非免费Pine包中的默认编辑器Pico。nano不仅复制了Pico的外观,还实现了Pico中一些缺失(或默认禁用)的功能,例如“搜索和替换”和“转到行号和列号”。nan…...
IT项目管理(作业1)
一.单选题(共12题,100.0分) 1.以下哪项是项目的一个实例?( ) A、改进现有的业务流程或程序B、为公司运营提供信息技术支持C、批量生产一种新近开发出来的家用电冰箱D、管理一个公司 我的答案:A 2.下列哪项不能成为项目结束的理由?( ) A…...

蓝桥杯嵌入式(G4系列):串口收发
前言: 在整个蓝桥杯考试中涉及串口的次数还是较多,这里写下这篇博客,记录一下自己的学习过程。 STM32Cubemx配置: 首先,我们点击左侧的Connectivity选择USART1进行如下配置。 使能串口中断 在左侧的管脚配置上也要做出…...

「兔了个兔」玉兔踏青,纯CSS实现瑞兔日历(附源码)
💂作者简介: THUNDER王,一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学会计学专业大二本科在读,同时任汉硕云(广东)科技有限公司ABAP开发顾问。在学习工作中,我通常使用偏后…...

第17章 关于局部波动率的一些总结
这学期会时不时更新一下伊曼纽尔德曼(Emanuel Derman) 教授与迈克尔B.米勒(Michael B. Miller)的《The Volatility Smile》这本书,本意是协助导师课程需要,发在这里有意的朋友们可以学习一下,思…...

反转链表合并两个有序链表链表分割链表的回文结构相交链表
反转链表来源:杭哥206. 反转链表 - 力扣(LeetCode)typedef struct ListNode ListNode; struct ListNode* reverseList(struct ListNode* head) {if (headNULL){return NULL;}ListNode* prevhead;ListNode* curhead->next;ListNode* furNUL…...

联想触摸板只能单击,二指三指失效
问题背景 这问题是我笔记本两三年前重装win10系统后出现的,当时有鼠标懒得弄。今天发现没鼠标后,触摸板连二指滑动都没有太麻烦了,所以决定弄一下。 联想笔记本,win10系统重装后出现的问题。 1.鲁大师,联想电脑管家 …...
mysql 删除表卡死,或是截断(truncate)卡死解决办法
利用工具进行truncate表的时候,一直运行,运行了十几分钟也没有成功。中止之后再运行也是一样。但是删除表的数据以及查询表数据都是可以的。猜测是锁死了。 使用 show processlist; 发现Waiting for table metadata lock 问题; mysql> s…...

ORACLE P6 EPPM 架构及套件介绍(源自Oracle Help)
引言 借助官方帮助的内容, 我水一篇文章,翻译了下文 P6EPPM架构 P6各套件 P6:大多数用户几乎完全依赖在标准网络浏览器中运行的 P6 网络应用程序。简称为 P6,它是管理项目的主要界面。P6 移动版:允许团队成员提供任…...
Android开发面试:数据结构与算法知识答案精解
目录 数据结构与算法 线性表 数组 链表 栈 队列 树 二叉树 红黑树 哈夫曼树 排序算法 冒泡排序 选择排序 插入排序 希尔排序 堆排序 快速排序 归并排序 查找算法 线性查找 二分查找 插值查找 斐波拉契查找 树表查找 分块查找 哈希查找 动态规划算法…...
京东前端手写面试题集锦
实现call方法 call做了什么: 将函数设为对象的属性执行和删除这个函数指定this到函数并传入给定参数执行函数如果不传入参数,默认指向为 window // 模拟 call bar.mycall(null); //实现一个call方法: // 原理:利用 context.xxx self obj.…...
【JDK动态代理】及【CGLib动态代理】:Java的两种动态代理方式
Java的两种动态代理方式动态代理是什么?JDK动态代理CGLib动态代理CGLib 底层原理CGLib 实现步骤两者区别Spring AOP原理--动态代理动态代理是什么? 动态代理就是,在程序运行期,创建目标对象的代理对象,并对目标对象中的…...

《程序员面试金典(第6版)》面试题 04.05. 合法二叉搜索树
题目描述 实现一个函数,检查一棵二叉树是否为二叉搜索树。 示例 1: 输入: 2/ \1 3输出: true 示例 2: 输入: 5/ \1 4/ \3 6输出: false 解释: 输入为: [5,1,4,null,null,3,6]。 根节点的值为 5 ,但是其右子节点值为 4 。 解题思路与代码 使用…...

Nginx 反向代理技术梳理
Nginx 反向代理技术梳理 使用反向代理脑图 域名 A 可以解析找到 CDN 缓存 用户点击 APP 即通过 URL 发送 HTTPS 请求域名会进入阿里云的 DNS 服务器,解析域名会做第一级负载均衡通过 CDN 解析出域名,通过阿里云配置转发到 CDN 缓存服务器 CDN 有数据则直…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...

前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...