YOLOv8改进 | 2023 | SCConv空间和通道重构卷积(精细化检测,又轻量又提点)
一、本文介绍
本文给大家带来的改进内容是SCConv,即空间和通道重构卷积,是一种发布于2023.9月份的一个新的改进机制。它的核心创新在于能够同时处理图像的空间(形状、结构)和通道(色彩、深度)信息,这样的处理方式使得SCConv在分析图像时更加精细和高效。这种技术不仅适用于复杂场景的图像处理,还能在普通的对象检测任务中提供更高的精确度(亲测在小目标检测和正常的物体检测中都有效提点)。SCConv的这种能力,特别是在处理大量数据和复杂图像时的优势。本文通过先介绍SCConv的基本网络结构和原理当大家对该卷积有一个大概的了解,然后教大家如何将该卷积添加到自己的网络结构中(值得一提的是该卷积的GFLOPs降低了0.3左右适合轻量化的读者) 。
适用检测目标:所有的目标检测均有一定的提点
推荐指数:⭐⭐⭐⭐⭐
专栏回顾:YOLOv8改进系列专栏——本专栏持续复习各种顶会内容——科研必备
训练结果对比图->
因为资源有限我发的文章都要做对比实验所以本次实验我只用了一百张图片检测的是火灾训练了一百个epoch,该结果只能展示出该机制有效,但是并不能产生决定性结果,因为具体的效果还要看你的数据集和实验环境所影响(这次找的数据集质量好像不太好效果波动很大)。
大家可以看出mAP(50)提高了大概0.6左右(值得一提的是该卷积的GFLOPs降低了0.3左右适合轻量化的读者)
目录
一、本文介绍
二、网络结构讲解
2.1 SCConv的主要思想
2.2 空间重构单元(SRU)
2.3 通道重构单元(CRU)
三、SCConv代码
3.1 SCConv本地代码
3.2 在SCConv外层套用函数
3.3 修改了SCConv的C2f和Bottleneck模块
四、手把手教你添加SCConv和C2f_SCConv模块
4.1 SCConv的添加教程
4.2 SCConv的yaml文件和训练截图
4.2.1 SCConv的yaml文件
4.2.2 SCConv的训练过程截图
五、SCConv可添加的位置
5.1 推荐SCConv可添加的位置
5.2 图示SCConv可添加的位置
六、本文总结
二、网络结构讲解
论文地址:官方论文地址
代码地址:官方代码地址
2.1 SCConv的主要思想
SCConv(空间和通道重构卷积)的高效卷积模块,以减少卷积神经网络(CNN)中的空间和通道冗余。SCConv旨在通过优化特征提取过程,减少计算资源消耗并提高网络性能。该模块包括两个单元:
1.空间重构单元(SRU):SRU通过分离和重构方法来减少空间冗余。
2.通道重构单元(CRU):CRU采用分割-变换-融合策略来减少通道冗余。
下面是SCConv的结构示意图->
下面我将分别解释这两个单元->
2.2 空间重构单元(SRU)
空间重构单元(SRU)是SCConv模块的一部分,负责减少特征在空间维度上的冗余。SRU接收输入特征,并通过以下步骤处理:
1. 组归一化(Group Normalization):首先对输入特征进行归一化,以减少不同特征图之间的尺度差异。
2. 权重生成:通过应用归一化和激活函数,如Sigmoid,从归一化的特征图中生成权重。
3. 特征分离:根据生成的权重,对输入特征进行分离,形成多个子特征集。
4. 特征重构:最后,这些分离出来的特征集经过变换和重组,产生空间精炼的特征输出,以便进一步处理。
上图展示了空间重构单元(SRU)的架构。SRU的工作流程如下:
1. 输入特征X:首先进行组归一化(GN)处理。
2. 分离:通过一系列的权重 ,
, ...,
对特征进行加权,这些权重是通过输入特征的通道
经过归一化和非线性激活函数(如Sigmoid)计算得到的。
3. 重构:加权后的特征被分割成两个部分 和
,然后这两部分各自经过变换,最终通过加法和拼接操作重构,得到空间精炼特征
。
总结:这个单元的设计目的是为了减少输入特征的空间冗余,从而提高卷积神经网络处理特征的效率。
2.3 通道重构单元(CRU)
通道重构单元(CRU)是SCConv模块的一部分,旨在减少卷积神经网络特征的通道冗余。CRU对经过空间重构单元(SRU)处理后的特征进一步操作,通过以下步骤减少通道冗余:
上图详细展示了通道重构单元(CRU)的架构,该单元从空间精炼特征 \( X^W \) 开始进行处理。CRU的工作流程包括以下几个步骤:
1. 分割(Split):特征 被分割成两部分,通过不同比例的
和
路径进行不同的1x1卷积处理。
2. 变换(Transform):通过全局卷积(GWC)和点卷积(PWC)进一步变换这两部分特征。
3. 融合(Fuse):两个变换后的特征 和
经过池化和SoftMax加权融合,形成最终的通道精炼特征
。
总结:这种结构旨在通过细致地处理各个通道,减少不必要的信息,并提高网络的整体性能和效率。通过这一过程,CRU有效地提高了特征的表征效率,同时减少了模型的参数数量和计算成本。
三、SCConv代码
3.1 SCConv核心代码
该代码为SCConv的本体,使用方式请看章节四。
import torch
import torch.nn.functional as F
import torch.nn as nnclass GroupBatchnorm2d(nn.Module):def __init__(self, c_num: int,group_num: int = 16,eps: float = 1e-10):super(GroupBatchnorm2d, self).__init__()assert c_num >= group_numself.group_num = group_numself.weight = nn.Parameter(torch.randn(c_num, 1, 1))self.bias = nn.Parameter(torch.zeros(c_num, 1, 1))self.eps = epsdef forward(self, x):N, C, H, W = x.size()x = x.view(N, self.group_num, -1)mean = x.mean(dim=2, keepdim=True)std = x.std(dim=2, keepdim=True)x = (x - mean) / (std + self.eps)x = x.view(N, C, H, W)return x * self.weight + self.biasclass SRU(nn.Module):def __init__(self,oup_channels: int,group_num: int = 16,gate_treshold: float = 0.5,torch_gn: bool = True):super().__init__()self.gn = nn.GroupNorm(num_channels=oup_channels, num_groups=group_num) if torch_gn else GroupBatchnorm2d(c_num=oup_channels, group_num=group_num)self.gate_treshold = gate_tresholdself.sigomid = nn.Sigmoid()def forward(self, x):gn_x = self.gn(x)w_gamma = self.gn.weight / sum(self.gn.weight)w_gamma = w_gamma.view(1, -1, 1, 1)reweigts = self.sigomid(gn_x * w_gamma)# Gatew1 = torch.where(reweigts > self.gate_treshold, torch.ones_like(reweigts), reweigts) # 大于门限值的设为1,否则保留原值w2 = torch.where(reweigts > self.gate_treshold, torch.zeros_like(reweigts), reweigts) # 大于门限值的设为0,否则保留原值x_1 = w1 * xx_2 = w2 * xy = self.reconstruct(x_1, x_2)return ydef reconstruct(self, x_1, x_2):x_11, x_12 = torch.split(x_1, x_1.size(1) // 2, dim=1)x_21, x_22 = torch.split(x_2, x_2.size(1) // 2, dim=1)return torch.cat([x_11 + x_22, x_12 + x_21], dim=1)class CRU(nn.Module):'''alpha: 0<alpha<1'''def __init__(self,op_channel: int,alpha: float = 1 / 2,squeeze_radio: int = 2,group_size: int = 2,group_kernel_size: int = 3,):super().__init__()self.up_channel = up_channel = int(alpha * op_channel)self.low_channel = low_channel = op_channel - up_channelself.squeeze1 = nn.Conv2d(up_channel, up_channel // squeeze_radio, kernel_size=1, bias=False)self.squeeze2 = nn.Conv2d(low_channel, low_channel // squeeze_radio, kernel_size=1, bias=False)# upself.GWC = nn.Conv2d(up_channel // squeeze_radio, op_channel, kernel_size=group_kernel_size, stride=1,padding=group_kernel_size // 2, groups=group_size)self.PWC1 = nn.Conv2d(up_channel // squeeze_radio, op_channel, kernel_size=1, bias=False)# lowself.PWC2 = nn.Conv2d(low_channel // squeeze_radio, op_channel - low_channel // squeeze_radio, kernel_size=1,bias=False)self.advavg = nn.AdaptiveAvgPool2d(1)def forward(self, x):# Splitup, low = torch.split(x, [self.up_channel, self.low_channel], dim=1)up, low = self.squeeze1(up), self.squeeze2(low)# TransformY1 = self.GWC(up) + self.PWC1(up)Y2 = torch.cat([self.PWC2(low), low], dim=1)# Fuseout = torch.cat([Y1, Y2], dim=1)out = F.softmax(self.advavg(out), dim=1) * outout1, out2 = torch.split(out, out.size(1) // 2, dim=1)return out1 + out2class ScConv(nn.Module):def __init__(self,op_channel: int,group_num: int = 4,gate_treshold: float = 0.5,alpha: float = 1 / 2,squeeze_radio: int = 2,group_size: int = 2,group_kernel_size: int = 3,):super().__init__()self.SRU = SRU(op_channel,group_num=group_num,gate_treshold=gate_treshold)self.CRU = CRU(op_channel,alpha=alpha,squeeze_radio=squeeze_radio,group_size=group_size,group_kernel_size=group_kernel_size)def forward(self, x):x = self.SRU(x)x = self.CRU(x)return xif __name__ == '__main__':x = torch.randn(1, 32, 16, 16)model = ScConv(32)print(model(x).shape)
3.2 在SCConv外层套用函数代码
因为以上的代码不能够直接使用在我们的YOLOv8中会报错而且参数对不上,我对其外层嵌套了一个模块。
class SCConv_yolov8(nn.Module):def __init__(self, in_channels, out_channels, kernel_size=1, stride=1, g=1, dilation=1):super().__init__()self.conv = Conv(in_channels, out_channels, k=1)self.RFAConv = ScConv(out_channels)self.bn = nn.BatchNorm2d(out_channels)self.gelu = nn.GELU()def forward(self, x):x = self.conv(x)x = self.RFAConv(x)x = self.gelu(self.bn(x))return x
3.3 修改了SCConv的C2f和Bottleneck模块
class Bottleneck_SCConv(nn.Module):"""Standard bottleneck."""def __init__(self, c1, c2, shortcut=True, g=1, k=(3, 3), e=0.5):"""Initializes a bottleneck module with given input/output channels, shortcut option, group, kernels, andexpansion."""super().__init__()c_ = int(c2 * e) # hidden channelsself.cv1 = Conv(c1, c_, k[0], 1)self.cv2 = SCConv_yolov8(c_, c2, k[1], 1, g=g)self.add = shortcut and c1 == c2def forward(self, x):"""'forward()' applies the YOLO FPN to input data."""return x + self.cv2(self.cv1(x)) if self.add else self.cv2(self.cv1(x))class C2f_SCConv(nn.Module):"""Faster Implementation of CSP Bottleneck with 2 convolutions."""def __init__(self, c1, c2, n=1, shortcut=False, g=1, e=0.5):"""Initialize CSP bottleneck layer with two convolutions with arguments ch_in, ch_out, number, shortcut, groups,expansion."""super().__init__()self.c = int(c2 * e) # hidden channelsself.cv1 = Conv(c1, 2 * self.c, 1, 1)self.cv2 = Conv((2 + n) * self.c, c2, 1) # optional act=FReLU(c2)self.m = nn.ModuleList(Bottleneck_SCConv(self.c, self.c, shortcut, g, k=((3, 3), (3, 3)), e=1.0) for _ in range(n))def forward(self, x):"""Forward pass through C2f layer."""x = self.cv1(x)x = x.chunk(2, 1)y = list(x)# y = list(self.cv1(x).chunk(2, 1))y.extend(m(y[-1]) for m in self.m)return self.cv2(torch.cat(y, 1))def forward_split(self, x):"""Forward pass using split() instead of chunk()."""y = list(self.cv1(x).split((self.c, self.c), 1))y.extend(m(y[-1]) for m in self.m)return self.cv2(torch.cat(y, 1))
四、手把手教你添加SCConv和C2f_SCConv模块
4.1 SCConv的添加教程
添加教程这里不再重复介绍、因为专栏内容有许多,添加过程又需要截特别图片会导致文章大家读者也不通顺如果你已经会添加注意力机制了,可以跳过本章节,如果你还不会,大家可以看我下面的文章,里面详细的介绍了拿到一个任意机制(C2f、Conv、Bottleneck、Loss、DetectHead)如何添加到你的网络结构中去。
这个卷积也可以放在C2f和Bottleneck中进行使用可以即插即用,个人觉得放在Bottleneck中效果比较好。
添加教程->YOLOv8改进 | 如何在网络结构中添加注意力机制、C2f、卷积、Neck、检测头
4.2 SCConv的yaml文件和训练截图
4.2.1 SCConv的yaml文件
下面的配置文件为我修改的SCConv的位置。
# Ultralytics YOLO 🚀, AGPL-3.0 license
# YOLOv8 object detection model with P3-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/detect# Parameters
nc: 80 # number of classes
scales: # model compound scaling constants, i.e. 'model=yolov8n.yaml' will call yolov8.yaml with scale 'n'# [depth, width, max_channels]n: [0.33, 0.25, 1024] # YOLOv8n summary: 225 layers, 3157200 parameters, 3157184 gradients, 8.9 GFLOPss: [0.33, 0.50, 1024] # YOLOv8s summary: 225 layers, 11166560 parameters, 11166544 gradients, 28.8 GFLOPsm: [0.67, 0.75, 768] # YOLOv8m summary: 295 layers, 25902640 parameters, 25902624 gradients, 79.3 GFLOPsl: [1.00, 1.00, 512] # YOLOv8l summary: 365 layers, 43691520 parameters, 43691504 gradients, 165.7 GFLOPsx: [1.00, 1.25, 512] # YOLOv8x summary: 365 layers, 68229648 parameters, 68229632 gradients, 258.5 GFLOPs# YOLOv8.0n backbone
backbone:# [from, repeats, module, args]- [-1, 1, Conv, [64, 3, 2]] # 0-P1/2- [-1, 1, Conv, [128, 3, 2]] # 1-P2/4- [-1, 3, C2f, [128, True]]- [-1, 1, Conv, [256, 3, 2]] # 3-P3/8- [-1, 6, C2f, [256, True]]- [-1, 1, Conv, [512, 3, 2]] # 5-P4/16- [-1, 6, C2f, [512, True]]- [-1, 1, Conv, [1024, 3, 2]] # 7-P5/32- [-1, 3, C2f, [1024, True]]- [-1, 1, SPPF, [1024, 5]] # 9# YOLOv8.0n head
head:- [-1, 1, nn.Upsample, [None, 2, 'nearest']]- [[-1, 6], 1, Concat, [1]] # cat backbone P4- [-1, 3, C2f, [512]] # 12- [-1, 1, nn.Upsample, [None, 2, 'nearest']]- [[-1, 4], 1, Concat, [1]] # cat backbone P3- [-1, 3, C2f_SCConv, [256]] # 15 (P3/8-small)- [-1, 1, Conv, [256, 3, 2]]- [[-1, 12], 1, Concat, [1]] # cat head P4- [-1, 3, C2f_SCConv, [512]] # 18 (P4/16-medium)- [-1, 1, Conv, [512, 3, 2]]- [[-1, 9], 1, Concat, [1]] # cat head P5- [-1, 3, C2f_SCConv, [1024]] # 21 (P5/32-large)- [[15, 18, 21], 1, Detect, [nc]] # Detect(P3, P4, P5)
4.2.2 SCConv的训练过程截图
下面是添加了SCConv的训练截图。
下面的是将SCConv机制添加到了C2f和Bottleneck。
(最近有人说我改的代码是没有发全的,我不知道这群人是怎么说出这种话的,希望大家如果用我的代码成功的可以在评论区支持一下,我也好发更多的改进毕竟免费给大家看。同时有问题皆可在评论区留言我看到都会回复)
五、SCConv可添加的位置
5.1 推荐SCConv可添加的位置
SCConv是一种即插即用的模块,其可以添加的位置有很多,添加的位置不同效果也不同,所以我下面推荐几个添加的位,置大家可以进行参考,当然不一定要按照我推荐的地方添加。
残差连接中:在残差网络的残差连接中加入SCConv
Neck部分:YOLOv8的Neck部分负责特征融合,这里添加修改后的C2f_SCConv可以帮助模型更有效地融合不同层次的特征。
检测头中的卷积:在最终的输出层前加入SCConv可以使模型在做出最终预测之前,更加集中注意力于最关键的特征。
文字大家可能看我描述不太懂,大家可以看下面的网络结构图中我进行了标注。
5.2 图示SCConv可添加的位置
六、本文总结
到此本文的正式分享内容就结束了,在这里给大家推荐我的YOLOv8改进有效涨点专栏,本专栏目前为新开的平均质量分98分,后期我会根据各种最新的前沿顶会进行论文复现,也会对一些老的改进机制进行补充,目前本专栏免费阅读(暂时,大家尽早关注不迷路~),如果大家觉得本文帮助到你了,订阅本专栏,关注后续更多的更新~
专栏回顾:YOLOv8改进系列专栏——本专栏持续复习各种顶会内容——科研必备
相关文章:

YOLOv8改进 | 2023 | SCConv空间和通道重构卷积(精细化检测,又轻量又提点)
一、本文介绍 本文给大家带来的改进内容是SCConv,即空间和通道重构卷积,是一种发布于2023.9月份的一个新的改进机制。它的核心创新在于能够同时处理图像的空间(形状、结构)和通道(色彩、深度)信息…...

Python 全栈体系【四阶】(一)
四阶:机器学习 - 深度学习 第一章 numpy 一、numpy 概述 Numerical Python,数值的 Python,补充了 Python 语言所欠缺的数值计算能力。 Numpy 是其它数据分析及机器学习库的底层库。 Numpy 完全标准 C 语言实现,运行效率充分优…...

Git【成神路】
目录 1.为啥要学git啊?😕😕😕 2.版本控制软件的基本功能 🤞🤞🤞 3.集中式版本控制 🤶🤶🤶 4.分布式版本控制😎😎😎 …...

文件操作详解
文件操作详解 一:文件相关概念1:问什么使用文件2:什么是文件???2.1:程序文件2.2数据文件 二:文件的打开和关闭1:流的定义2:标准流3:文件指针 一&a…...

模块 A:web理论测试
模块 A:理论测试 任务一:单选题 1.为 EMP 表的 namesalary 字段创建名为 emp name salary idx 的校复习接课 name 字段升序, salary 字段降序的复合索引的 SQL 语句是? B A: CREATEINDEX emp name salary idx ON EMP(namesalary) B: …...

git rebase冲突说明(base\remote\local概念说明)
主线日志及修改 $ git log master -p commit 31213fad6150b9899c7e6b27b245aaa69d2fdcff (master) Author: Date: Tue Nov 28 10:19:53 2023 08004diff --git a/123.txt b/123.txt index 294d779..a712711 100644 --- a/123.txtb/123.txt-1,3 1,4 123 4^Mcommit a77b518156…...

函数式接口的妙用,让异步执行更简单
你是否曾经遇到过在SpringBoot中Async注解无法正常工作的问题?今天,我们用函数式接口来解决这个问题。 一、什么是函数式接口? 函数式接口(Functional Interface)是 Java 8 中引入的一个概念,是指只包含一…...

读书笔记:《More Effective C++》
More Effective C Basics reference & pointer reference 必定有值,pointer 可以为空reference 声明时必须定义,必须初始化reference 无需测试有效性,pointer 必须测试是否为 nullreference 可以更改指向对象的值,但是无法…...

手写VUE后台管理系统6 - 支持TS声明文件.d.ts
TS 使用声明文件进行类型定义。 配置 在 tsconfig.json 文件中,找到 include 属性,添加 "src/**/*.d.ts",表示 src 目录下的所有 .d.ts 文件都会被自动加载。 添加后内容如下 "include": ["src/**/*.ts",&…...

第八天:信息打点-系统端口CDN负载均衡防火墙
信息打点-系统篇&端口扫描&CDN服务&负载均衡&WAF防火墙 一、知识点 1、获取网络信息-服务器厂商: 阿里云,腾讯云,机房内部等。 网络架构: 内外网环境。 2、获取服务信息-应用协议-内网资产: FTP…...

一款充电桩解决方案设计
一、基本的概述 项目由IP6536提供两路5V 1.5A 的USB充电口,IP6505提供一路最大24W的USB快充口支持QC3.0 / DCP / QC2.0 / MTK PE1.1 / PE2.0 / FCP / SCP / AFC / SFCP的快充协议,电池充电由type-C输入经过IP2326输出最高15W快充对电池进行充电…...

Leetcode 2953. Count Complete Substrings
Leetcode 2953. Count Complete Substrings 1. 解题思路2. 代码实现 题目链接:2953. Count Complete Substrings 1. 解题思路 这一题麻烦的点就在于说有两个限制条件,但是好的点在于说这两个限制条件事实上是相互独立的。 因此,我们可以通…...

【Python-第三方库-pywin32】随笔- Python通过`pywin32`获取窗口的属性
Python通过pywin32获取窗口的属性 基础 获取所有窗口的句柄 【代码】 import win32guidef get_all_windows():hWnd_list []win32gui.EnumWindows(lambda hWnd, param: param.append(hWnd), hWnd_list)print(hWnd_list)return hWnd_list【结果】 获取窗口的子窗口句柄 【代…...

Flask使用线程异步执行耗时任务
1 问题说明 1.1 任务简述 在开发Flask应用中一定会遇到执行耗时任务,但是Flask是轻量级的同步框架,即在单个请求时服务会阻被塞,直到任务完成(注意:当前请求被阻塞不会影响到其他请求)。 解决异步问题有…...

zabbix监控nginx
zabbix是什么 web界面提供的一种可视化的监控服务软件 以分布式的方式系统监控以及网络监控,硬件监控等等开源的软件 zabbix的架构 1、c/s模式 客户端和服务端,zabbix server服务端 zabbix agent 客户端 2、通过B/S B是浏览器 S服务端,通…...

【CVE-2023-49103】ownCloud graphapi信息泄露漏洞(2023年11月发布)
漏洞简介 ownCloud owncloud/graphapi 0.2.x在0.2.1之前和0.3.x在0.3.1之前存在漏洞。graphapi应用程序依赖于提供URL的第三方GetPhpInfo.php库。当访问此URL时,会显示PHP环境的配置详细信息(phpinfo)。此信息包括Web服务器的所有环境变量&a…...

可视化数据库管理客户端:Adminer
简介:Adminer(前身为phpMinAdmin)是一个用PHP编写的功能齐全的数据库管理工具。与phpMyAdmin相反,它由一个可以部署到目标服务器的文件组成。Adminer可用于MySQL、PostgreSQL、SQLite、MS SQL、Oracle、Firebird、SimpleDB、Elast…...

Python----字典练习
相关链接:Python---字典的增、删、改、查操作_python中字典的增删改查-CSDN博客 Python---字典---dict-CSDN博客 Python---引用变量与可变、非可变类型-CSDN博客 重点: 字典中的 key (就是键)可以是很多数据类型(…...

CentOS 部署 WBO 在线协作白板
1)WBO 白板工具介绍 1.1)WBO 白板简介 WBO 是一个自由和开源的在线协作白板。它允许多个用户同时在一个虚拟的大型白板上画图。该白板对所有线上用户实时更新,并且状态始终保持。它可以用于许多不同的目的,包括艺术、娱乐、设计和…...

qt-C++笔记之QStringList
qt-C笔记之QStringList —— 杭州 2023-12-03 文章目录 qt-C笔记之QStringList1.1.《Qt官方文档》第一部分翻译:继承自QList\<QString\>-初始化-添加字符串1.2.迭代字符串1.3.join()和split()1.4.filter()1.5.lastIndexOf()1.6.indexOf()1.7.replaceInString…...

ply前端
ply 是 eBPF 的 front-end 前端工具之一,专为 embedded Linux systems 开发,采用 C 语言编写,只需 libc 和内核支持 BPF 就可以运行,不需要外部 kernel 模块,不需要 LLVM,不需要 python。 ply 由瑞典工程师…...

U盘不仅能在电脑上使用,在手机上也可使用,包括安卓和苹果手机,但苹果的较特殊
许多最好的安卓手机都使用USB-C端口在电脑上充电和来回传输文件,但如果你需要给老板发电子邮件的文件放在闪存驱动器或全尺寸SD卡上呢? 幸运的是,使用廉价的适配器电缆,你可以将USB加密狗或读卡器直接连接到手机上。你甚至可以直接使用USB-C闪存驱动器,以实现更轻松的过程…...

面试数据库八股文十问十答第二期
面试数据库八股文十问十答第二期 作者:程序员小白条,个人博客 相信看了本文后,对你的面试是有一定帮助的! ⭐点赞⭐收藏⭐不迷路!⭐ 1.MySQL的主从复制 MySQL的主从复制是什么?MySQL主从复制是一种常见的…...

【LeetCode】每日一题 2023_12_2 拼车(模拟/差分)
文章目录 刷题前唠嗑题目:拼车题目描述代码与解题思路学习大佬题解 刷题前唠嗑 LeetCode?启动!!! 题目:拼车 题目链接:1094. 拼车 题目描述 代码与解题思路 func carPooling(trips [][]int…...

网络和Linux网络_7(传输层)UDP和TCP协议(端口号+确认应答+超时重传+三次握手四次挥手)
目录 1. 重看端口号 1.1 端口号的概念 1.2 端口号的划分 2. 重看UDP协议 2.1 UDP协议格式 2.2 UDP的特点 3. 重看TCP协议 3.1 TCP协议格式 3.2 TCP的解包分用 3.3 TCP的可靠性及机制 3.3.1 确认应答ACK机制 3.3.2 超时重传机制 3.3.3 连接管理机制(三次…...

KALI LINUX安全审核
预计更新 第一章 入门 1.1 什么是Kali Linux? 1.2 安装Kali Linux 1.3 Kali Linux桌面环境介绍 1.4 基本命令和工具 第二章 信息收集 1.1 网络扫描 1.2 端口扫描 1.3 漏洞扫描 1.4 社交工程学 第三章 攻击和渗透测试 1.1 密码破解 1.2 暴力破解 1.3 漏洞利用 1.4 …...

2023-12-03-解决libxkbcommon库编译完后图像界面不能使用键盘
layout: post # 使用的布局(不需要改) title: Ubuntu修复 # 标题 subtitle: 解决libxkbcommon库编译完图形界面不能使用键盘 #副标题 date: 2023-12-03 # 时间 author: BY ThreeStones1029 # 作者 header-img: img/about_bg.jpg #这篇文章标题背景图片 c…...

vue el-table表格中每行上传文件(上传简历)操作
1、HTML中 <el-table :data"formInfo.userListDto" border stripe max-height"400"><el-table-column type"index" label"序号" width"50"> </el-table-column><el-table-column prop"realName&q…...

Python批量图像处理--图片重命名、图片旋转
图像批量重命名: 使用batch_rename_images函数实现对多个文件夹下面的图片进行重命名操作 先检查文件名的后缀,使用了.endswith()方法来判断文件名是否以.jpg、.png或.JPG结尾,判断是否为图片文件 然后构造新的文件路径new_filepath&#…...

第五天 用Python批量处理Excel文件,实现自动化办公
用Python批量处理Excel文件,实现自动化办公 一、具体需求 有以下N个表,每个表的结构一样,如下: 需要把所有表数据汇总,把每个人的得分、积分分别加起来,然后按总积分排名,总积分一致时ÿ…...