当前位置: 首页 > news >正文

【人脸检测】Yolov5Face:优秀的one-stage人脸检测算法

论文题目:《YOLO5Face: Why Reinventing a Face Detector》
论文地址:https://arxiv.org/pdf/2105.12931.pdf
代码地址:https://github.com/deepcam-cn/yolov5-face

1.简介

       近年来,CNN在人脸检测方面已经得到广泛的应用。但是许多人脸检测器都是需要使用特别设计的人脸检测器来进行人脸的检测,而YOLOv5的作者则是把人脸检测作为一个一般的目标检测任务来看待的。YOLOv5Face在YOLOv5的基础上添加了一个 5-Point Landmark Regression Head(关键点回归),并对Landmark Regression Head使用了Wing loss进行约束。YOLOv5Face设计了不同模型尺寸的检测器,从大模型到超小模型,以实现在嵌入式或移动设备上的实时检测。

在这里插入图片描述

       在WiderFace数据集上的实验结果表明,YOLOv5Face在几乎所有的Easy、Medium和Hard子集上都能达到最先进的性能,超过了特定设计的人脸检测器。

为什么人脸检测=一般检测:

       在YOLOv5Face的方法中是把人脸检测作为一个一般的目标检测任务。与TinaFace想法类似把人脸作为一个目标。正如在TinaFace中所讨论的:
・从数据的角度来看,人脸所具有的诸如姿态、尺度、遮挡、光照以及模糊等也会出现在其他的一般检测任务之中;
・从面部的独特属来看性,如表情和化妆,也可以对应一般检测问题中的形状变化和颜色变化。
       Landmark相对来说是一个特殊的存在,但他们也并不是唯一的。它们只是一个物体的关键点。例如,在车牌检测中,也使用了Landmark。在目标预测模型的Head中添加Landmark回归相对来说是一键简单的事情。那么从人脸检测所面临的挑战来看,多尺度、小人脸、密集场景等在一般的目标检测中都存在。因此,人脸检测完全可以看作一个一般目标检测子任务。

设计目标

       YOLOv5Face针对人脸检测的对YOLOv5进行了再设计和修改,考虑到大人脸、小人脸、Landmark监督等不同的复杂性和应用。YOLOv5Face的目标是为不同的应用程序提供一个模型组合,从非常复杂的应用程序到非常简单的应用程序,以在嵌入式或移动设备上获得性能和速度的最佳权衡。

主要贡献

       1.重新设计了YOLOV5来作为一个人脸检测器,并称之为YOLOv5Face。对网络进行了关键的修改,以提高平均平均精度(mAP)和速度方面的性能;
       2.设计了一系列不同规模的模型,从大型模型到中型模型,再到超小模型,以满足不同应用中的需要。除了在YOLOv5中使用的Backbone外,还实现了一个基于ShuffleNetV2的Backbone,它为移动设备提供了最先进的性能和快速的速度;
       3.在WiderFace数据集上评估了YOLOv5Face模型。在VGA分辨率的图像上,几乎所有的模型都达到了SOTA性能和速度。这也证明了前面的结论,不需要重新设计一个人脸检测器,因为YOLO5就可以完成它。

2.Yolov5Face

2.1.网络结构

2.1.1.整体架构

       YOLOv5Face是以YOLOv5作为Baseline来进行改进和再设计以适应人脸检测。这里主要是检测小脸和大脸的修改。整体结构如下:
在这里插入图片描述
       YOLO5人脸检测器的网络架构如上图所示。它由Backbone、Neck和Head组成,描述了整体的网络体系结构。在YOLOv5中,使用了CSPNet Backbone。在Neck中使用了SPP和PAN来融合这些特征。在Head中也都使用了回归和分类。

2.1.2.CBS Block

在这里插入图片描述
       上图定义了一个CBS Block,它由Conv、BN和SiLU激活函数组成。CBS Block也被用于许多其他Block之中。

class Conv(nn.Module):# Standard convolutiondef __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True):  # ch_in, ch_out, kernel, stride, padding, groupssuper(Conv, self).__init__()# 卷积层self.conv = nn.Conv2d(c1, c2, k, s, autopad(k, p), groups=g, bias=False)# BN层self.bn = nn.BatchNorm2d(c2)# SiLU激活层self.act = nn.SiLU() if act is True else (act if isinstance(act, nn.Module) else nn.Identity())def forward(self, x):return self.act(self.bn(self.conv(x)))

2.1.3.Head

在这里插入图片描述
       在上图中,显示了Head的输出标签,其中包括边界框(bbox)、置信度(conf)、分类(cls)和5-Point Landmarks。这些Landmarks是对YOLOv5的改进点,使其成为一个具有Landmarks输出的人脸检测器。如果没有Landmarks,最后一个向量的长度应该是6而不是16。

请注意,P3中的输出尺寸80×80×16,P4中的40×40×16,P5中的20×20×16,可选P6中的10×10×16为每个Anchor。实际的尺寸应该乘以Anchor的数量。

2.1.4.stem结构

在这里插入图片描述

       上图为stem结构,它用于取代YOLOv5中原来的Focus层。在YOLOv5中引入Stem块用于人脸检测是YOLOv5Face的创新之一。用Stem模块替代网络中原有的Focus模块,提高了网络的泛化能力,降低了计算复杂度,同时性能也没有下降。Stem模块的图示中虽然都是用的CBS,但是看代码可以看出来第2个和第4个CBS是1×1卷积,第1个和第3个CBS是3×3,stride=2的卷积。配合yaml文件可以看到stem以后图像大小由640×640变成了160×160。

class StemBlock(nn.Module):def __init__(self, c1, c2, k=3, s=2, p=None, g=1, act=True):super(StemBlock, self).__init__()# 3×3卷积self.stem_1 = Conv(c1, c2, k, s, p, g, act)# 1×1卷积self.stem_2a = Conv(c2, c2 // 2, 1, 1, 0)# 3×3卷积self.stem_2b = Conv(c2 // 2, c2, 3, 2, 1)# 最大池化层self.stem_2p = nn.MaxPool2d(kernel_size=2, stride=2, ceil_mode=True)# 1×1卷积self.stem_3 = Conv(c2 * 2, c2, 1, 1, 0)def forward(self, x):stem_1_out = self.stem_1(x)stem_2a_out = self.stem_2a(stem_1_out)stem_2b_out = self.stem_2b(stem_2a_out)stem_2p_out = self.stem_2p(stem_1_out)out = self.stem_3(torch.cat((stem_2b_out, stem_2p_out), 1))return out

2.1.5.CSP Block(C3)

在这里插入图片描述
       上图显示了一个CSP Block(C3)。CSP Block的设计灵感来自于DenseNet。但是,不是在一些CNN层之后添加完整的输入和输出,输入被分成 2 部分。其中一半通过一个CBS Block,即一些Bottleneck Blocks,另一半是经过Conv层进行计算。

class C3(nn.Module):# CSP Bottleneck with 3 convolutionsdef __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):  # ch_in, ch_out, number, shortcut, groups, expansionsuper(C3, self).__init__()c_ = int(c2 * e)  # hidden channelsself.cv1 = Conv(c1, c_, 1, 1)self.cv2 = Conv(c1, c_, 1, 1)self.cv3 = Conv(2 * c_, c2, 1)  # act=FReLU(c2)self.m = nn.Sequential(*[Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n)])def forward(self, x):return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), dim=1))

2.1.6. C3模块中的Bottleneck层

在这里插入图片描述

class Bottleneck(nn.Module):# Standard bottleneckdef __init__(self, c1, c2, shortcut=True, g=1, e=0.5):  # ch_in, ch_out, shortcut, groups, expansionsuper(Bottleneck, self).__init__()c_ = int(c2 * e)  # hidden channels#第1个CBS模块self.cv1 = Conv(c1, c_, 1, 1)#第2个CBS模块self.cv2 = Conv(c_, c2, 3, 1, g=g)#元素add操作self.add = shortcut and c1 == c2def forward(self, x):return x + self.cv2(self.cv1(x)) if self.add else self.cv2(self.cv1(x))

2.1.7.SPP Block

在这里插入图片描述

       上图是SPP Block。YOLOv5Face在这个Block中把YOLOv5中的13×13,9×9,5×5的kernel size修改为7×7,5×5,3×3,这个改进更适用于人脸检测并提高了人脸检测的精度

class SPP(nn.Module):# 这里主要是讲YOLOv5中的kernel=(5,7,13)修改为(3, 5, 7)def __init__(self, c1, c2, k=(3, 5, 7)):super(SPP, self).__init__()c_ = c1 // 2  # hidden channels# 对应第1个CBS Blockself.conv1 = Conv(c1, c_, 1, 1)# 对应第2个 cat后的 CBS Blockself.conv2 = Conv(c_ * (len(k) + 1), c2, 1, 1)# ModuleList=[3×3 MaxPool2d,5×5 MaxPool2d,7×7 MaxPool2d]self.m = nn.ModuleList([nn.MaxPool2d(kernel_size=x, stride=1, padding=x // 2) for x in k])def forward(self, x):x = self.conv1(x)return self.conv2(torch.cat([x] + [m(x) for m in self.m], 1))

2.1.8.增加P6特征图

       同时,YOLOv5Face添加一个stride=64的P6输出块,P6可以提高对大人脸的检测性能。(之前的人脸检测模型大多关注提高小人脸的检测性能,这里作者关注了大人脸的检测效果,提高大人脸的检测性能来提升模型整体的检测性能)。P6的特征图大小为10x10。

注意,这里只考虑VGA分辨率的输入图像。为了更精确地说,输入图像的较长的边缘被缩放到640,并且较短的边缘被相应地缩放。较短的边缘也被调整为SPP块最大步幅的倍数。例如,当不使用P6时,较短的边需要是32的倍数;当使用P6时,较短的边需要是64的倍数。

2.2.输入端改进

       YOLOv5Face作者发现一些目标检测的数据增广方法并不适合用在人脸检测中,包括上下翻转和Mosaic数据增广。删除上下翻转可以提高模型性能。对小人脸进行Mosaic数据增广反而会降低模型性能,但是对中尺度和大尺度人脸进行Mosaic可以提高性能。随机裁剪有助于提高性能。

这里主要还是COCO数据集和WiderFace数据集尺度有差异,WiderFace数据集小尺度数据相对较多。

2.3.Landmark回归

       Landmark是人脸的重要特征。它们可以用于人脸比对、人脸识别、面部表情分析、年龄分析等任务。传统Landmark由68个点组成。它们被简化为5点时,这5点Landmark就被广泛应用于面部识别。人脸标识的质量直接影响人脸对齐和人脸识别的质量。
       一般的物体检测器不包括Landmark。可以直接将其添加为回归Head。因此,作者将它添加到YOLO5Face中。Landmark输出将用于对齐人脸图像,然后将其发送到人脸识别网络。
在这里插入图片描述

       用于Landmark回归的一般损失函数为L2、L1或smooth-L1。MTCNN使用的就是L2损失函数。然而,作者发现这些损失函数对小的误差并不敏感。为了克服这个问题,提出了Wing loss:

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

landmark的获取:

#landmarks
lks = t[:,6:14]
lks_mask = torch.where(lks < 0, torch.full_like(lks, 0.), torch.full_like(lks, 1.0))
#应该是关键点的坐标除以anch的宽高才对,便于模型学习。使用gwh会导致不同关键点的编码不同,没有统一的参考标准
lks[:, [0, 1]] = (lks[:, [0, 1]] - gij)
lks[:, [2, 3]] = (lks[:, [2, 3]] - gij)
lks[:, [4, 5]] = (lks[:, [4, 5]] - gij)
lks[:, [6, 7]] = (lks[:, [6, 7]] - gij)

Wing Loss的计算如下:

#landmarks
lks = t[:,6:14]
lks_mask = torch.where(lks < 0, torch.full_like(lks, 0.), torch.full_like(lks, 1.0))
#应该是关键点的坐标除以anch的宽高才对,便于模型学习。使用gwh会导致不同关键点的编码不同,没有统一的参考标准
lks[:, [0, 1]] = (lks[:, [0, 1]] - gij)
lks[:, [2, 3]] = (lks[:, [2, 3]] - gij)
lks[:, [4, 5]] = (lks[:, [4, 5]] - gij)
lks[:, [6, 7]] = (lks[:, [6, 7]] - gij)
Wing Loss的计算如下:class WingLoss(nn.Module):def __init__(self, w=10, e=2):super(WingLoss, self).__init__()# https://arxiv.org/pdf/1711.06753v4.pdf   Figure 5self.w = wself.e = eself.C = self.w - self.w * np.log(1 + self.w / self.e)def forward(self, x, t, sigma=1):  #这里的x,t分别对应之后的pret,truelweight = torch.ones_like(t) #返回一个大小为1的张量,大小与t相同weight[torch.where(t==-1)] = 0diff = weight * (x - t)abs_diff = diff.abs()flag = (abs_diff.data < self.w).float()y = flag * self.w * torch.log(1 + abs_diff / self.e) + (1 - flag) * (abs_diff - self.C) #全是0,1return y.sum()class LandmarksLoss(nn.Module):# BCEwithLogitLoss() with reduced missing label effects.def __init__(self, alpha=1.0):super(LandmarksLoss, self).__init__()self.loss_fcn = WingLoss()#nn.SmoothL1Loss(reduction='sum')self.alpha = alphadef forward(self, pred, truel, mask): #预测的,真实的 600(原来为62*10)(推测是去掉了那些没有标注的值)loss = self.loss_fcn(pred*mask, truel*mask)  #一个值(tensor)return loss / (torch.sum(mask) + 10e-14)

2.4.YOLOv5Face的后处理NMS

       其实本质上没有改变,这里仅仅给出对比的代码。

yolov5的NMS代码如下:

def non_max_suppression(prediction, conf_thres=0.25, iou_thres=0.45, classes=None, agnostic=False, labels=()):"""Performs Non-Maximum Suppression (NMS) on inference resultsReturns:detections with shape: nx6 (x1, y1, x2, y2, conf, cls)"""nc = prediction.shape[2] -5  # number of classes

yolov5face的NMS代码如下:

def non_max_suppression_face(prediction, conf_thres=0.25, iou_thres=0.45, classes=None, agnostic=False, labels=()):"""Performs Non-Maximum Suppression (NMS) on inference resultsReturns:detections with shape: nx6 (x1, y1, x2, y2, conf, cls)"""# 不同之处nc = prediction.shape[2] - 15  # number of classes

综上,对比yolov5,yolov5face主要改进点简单总结如下:
1.增加了人脸landmark回归head,并提出和采用了更适用于landmark回归的wing loss。
2.替换Focus层为Stem层。增加了网络的通用性,同时减少了计算量,且模型表现没有下降。
3.将SPP的kernel尺寸改小。YOLOv5Face在这个Block中把YOLOv5中的13×13,9×9,5×5的kernel size修改为7×7,5×5,3×3,这个改进更适用于人脸检测并提高了人脸检测的精度。
4.增加了stride=64的P6特征图输出块。P6可以提高对大人脸的检测性能。(之前的人脸检测模型大多关注提高小人脸的检测性能,这里作者关注了大人脸的检测效果,提高大人脸的检测性能来提升模型整体的检测性能)。P6的特征图大小为10x10。

##################################################################################

分析比较L1,L2、Smooth L1损失函数和WingLoss

在这里插入图片描述

其中s是人脸关键点的ground-truth,函数f(x)就等价于:

在这里插入图片描述

损失函数对x的导数分别为:

在这里插入图片描述

       L2损失函数。当x增大时L2 loss对x的导数也增大,这就导致训练初期,预测值与ground-truth差异过大时,损失函数对预测值的梯度十分大,导致训练不稳定。
       L1损失函数。L1 loss的导数为常数,在训练后期,预测值与ground-truth差异很小时, 损失对预测值的导数的绝对值仍然为1,此时学习率(learning rate)如果不变,损失函数将在稳定值附近波动,难以继续收敛达到更高精度。
       Smooth L1损失函数。在x较小时,对x的梯度也会变小,而在x很大时,对x的梯度的绝对值达到上限 1,也不会太大以至于破坏网络参数。smooth L1完美地避开了L1和L2损失的缺陷。
       此外,根据fast rcnn的说法,“… L1 loss that is less sensitive to outliers than the L2 loss used in R-CNN and SPPnet.” 也就是smooth L1让loss对于离群点更加鲁棒,即相比于L2损失函数,其对离群点、异常值(outlier)不敏感,梯度变化相对更小,训练时不容易跑飞。
在这里插入图片描述

WingLoss的优势:

       上一部分中分析的所有损失函数在出现较大误差时表现良好。这说明神经网络的训练应更多地关注具有小或中误差的样本。为了实现此目标,提出了一种新的损失函数,即基于CNN的面部Landmark定位的Wing Loss。

在这里插入图片描述
       当NME在0.04的时候,测试数据比例已经接近1了,所以在0.04到0.05这一段,也就是所谓的large errros段,并没有分布更多的数据,说明各损失函数在large errors段都表现很好。模型表现不一致的地方就在于small errors和medium errors段,例如,在NME为0.02的地方画一根竖线,相差甚远的。因此作者提出训练过程中应该更多关注samll or medium range errros样本。

       可以使用ln x来增强小误差的影响,它的梯度是1/x,对于接近0的值就会越大,optimal step size为x的平方,这样gradient就由small errors“主导”,step size由large errors“主导”。这样可以恢复不同大小误差之间的平衡。
       但是,为了防止在可能的错误方向上进行较大的更新步骤,重要的是不要过度补偿较小的定位错误的影响。这可以通过选择具有正偏移量的对数函数来实现。
       但是这种类型的损失函数适用于处理相对较小的定位误差。在wild人脸关键点检测中,可能会处理极端姿势,这些姿势最初的定位误差可能非常大,在这种情况下,损失函数应促进从这些大错误中快速恢复。这表明损失函数的行为应更像L1或L2。由于L2对异常值敏感,因此选择了L1。
       所以,对于小误差,它应该表现为具有偏移量的对数函数,而对于大误差,则应表现为L1。因此复合损失函数Wing Loss就诞生了。

相关文章:

【人脸检测】Yolov5Face:优秀的one-stage人脸检测算法

论文题目&#xff1a;《YOLO5Face: Why Reinventing a Face Detector》 论文地址&#xff1a;https://arxiv.org/pdf/2105.12931.pdf 代码地址&#xff1a;https://github.com/deepcam-cn/yolov5-face 1.简介 近年来&#xff0c;CNN在人脸检测方面已经得到广泛的应用。但是许多…...

【Unity3d】Unity与Android之间通信

在unity开发或者sdk开发经常遇到unity与移动端原生层之间进行通信&#xff0c;这里把它们之间通信做一个整理。 关于Unity与iOS之间通信&#xff0c;参考【Unity3d】Unity与iOS之间通信 Unity(c#)调用Android (一)、编写Java代码 实际上&#xff0c;任何已经存在的Java代码…...

Allegro如何更改DRC尺寸大小操作指导

Allegro如何更改DRC尺寸大小操作指导 在做PCB设计的时候,DRC可以辅助设计,有的时候DRC的尺寸过大会影响视觉,Allegro支持将DRC的尺寸变小或者改大 如下图,DRC尺寸过大 如何改小,具体操作如下 点击Setup选择Design Parameters...

Mongodb WT_PANIC: WiredTiger library panic

文章目录故障现象排查过程1.查看Log2.同步恢复数据故障现象 周五突然收到Mongo实例莫名奇妙挂了告警&#xff0c;一般都是RS复制集架构模式&#xff08;5节点&#xff09;&#xff0c;查看此实例角色为SECONDAR&#xff0c;挂了暂时不影响线上业务&#xff0c;但还是需要尽快修…...

【HTML】HTML 表格总结 ★★★ ( 表格标签 | 行标签 | 单元格标签 | 表格标签属性 | 表头单元格标签 | 表格标题标签 | 合并单元格 )

文章目录一、表格标签组成 ( 表格标签 | 行标签 | 单元格标签 )二、table 表格属性 ( border 属性 | align 属性 | width 属性 | height 属性 )三、表头单元格标签四、表格标题标签五、合并单元格1、合并单元格方式2、合并单元格顺序3、合并单元格流程六、合并单元格示例1、原始…...

linux013之文件和目录的权限管理

用户、组、文件目录的关系&#xff1a; 简介&#xff1a;用户和组关联&#xff0c;组合文件目录关联&#xff0c;这样就实现了用户对文件的权限管理。首先来看一下&#xff0c;一个文件或目录的权限是怎么查看的&#xff0c;ls -l&#xff0c; 如下&#xff0c;这个信息怎么看呢…...

设计模式之状态模式

什么是状态模式 状态模式是指允许一个对象在其内部状态改变时改变他的行为&#xff0c;对象看起来似乎改变了整个类。     状态模式将一个对象在不同状态下的不同行为封装在一个个状态类中&#xff0c;通过设置不同的状态对象可以让环境对象拥有不同的行为&#xff0c;而状…...

XQuery 选择 和 过滤

XML实例文档 我们将在下面的例子中继续使用这个 "books.xml" 文档&#xff08;和上面的章节所使用的 XML 文件相同&#xff09;。 在您的浏览器中查看 "books.xml" 文件。 选择和过滤元素 正如在前面的章节所看到的&#xff0c;我们使用路径表达式或 FL…...

室友打了一把王者的时间,我理清楚了grep,find,管道|,xargs的区别与联系,用的时候不知道为什么要这样用

目录 问题引入 find和grep的基本区别 xargs命令 Linux命令的标准输入 vs 命令行参数 举例总结 问题引入 在自己做项目的过程中&#xff0c;想使用linux命令统计下一个目录下html文件的数量&#xff0c;在思考应该使用grep还是find去配合wc指令统计文件数量&#xff0c;后来…...

python 刷题时常见的函数

collections.OrderedDict 1. move_to_end() move_to_end() 函数可以将指定的键值对移动到最前面或者最后面&#xff0c;即最左边或最右边 。 2. popitem() popitem()可以完成元素的删除操作&#xff0c;有一个可选参数last&#xff08;默认为True&#xff09;&#xff0c;…...

Python之列表推导式和列表排序

Python中的列表推导式&#xff0c;是小编比较喜欢的一种&#xff0c;他能大大减少你的代码量来得到你想要的结果&#xff0c;下面说说列表中常用的几种推导式 列表排序 Python开发中会经常用到排序操作&#xff0c;这里提供两种方式供大家参考&#xff0c;对象的sort()方法和…...

力扣(LeetCode)240. 搜索二维矩阵 II(C++)

题目描述 枚举 枚举整个矩阵&#xff0c;找到等于 target 的元素&#xff0c;则 return true &#xff0c;否则 return false。 class Solution { public:bool searchMatrix(vector<vector<int>>& matrix, int target) {int n matrix.size(), m matrix[0]…...

golang defer

文章目录延迟函数的参数在defer语句出现时就已经确定下来了延迟函数没有入参时&#xff0c;延迟函数体内的变量会受到影响延迟函数 *可以* 修改主函数的 *具名* 返回值延迟函数 *无法* 修改主函数的 *匿名* 返回值defer会把声明的 延迟函数以及 函数的入参放到栈上&#xff0c;…...

【Java】线程的死锁和释放锁

线程死锁是线程同步的时候可能出现的一种问题 文章目录1. 线程的死锁1.1 基本介绍1.2 应用案例2. 释放锁2.1 下面的操作会释放锁2.2 下面的操作不会释放锁1. 线程的死锁 1.1 基本介绍 多个线程都占用了对方的锁资源&#xff0c;但不肯相让&#xff0c;导致了死锁&#xff0c;…...

如何使用断点续传上传大文件

概念 大文件上传的需求介绍 不管怎样简单的需求&#xff0c;在量级达到一定层次时&#xff0c;都会变得异常复杂。 文件上传简单&#xff0c;文件变大就复杂 上传大文件时&#xff0c;以下几个变量会影响我们的用户体验 服务器处理数据的能力请求超时网络波动 上传时间会变长…...

【图神经网络】图拉普拉斯滤波器如何实现全通、低通、高通滤波

【图神经网络】图拉普拉斯滤波器如何实现全通、低通、高通滤波 文章目录【图神经网络】图拉普拉斯滤波器如何实现全通、低通、高通滤波1. 前言2. 符号说明3. 三种滤波3.1 全通滤波3.2 低通滤波3.2.1 平滑信号分析3.2.2 广义拉普拉斯平滑滤波器3.3 高通滤波4. 总结1. 前言 GCN&…...

python操作mysql数据库详解

使用Python操作MySQL数据库 MySQL是一种关系型数据库管理系统&#xff0c;它可以用来存储和管理大量的数据。之前介绍了大部分主流数据库&#xff0c;今天将介绍如何使用Python来操作MySQL数据库。 安装MySQL 首先&#xff0c;我们需要安装MySQL服务器&#xff0c;可以从MyS…...

netty群聊系统

1设计思路&#xff1a;启动一个服务端&#xff0c;多个客户端第一个客户端启动时&#xff0c;会告诉服务器上线了第二个客户端启动时&#xff0c;告诉服务器上线&#xff0c;并且通知第一个启动的客户端第三个客户端启动时&#xff0c;告诉服务器上线&#xff0c;并且通知第一个…...

Android 初代 K-V 存储框架 SharedPreferences,旧时代的余晖?

本文已收录到 AndroidFamily&#xff0c;技术和职场问题&#xff0c;请关注公众号 [彭旭锐] 提问。 前言 大家好&#xff0c;我是小彭。 SharedPreferences 是 Android 平台上轻量级的 K-V 存储框架&#xff0c;亦是初代 K-V 存储框架&#xff0c;至今被很多应用沿用。 有的…...

在windows中使用tomcat搭建Jenkins

1、 准备环境&#xff1a;JDK JDK官网下载&#xff1a;https://download.oracle.com/java/19/latest/jdk-19_windows-x64_bin.msi 2、 tomcat包 tocat官网下载&#xff1a;https://tomcat.apache.org/download-90.cgi 3、 Jenkins.war包 Jenkins官网下载&#xff1a;https://mi…...

Linux系统

linux系统 世界上最重要的服务器端操作系统。 创建新目录 mkdir app mkdir -m 目录权限 目录名 创建有权限的目录名。 创建一个空白文件 touch app.txt创建一个文件。 cat创建一个文件。 vi/vim创建一个文件。 nano创建一个文件。 truncate创建一个文件。 pwd查看当前目录。 rm…...

Mel Frequency Cepstral Coefficients (MFCCs)

wiki里说 在声音处理中&#xff0c;梅尔频率倒谱( MFC ) 是声音的短期功率谱的表示&#xff0c;基于非线性梅尔频率标度上的对数功率谱的线性余弦变换。 倒谱和MFC 之间的区别在于&#xff0c;在 MFC 中&#xff0c;频带在梅尔尺度上等距分布&#xff0c;这比正常频谱中使用的线…...

第七讲---贪心(上课)

1.股票买卖 一、贪心 考虑一种方案&#xff0c;在每次上升的前一天购入股票&#xff0c;并在上升后的当天卖出的方案 if (w[i] > w[i - 1])res w[i] - w[i - 1];接下来证明该贪心思路得出的方案即是最优解。 &#xff08;1&#xff09;证明贪心解 ≥ 最优解&#xff1a; …...

计算机如何思考与图灵完备

图灵完备是针对一套数据操作规则而言的概念,数据操作规则可以是一门编程语言,也可以是计算机实现里面的指令集,比如C/C++是图图灵完备的,通用CPU也是图灵完备的,但是GPU却不一定是图灵完备的。说白了图灵完备定义了一套规则,当这套规则可以实现图灵迹模型里的全部功能时,…...

惠普LaserJet M1005 MFP报错b2

故障现象: 惠普LaserJet M1005 MFP开机后直接报b2错误; 检测维修: 故障大意是:机器的硬件可能出现点突变,此问题建议联系当地维修中心进行处理。...

网络协议(TCP/IP)

目录一、网络分层模型二、OSI模型三、网络传输原理四、TCP/IP1、TCP/IP 原理2、TCP 三次握手/四次挥手3、Http协议和TCP/IP的区别五、HTTP原理六、HTTPS原理七、CDN原理一、网络分层模型 互联网的本质就是一系列的网络协议&#xff0c;最早由ISO国际组织定义为7层网络参考模型…...

2023河南省第二届职业技能大赛郑州市选拔赛“网络安全” 项目比赛样题任务书

2023河南省第二届职业技能大赛郑州市选拔赛“网络安全” 项目比赛样题任务书2023河南省第二届职业技能大赛郑州市选拔赛“网络安全” 项目比赛样题任务书A模块基础设施设置/安全加固&#xff08;200分&#xff09;A-1&#xff1a;登录安全加固&#xff08;Windows, Linux&#…...

6、流程控制

目录一、if二、switch三、for四、break与continue五、goto与Label一、if if使用&#xff1a;逻辑表达式成立&#xff0c;就会执行{}里的内容&#xff1b;逻辑表达式不需要加() if 5 > 9 {fmt.Println("5>9") }if句子中允许包含1个(仅1个)分号&#xff1a;在分…...

Linux中最基本常见命令总结

❤❤&#x1f49b;&#x1f49b;&#x1f49a;&#x1f49a;&#x1f499;&#x1f499;&#x1f49c;&#x1f49c;您的认可是对我最大的帮助&#x1f49c;&#x1f49c;&#x1f499;&#x1f499;&#x1f49a;&#x1f49a;&#x1f49b;&#x1f49b;❤❤ &#x1f90e;&…...

Python学习-----模块2.0(常用模块之时间模块-->time)

目录 前言&#xff1a; time简介 导入模块 1.时间戳 2.时间元组 &#xff08;1&#xff09;把时间戳转换为元组形式 &#xff08;2&#xff09;元组转换为时间戳输出 &#xff08;3&#xff09;把元组转换为格式化时间 &#xff08;4&#xff09;把时间戳转换为格式化时间…...

网站被入侵后需做的检测(1)/附子seo

1.用户分类 超级用户&#xff08;root&#xff1a;#&#xff09;&#xff1a;可以在Linux下几乎做任何事情&#xff0c;不受限制普通用户&#xff08;local&#xff1a;$&#xff09;&#xff1a;在Linux下做有限的事情 2.用户切换 &#xff08;1&#xff09;普通用户切换到…...

合肥网络公司 网站建设/成功的软文推广

浅谈C语言中函数形参为地址类型定义形式和类型自动转换浅谈C语言中函数形参为地址类型定义形式和类型自动转换摘要&#xff1a;当函数参数为地址类型时&#xff0c;可以有多种定义形式&#xff0c;因而读者易产生迷惑&#xff0c;通过对各种实例的分析和证明&#xff0c;介绍了…...

怎么建网站数据库/常用的网络推广方式有哪些

设置max_execution_time 来阻止太长的读SQL。那可能存在的问题是会把所有长SQL都给KILL 掉。有些必须要执行很长时间的也会被误杀。自己写个脚本检测这类语句&#xff0c;比如order by rand()&#xff0c; 超过一定时间用Kill query thread_id 给杀掉。那能不能不要杀掉而让他正…...

怎样做网站的排名/企业网站优化价格

留个脚印&#xff0c;过两天总结。 看到知乎上有人对于DI|IOC 的解释&#xff0c;满不错&#xff0c;收藏下先 作者&#xff1a;OneNoodle链接&#xff1a;http://www.zhihu.com/question/23277575/answer/24259844来源&#xff1a;知乎著作权归作者所有。商业转载请联系作者获…...

东营网站建设天锐科技/友情链接导航

目前市面上双机热备软件厂家比较多&#xff0c;要想一一了解费时费力。今天我们小编就给大家来详细介绍几款双机热备软件。 一、Skybility HA Skybility HA 提供的双机高可用系统解决方案&#xff0c;为用户提供了具有单点故障容错能力的系统平台。它采用主服务发生故障时备服…...

新闻宣传wordpress主题/如何优化关键词提升相关度

在安装之前&#xff0c;确认你的机器安装了python,和easy_install.通常python是自动安装的&#xff0c;如果没有安装easy_install&#xff0c;那么wget -q http://peak.telecommunity.com/dist/ez_setup.py获取一下python ez_setup.pypexpect是python一个模块&#xff0c;可以通…...