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

【YOLOv8模型网络结构图理解】

在这里插入图片描述

YOLOv8模型网络结构图理解

  • 1 YOLOv8的yaml配置文件
  • 2 YOLOv8网络结构
    • 2.1 Conv
    • 2.2 C3与C2f
    • 2.3 SPPF
    • 2.4 Upsample
    • 2.5 Detect层

1 YOLOv8的yaml配置文件

YOLOv8的配置文件定义了模型的关键参数和结构,包括类别数、模型尺寸、骨干(backbone)和头部(head)结构。这些配置决定了模型的性能和复杂性。

下面是YOLOv8的配置文件和参数的解释:

# 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  # 类别数目,nc代表"number of classes",即模型用于检测的对象类别总数。 80表示该模型配置用于检测80种不同的对象。由于默认使用COCO数据集,这里nc=80;
scales: # 模型复合缩放常数,用于定义模型的不同尺寸和复杂度。例如 'model=yolov8n.yaml' 将调用带有 'n' 缩放的 yolov8.yaml# [depth, width, max_channels]n: [0.33, 0.25, 1024]  # YOLOv8n概览:225层, 3157200参数, 3157184梯度, 8.9 GFLOPss: [0.33, 0.50, 1024]  # YOLOv8s概览:225层, 11166560参数, 11166544梯度, 28.8 GFLOPsm: [0.67, 0.75, 768]   # YOLOv8m概览:295层, 25902640参数, 25902624梯度, 79.3 GFLOPsl: [1.00, 1.00, 512]   # YOLOv8l概览:365层, 43691520参数, 43691504梯度, 165.7 GFLOPsx: [1.00, 1.25, 512]   # YOLOv8x概览:365层, 68229648参数, 68229632梯度, 258.5 GFLOPs# YOLOv8.0n backbone 骨干层
backbone:# [from, repeats, module, args]- [-1, 1, Conv, [64, 3, 2]]  # 0-P1/2 第0层,-1代表将上层的输出作为本层的输入。第0层的输入是640*640*3的图像。Conv代表卷积层,相应的参数:64代表输出通道数,3代表卷积核大小k,2代表stride步长。卷积后输出的特征图尺寸为320*320*64,长宽为初始图片的1/2- [-1, 1, Conv, [128, 3, 2]]  # 1-P2/4 第1层,本层和上一层是一样的操作(128代表输出通道数,3代表卷积核大小k,2代表stride步长)。卷积后输出的特征图尺寸为160*160*128,长宽为初始图片的1/4- [-1, 3, C2f, [128, True]] # 第2层,本层是C2f模块,3代表本层重复3次。128代表输出通道数,True表示Bottleneck有shortcut。输出的特征图尺寸为160*160*128。- [-1, 1, Conv, [256, 3, 2]]  # 3-P3/8 第3层,进行卷积操作(256代表输出通道数,3代表卷积核大小k,2代表stride步长),输出特征图尺寸为80*80*256(卷积的参数都没变,所以都是长宽变成原来的1/2,和之前一样),特征图的长宽已经变成输入图像的1/8。- [-1, 6, C2f, [256, True]] # 第4层,本层是C2f模块,可以参考第2层的讲解。6代表本层重复6次。256代表输出通道数,True表示Bottleneck有shortcut。经过这层之后,特征图尺寸依旧是80*80*256。- [-1, 1, Conv, [512, 3, 2]]  # 5-P4/16 第5层,进行卷积操作(512代表输出通道数,3代表卷积核大小k,2代表stride步长),输出特征图尺寸为40*40*512(卷积的参数都没变,所以都是长宽变成原来的1/2,和之前一样),特征图的长宽已经变成输入图像的1/16。- [-1, 6, C2f, [512, True]] # 第6层,本层是C2f模块,可以参考第2层的讲解。6代表本层重复6次。512代表输出通道数,True表示Bottleneck有shortcut。经过这层之后,特征图尺寸依旧是40*40*512。- [-1, 1, Conv, [1024, 3, 2]]  # 7-P5/32 第7层,进行卷积操作(1024代表输出通道数,3代表卷积核大小k,2代表stride步长),输出特征图尺寸为20*20*1024(卷积的参数都没变,所以都是长宽变成原来的1/2,和之前一样),特征图的长宽已经变成输入图像的1/32。- [-1, 3, C2f, [1024, True]] #第8层,本层是C2f模块,可以参考第2层的讲解。3代表本层重复3次。1024代表输出通道数,True表示Bottleneck有shortcut。经过这层之后,特征图尺寸依旧是20*20*1024。- [-1, 1, SPPF, [1024, 5]]  # 9 第9层,本层是快速空间金字塔池化层(SPPF)。1024代表输出通道数,5代表池化核大小k。结合模块结构图和代码可以看出,最后concat得到的特征图尺寸是20*20*(512*4),经过一次Conv得到20*20*1024。# YOLOv8.0n head 头部层
head:- [-1, 1, nn.Upsample, [None, 2, 'nearest']] # 第10层,本层是上采样层。-1代表将上层的输出作为本层的输入。None代表上采样的size=None(输出尺寸)不指定。2代表scale_factor=2,表示输出的尺寸是输入尺寸的2倍。mode=nearest代表使用的上采样算法为最近邻插值算法。经过这层之后,特征图的长和宽变成原来的两倍,通道数不变,所以最终尺寸为40*40*1024。- [[-1, 6], 1, Concat, [1]]  # cat backbone P4 第11层,本层是concat层,[-1, 6]代表将上层和第6层的输出作为本层的输入。[1]代表concat拼接的维度是1。从上面的分析可知,上层的输出尺寸是40*40*1024,第6层的输出是40*40*512,最终本层的输出尺寸为40*40*1536。- [-1, 3, C2f, [512]]  # 12 第12层,本层是C2f模块,可以参考第2层的讲解。3代表本层重复3次。512代表输出通道数。与Backbone中C2f不同的是,此处的C2f的bottleneck模块的shortcut=False。- [-1, 1, nn.Upsample, [None, 2, 'nearest']] # 第13层,本层也是上采样层(参考第10层)。经过这层之后,特征图的长和宽变成原来的两倍,通道数不变,所以最终尺寸为80*80*512。- [[-1, 4], 1, Concat, [1]]  # cat backbone P3 第14层,本层是concat层,[-1, 4]代表将上层和第4层的输出作为本层的输入。[1]代表concat拼接的维度是1。从上面的分析可知,上层的输出尺寸是80*80*512,第6层的输出是80*80*256,最终本层的输出尺寸为80*80*768。- [-1, 3, C2f, [256]]  # 15 (P3/8-small) 第15层,本层是C2f模块,可以参考第2层的讲解。3代表本层重复3次。256代表输出通道数。经过这层之后,特征图尺寸变为80*80*256,特征图的长宽已经变成输入图像的1/8。- [-1, 1, Conv, [256, 3, 2]] # 第16层,进行卷积操作(256代表输出通道数,3代表卷积核大小k,2代表stride步长),输出特征图尺寸为40*40*256(卷积的参数都没变,所以都是长宽变成原来的1/2,和之前一样)。- [[-1, 12], 1, Concat, [1]]  # cat head P4 第17层,本层是concat层,[-1, 12]代表将上层和第12层的输出作为本层的输入。[1]代表concat拼接的维度是1。从上面的分析可知,上层的输出尺寸是40*40*256,第12层的输出是40*40*512,最终本层的输出尺寸为40*40*768。- [-1, 3, C2f, [512]]  # 18 (P4/16-medium) 第18层,本层是C2f模块,可以参考第2层的讲解。3代表本层重复3次。512代表输出通道数。经过这层之后,特征图尺寸变为40*40*512,特征图的长宽已经变成输入图像的1/16。- [-1, 1, Conv, [512, 3, 2]] # 第19层,进行卷积操作(512代表输出通道数,3代表卷积核大小k,2代表stride步长),输出特征图尺寸为20*20*512(卷积的参数都没变,所以都是长宽变成原来的1/2,和之前一样)。- [[-1, 9], 1, Concat, [1]]  # cat head P5 第20层,本层是concat层,[-1, 9]代表将上层和第9层的输出作为本层的输入。[1]代表concat拼接的维度是1。从上面的分析可知,上层的输出尺寸是20*20*512,第9层的输出是20*20*1024,最终本层的输出尺寸为20*20*1536。- [-1, 3, C2f, [1024]]  # 21 (P5/32-large) 第21层,本层是C2f模块,可以参考第2层的讲解。3代表本层重复3次。1024代表输出通道数。经过这层之后,特征图尺寸变为20*20*1024,特征图的长宽已经变成输入图像的1/32。- [[15, 18, 21], 1, Detect, [nc]]  # Detect(P3, P4, P5) 第20层,本层是Detect层,[15, 18, 21]代表将第15、18、21层的输出(分别是80*80*256、40*40*512、20*20*1024)作为本层的输入。nc是数据集的类别数。
1. nc
含义: nc代表"number of classes",即模型用于检测的对象类别总数。
示例中的值: 80表示该模型配置用于检测80种不同的对象。由于默认使用COCO数据集,这里nc=80;2. scales
含义: scales用于定义模型的不同尺寸和复杂度,它包含一系列缩放参数。
子参数: n, s, m, l, x表示不同的模型尺寸,每个尺寸都有对应的depth(深度)、width(宽度)和max_channels(最大通道数)。
depth: 表示深度因子,用来控制一些特定模块的数量的,模块数量多网络深度就深;
width: 表示宽度因子,用来控制整个网络结构的通道数量,通道数量越多,网络就看上去更胖更宽;
max_channels: 最大通道数,为了动态地调整网络的复杂性。在 YOLO 的早期版本中,网络中的每个层都是固定的,这意味着每个层的通道数也是固定的。但在 YOLOv8 中,为了增加网络的灵活性并使其能够更好地适应不同的任务和数据集,引入了 max_channels 参数。3. backbone
主干网络是模型的基础,负责从输入图像中提取特征。这些特征是后续网络层进行目标检测的基础。在YOLOv8中,主干网络采用了类似于CSPDarknet的结构。
含义: backbone部分定义了模型的基础架构,即用于特征提取的网络结构。
关键组成:
[from, repeats, module, args]表示层的来源、重复次数、模块类型和参数。
from:表示该模块的输入来源,如果为-1则表示来自于上一个模块的输出,如果为其他具体的值则表示从特定的模块中得到输入信息;
repeats: 这个参数用于指定一个模块或层应该重复的次数。例如,如果想让某个卷积层重复三次,你可以使用 repeats=3。
module: 这个参数用于指定要添加的模块或层的类型。例如,如果想添加一个卷积层,可以使用 conv 作为模块类型。
args: 这个参数用于传递给模块或层的特定参数。例如,如果想指定卷积层的滤波器数量,可以使用 args=[filters]。
Conv表示卷积层,其参数指定了输出通道数、卷积核大小和步长。
C2f可能是一个特定于YOLOv8的自定义模块。
SPPF是空间金字塔池化层,用于在多个尺度上聚合特征。4. head
含义: head部分定义了模型的检测头,即用于最终目标检测的网络结构。
关键组成:
nn.Upsample表示上采样层,增加特征图的空间分辨率,用于放大特征图。
Concat表示连接层,特征图拼接,用于合并来自不同层的特征。
C2f层再次出现,可能用于进一步处理合并后的特征。
Detect层是最终的检测层,负责输出检测结果。

2 YOLOv8网络结构

在这里插入图片描述

Backbone主干网络是模型的基础,负责从输入图像中提取特征。这些特征是后续网络层进行目标检测的基础。 在YOLOv8中,主干网络采用了类似于CSPDarknet的结构。

Head头部网络是目标检测模型的决策部分,负责产生最终的检测结果。

Neck颈部网络位于主干网络和头部网络之间,它的作用是进行特征融合和增强。

其他细节:

  • ConvModule:包含卷积层(Conv)、批量归一化(BN)和激活函数(如SiLU),即CBS模块,用于提取特征。
  • DarknetBottleneck:通过residual connections增加网络深度,同时保持效率。
  • CSP Layer:CSP结构的变体,通过部分连接来提高模型的训练效率

输出的特征图大小计算公式:f_out = ((f_in - k + 2*p ) / s ) 向下取整 +1

Bbox Loss(边界框回归损失)用于计算预测边界框与真实边界框之间的差异。均方误差(MSE)是一个常用的损失函数,它在较大误差时赋予更高的惩罚,这有助于模型快速修正大的预测错误。因此,Bbox Loss计算预测与实际坐标之间的差异的平方和,其计算公式如下:
L o s s b b o x = ∑ i = 1 N ( x i − x ^ i ) 2 Loss_{bbox}=\sum_{i=1}^N{(x_i-\hat{x}_i)^2} Lossbbox=i=1N(xix^i)2
其中, x i {x}_i xi表示真实边界框的坐标, x ^ i \hat{x}_i x^i表示预测边界框的坐标。该损失函数作为优化目标,引导模型在训练过程中减少预测框和真实框之间的差距。

Cls Loss(分类损失)用于衡量模型预测的类别分布与真实标签之间的差异。交叉熵损失函数是分类任务中常用的一种损失函数,对于错误预测给出了很大的惩罚,尤其是在预测的概率和实际标签相差很大时。因此,Cls Loss帮助模型在分类问题中优化其预测,使预测概率分布尽可能接近真实的标签分布,其计算公式为:
L o s s c l s = − ∑ c = 1 M y o , c l o g ( p o , c ) Loss_{cls}=-\sum_{c=1}^My_{o,c}log(p_o,c) Losscls=c=1Myo,clog(po,c)
其中, y o , c y_{o,c} yo,c是一个指示器。如果样本o属于类别c,则为1,反之为0。 p o p_o po是模型预测样本o属于类别c的概率。

2.1 Conv


def autopad(k, p=None, d=1):  # kernel, padding, dilation# Pad to 'same' shape outputsif d > 1:k = d * (k - 1) + 1 if isinstance(k, int) else [d * (x - 1) + 1 for x in k]  # actual kernel-sizeif p is None:p = k // 2 if isinstance(k, int) else [x // 2 for x in k]  # auto-padreturn pclass Conv(nn.Module):# Standard convolution with args(ch_in, ch_out, kernel, stride, padding, groups, dilation, activation)default_act = nn.SiLU()  # default activationdef __init__(self, c1, c2, k=1, s=1, p=None, g=1, d=1, act=True):super().__init__()self.conv = nn.Conv2d(c1, c2, k, s, autopad(k, p, d), groups=g, dilation=d, bias=False)self.bn = nn.BatchNorm2d(c2)self.act = self.default_act 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)))def forward_fuse(self, x):return self.act(self.conv(x))

2.2 C3与C2f

在这里插入图片描述

# 整个过程就是cv1接上了n个bottleneck模块再与cv2进行concat操作,最后在进行一次cv3的Conv。所以经过了C3模块,输出特征图尺寸是h*w*cout
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().__init__()c_ = int(c2 * e)  # hidden channelsself.cv1 = Conv(c1, c_, 1, 1) #上图最左边的CBS模块self.cv2 = Conv(c1, c_, 1, 1) #上图中间的CBS模块self.cv3 = Conv(2 * c_, c2, 1)  # optional act=FReLU(c2) 上图最右边的CBS模块self.m = nn.Sequential(*(Bottleneck(c_, c_, shortcut, g, k=((1, 1), (3, 3)), e=1.0) for _ in range(n))) # 接上了n个Bottleneck模块def forward(self, x):return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), 1))

对比C3模块和C2f模块,可以看到C2f获得了更多的梯度流信息(参考了YOLOv7的ELAN模块的思想):

在这里插入图片描述

class C2f(nn.Module):# CSP Bottleneck with 2 convolutionsdef __init__(self, c1, c2, n=1, shortcut=False, g=1, e=0.5):  # ch_in, ch_out, number, shortcut, groups, expansionsuper().__init__()self.c = int(c2 * e)  # hidden channelsself.cv1 = Conv(c1, 2 * self.c, 1, 1) # 最左边的CBS模块self.cv2 = Conv((2 + n) * self.c, c2, 1)  # optional act=FReLU(c2) 最右边的CBS模块self.m = nn.ModuleList(Bottleneck(self.c, self.c, shortcut, g, k=((3, 3), (3, 3)), e=1.0) for _ in range(n)) # 接上了n个Bottleneck模块def forward(self, x):# tensor.chunk(chunk数,维度)y = list(self.cv1(x).chunk(2, 1)) #先将输入特征图cv1卷积,然后chunk分2块y.extend(m(y[-1]) for m in self.m) #表示被切分的最后一块,即第二块,把第二块放进n个连续的Bottleneck里,加到y列表的尾部,y就变成了2+n块return self.cv2(torch.cat(y, 1)) #将y按第一维度拼接在一起,然后进行cv2卷积操作。def forward_split(self, x):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))class Bottleneck(nn.Module):# Standard bottleneckdef __init__(self, c1, c2, shortcut=True, g=1, k=(3, 3), e=0.5):  # ch_in, ch_out, shortcut, groups, kernels, expandsuper().__init__()c_ = int(c2 * e)  # hidden channelsself.cv1 = Conv(c1, c_, k[0], 1)self.cv2 = Conv(c_, c2, k[1], 1, g=g)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.3 SPPF

class SPPF(nn.Module):# Spatial Pyramid Pooling - Fast (SPPF) layer for YOLOv5 by Glenn Jocherdef __init__(self, c1, c2, k=5):  # equivalent to SPP(k=(5, 9, 13))super().__init__()c_ = c1 // 2  # hidden channelsself.cv1 = Conv(c1, c_, 1, 1)self.cv2 = Conv(c_ * 4, c2, 1, 1)self.m = nn.MaxPool2d(kernel_size=k, stride=1, padding=k // 2)def forward(self, x):x = self.cv1(x)y1 = self.m(x)y2 = self.m(y1)return self.cv2(torch.cat((x, y1, y2, self.m(y2)), 1))

2.4 Upsample

torch.nn.Upsample(size=None, scale_factor=None, mode='nearest', align_corners=None)

2.5 Detect层

class Detect(nn.Module):# YOLOv8 Detect head for detection modelsdynamic = False  # force grid reconstructionexport = False  # export modeshape = Noneanchors = torch.empty(0)  # initstrides = torch.empty(0)  # initdef __init__(self, nc=80, ch=()):  # detection layersuper().__init__()self.nc = nc  # number of classesself.nl = len(ch)  # number of detection layersself.reg_max = 16  # DFL channels (ch[0] // 16 to scale 4/8/12/16/20 for n/s/m/l/x)self.no = nc + self.reg_max * 4  # number of outputs per anchorself.stride = torch.zeros(self.nl)  # strides computed during buildc2, c3 = max((16, ch[0] // 4, self.reg_max * 4)), max(ch[0], self.nc)  # channelsself.cv2 = nn.ModuleList(nn.Sequential(Conv(x, c2, 3), Conv(c2, c2, 3), nn.Conv2d(c2, 4 * self.reg_max, 1)) for x in ch)self.cv3 = nn.ModuleList(nn.Sequential(Conv(x, c3, 3), Conv(c3, c3, 3), nn.Conv2d(c3, self.nc, 1)) for x in ch)self.dfl = DFL(self.reg_max) if self.reg_max > 1 else nn.Identity()def forward(self, x):shape = x[0].shape  # BCHWfor i in range(self.nl):x[i] = torch.cat((self.cv2[i](x[i]), self.cv3[i](x[i])), 1)if self.training:return xelif self.dynamic or self.shape != shape:self.anchors, self.strides = (x.transpose(0, 1) for x in make_anchors(x, self.stride, 0.5))self.shape = shapeif self.export and self.format == 'edgetpu':  # FlexSplitV ops issuex_cat = torch.cat([xi.view(shape[0], self.no, -1) for xi in x], 2)box = x_cat[:, :self.reg_max * 4]cls = x_cat[:, self.reg_max * 4:]else:box, cls = torch.cat([xi.view(shape[0], self.no, -1) for xi in x], 2).split((self.reg_max * 4, self.nc), 1)dbox = dist2bbox(self.dfl(box), self.anchors.unsqueeze(0), xywh=True, dim=1) * self.stridesy = torch.cat((dbox, cls.sigmoid()), 1)return y if self.export else (y, x)def bias_init(self):# Initialize Detect() biases, WARNING: requires stride availabilitym = self  # self.model[-1]  # Detect() module# cf = torch.bincount(torch.tensor(np.concatenate(dataset.labels, 0)[:, 0]).long(), minlength=nc) + 1# ncf = math.log(0.6 / (m.nc - 0.999999)) if cf is None else torch.log(cf / cf.sum())  # nominal class frequencyfor a, b, s in zip(m.cv2, m.cv3, m.stride):  # froma[-1].bias.data[:] = 1.0  # boxb[-1].bias.data[:m.nc] = math.log(5 / m.nc / (640 / s) ** 2)  # cls (.01 objects, 80 classes, 640 img)class DFL(nn.Module):# Integral module of Distribution Focal Loss (DFL) proposed in Generalized Focal Loss https://ieeexplore.ieee.org/document/9792391def __init__(self, c1=16):super().__init__()self.conv = nn.Conv2d(c1, 1, 1, bias=False).requires_grad_(False)x = torch.arange(c1, dtype=torch.float)self.conv.weight.data[:] = nn.Parameter(x.view(1, c1, 1, 1))self.c1 = c1def forward(self, x):b, c, a = x.shape  # batch, channels, anchorsreturn self.conv(x.view(b, 4, self.c1, a).transpose(2, 1).softmax(1)).view(b, 4, a)# return self.conv(x.view(b, self.c1, 4, a).softmax(1)).view(b, 4, a)

相关文章:

【YOLOv8模型网络结构图理解】

YOLOv8模型网络结构图理解 1 YOLOv8的yaml配置文件2 YOLOv8网络结构2.1 Conv2.2 C3与C2f2.3 SPPF2.4 Upsample2.5 Detect层 1 YOLOv8的yaml配置文件 YOLOv8的配置文件定义了模型的关键参数和结构,包括类别数、模型尺寸、骨干(backbone)和头部…...

使用 commitlint 和 husky 检查提交描述是否符合规范要求

在上一小节中,我们了解了 Git hooks 的概念,那么接下来我们就使用 Git hooks 来去校验我们的提交信息。 要完成这么个目标,那么我们需要使用两个工具: 注意:npm 需要在 7.x 以上版本。 1. commitlint 用于检查提交信…...

QT集成IntelRealSense双目摄像头3,3D显示

前两篇文章,介绍了如何继承intel realsense相机和opengl。 这里介绍如何给深度数据和色彩数据一块显示到opengl里面。 首先,需要了解深度数据和彩色数据是如何存储的。先说彩色数据。彩色图像一般都是RGB,也就是每个像素有三个字节&#xf…...

Vue 中el-table-column 进行循环,页面没渲染成功

文章目录 前言效果图代码示例可能出现的问题及原因解决思路 前言 实现效果:el-table-column 进行循环,使之代码简化 遇到的问题: data进行默认赋值,操作列的删除都可以出来,其他表格里面的数据没出来 效果图 示例&am…...

渗透测试-非寻常漏洞案例

声明 本文章所分享内容仅用于网络安全技术讨论,切勿用于违法途径,所有渗透都需获取授权,违者后果自行承担,与本号及作者无关,请谨记守法. 此文章不允许未经授权转发至除先知社区以外的其它平台!&#xff0…...

Spring Boot 实战篇(四):实现用户登录与注册功能

目录 Spring Boot 实战篇(四):实现用户登录与注册功能 一、用户注册功能 (一)前端页面设计(简要提及) (二)后端实现 二、用户登录功能 (一)…...

VScode SSH 错误:Got bad result from install script 解決

之前vscode好好的,某天突然连接报错如下 尝试1. 服务器没有断开,ssh可以正常连接 2. 用管理员权限运行vscode,无效 3. 删除服务器上的~/.vscode-server 文件夹,无效 试过很多后,原来很可能是前一天anaconda卸载导致注册表项 步…...

openGauss与GaussDB系统架构对比

openGauss与GaussDB系统架构对比 系统架构对比openGauss架构GaussDB架构 GaussDB集群管理组件 系统架构对比 openGauss架构 openGauss是集中式数据库系统,业务数据存储在单个物理节点上,数据访问任务被推送到服务节点执行,通过服务器的高并…...

【ArcGISPro/GeoScenePro】检查并处理高程数据

数据 https://arcgis.com/sharing/rest/content/items/535efce0e3a04c8790ed7cc7ea96d02d/data 数字高程模型 (DEM) 是一种栅格,可显示地面或地形的高程。 数字表面模型 (DSM) 是另一种高程栅格,可显示表面的高度,例如建筑物或树冠的顶部。 您需要准备 DEM 和 DSM 以供分析…...

WebRTC的三大线程

WebRTC中的三个主要线程: signaling_thread,信号线程:用于与应用层交互worker_thread,工作线程(最核心):负责内部逻辑处理network_thread,网络线程:负责网络数据包的收发…...

HTML-文本标签

历史上&#xff0c;网页的主要功能是文本展示。所以&#xff0c;HTML 提供了大量的文本处理标签。 1.<div> <div>是一个通用标签&#xff0c;表示一个区块&#xff08;division&#xff09;。它没有语义&#xff0c;如果网页需要一个块级元素容器&#xff0c;又没…...

C# 在PDF中添加和删除水印注释 (Watermark Annotation)

目录 使用工具 C# 在PDF文档中添加水印注释 C# 在PDF文档中删除水印注释 PDF中的水印注释是一种独特的注释类型&#xff0c;它通常以透明的文本或图片形式叠加在页面内容之上&#xff0c;为文档添加标识或信息提示。与传统的静态水印不同&#xff0c;水印注释并不会永久嵌入…...

Unity2022接入Google广告与支付SDK、导出工程到Android Studio使用JDK17进行打包完整流程与过程中的相关错误及处理经验总结

注&#xff1a;因为本人也是第一次接入广告与支付SDK相关的操作&#xff0c;网上也查了很多教程&#xff0c;很多也都是只言片语或者缺少一些关键步骤的说明&#xff0c;导致本人也是花了很多时间与精力踩了很多的坑才搞定&#xff0c;发出来也是希望能帮助到其他人在遇到相似问…...

docker部署项目

docker部署项目 &#xff08;加载tar包&#xff1a;docker image load -i mysql.tar&#xff09; 一、jdk环境配置 1.jdk下载地址 --Java Archive | Oracle 中国 --选择好版本进入 --下载Linux x64 Compressed Archive的链接 2.解压 --创建文件夹&#xff1a;mkdir /ro…...

C# 设计模式(创建型模式):工厂模式

C# 设计模式&#xff08;创建型模式&#xff09;&#xff1a;工厂模式 引言 在软件设计中&#xff0c;创建型模式是用来创建对象的设计模式&#xff0c;它们帮助我们将对象的创建过程从业务逻辑中分离出来&#xff0c;减少代码的重复性和耦合度。工厂模式作为创建型设计模式之…...

REMARK-LLM:用于生成大型语言模型的稳健且高效的水印框架

REMARK-LLM:用于生成大型语言模型的稳健且高效的水印框架 前言 提出这一模型的初衷为了应对大量计算资源和数据集出现伴随的知识产权问题。使用LLM合成类似人类的内容容易受到恶意利用,包括垃圾邮件和抄袭。 ChatGPT等大语言模型LLM的开发取得的进展标志着人机对话交互的范式…...

Lumos学习王佩丰Excel第二十三讲:Excel图表与PPT

一、双坐标柱形图的补充知识 1、主次坐标设置 2、主次坐标柱形避让&#xff08;通过增加两个系列&#xff0c;挤压使得两个柱形挨在一起&#xff09; 增加两个系列 将一个系列设置成主坐标轴&#xff0c;另一个设成次坐标轴 调整系列位置 二、饼图美化 1、饼图美化常见设置 …...

【Vue】v-if 和 :is 都是 Vue 中的指令,但它们用于不同的目的和场景

v-if v-if 是一个条件渲染指令&#xff0c;用于根据表达式的真假值来决定是否渲染一块内容。当 v-if 的表达式为真&#xff08;truthy&#xff09;时&#xff0c;Vue 会确保元素被渲染到 DOM 中&#xff1b;当表达式为假&#xff08;falsy&#xff09;时&#xff0c;元素不会被…...

private static final Logger log = LoggerFactory.getLogger()和@Slf4j的区别

一、代码方面 - private static final Logger log LoggerFactory.getLogger()方式 详细解释 这是一种传统的获取日志记录器&#xff08;Logger&#xff09;的方式。LoggerFactory是日志框架&#xff08;如 Log4j、Logback 等&#xff09;提供的工厂类&#xff0c;用于创建Lo…...

【项目】基于趋动云平台的Stable Diffusion开发

【项目】基于趋动云平台的Stable Diffusion开发 &#xff08;一&#xff09;登录趋动云&#xff08;二&#xff09;创建项目&#xff1a;&#xff08;三&#xff09;初始化开发环境&#xff1a;&#xff08;四&#xff09;运行代码&#xff08;五&#xff09;运行模型 &#xf…...

Git的.gitignore文件详解与常见用法

诸神缄默不语-个人CSDN博文目录 在日常使用 Git 进行版本控制时&#xff0c;我们经常会遇到一些不需要被提交到远程仓库的文件&#xff08;例如日志文件、临时配置文件、环境变量文件等&#xff09;。为了忽略这些文件的提交&#xff0c;Git 提供了一个非常有用的功能&#xf…...

客户端二维码优化居中和背景

原始 处理后...

Linux 安装运行gatk的教程

1.下载安装 wget https://github.com/broadinstitute/gatk/releases/download/4.1.8.1/gatk-4.1.8.1.zip2.解压 unzip *.zip3.查看 gatk --help 如下显示表示安装成功&#xff1a; 注意&#xff1a;仅限在该包所在位置的路径下能使用...

C++string类

1.为什么学习string类&#xff1f; 1.1C语言中的字符串 C语言中&#xff0c;字符串是以‘&#xff3c;0’结尾的一些字符的集合&#xff0c;为了操作方便&#xff0c;C标准库中提供了一些str系列的库函数&#xff0c;但是这些库函数与字符串是分离开的&#xff0c;不太符合OO…...

下载linux aarch64版本的htop

htop代码网站似乎没有编译好的各平台的包&#xff0c;而自己编译需要下载一些工具&#xff0c;比较麻烦。这里找到了快速下载和使用的方法&#xff0c;记录一下。 先在linux电脑上执行&#xff1a; mkdir htop_exe cd htop_exe apt download htop:arm64 # 会直接下载到当前目…...

MYSQL---------支持数据类型

数值类型 整数类型 TINYINT&#xff1a;通常用于存储小范围的整数&#xff0c;范围是-128到127或0到255&#xff08;无符号&#xff09;。例如&#xff0c;存储年龄可以使用TINYINT类型。示例&#xff1a;CREATE TABLE users (age TINYINT);SMALLINT&#xff1a;范围比TINYINT…...

黑马JavaWeb开发跟学(十四).SpringBootWeb原理

黑马JavaWeb开发跟学 十四.SpringBootWeb原理 SpingBoot原理1. 配置优先级2. Bean管理2.1 获取Bean2.2 Bean作用域2.3 第三方Bean 3. SpringBoot原理3.1 起步依赖3.2 自动配置3.2.1 概述3.2.2 常见方案3.2.2.1 概述3.2.2.2 方案一3.2.2.3 方案二 3.2.3 原理分析3.2.3.1 源码跟踪…...

迅为RK3568开发板编译Android12源码包-设置屏幕配置

在源码编译之前首先要确定自己想要使用的屏幕并修改源码&#xff0c;在编译镜像&#xff0c;烧写镜像。如下图所示&#xff1a; 第一步&#xff1a;确定要使用的屏幕种类&#xff0c;屏幕种类选择如下所示&#xff1a; iTOP-3568 开发板支持以下种类屏幕&#xff1a; 迅为 LV…...

Spring Boot 中 TypeExcludeFilter 的作用及使用示例

在Spring Boot应用程序中&#xff0c;TypeExcludeFilter 是一个用于过滤特定类型的组件&#xff0c;使之不被Spring容器自动扫描和注册为bean的工具。这在你想要排除某些类或类型&#xff08;如配置类、组件等&#xff09;而不希望它们参与Spring的自动装配时非常有用。 作用 …...

Prometheus 采集 JVM 数据

Prometheus 采集 JVM 数据通常通过集成 JMX Exporter&#xff08;Java Management Extensions Exporter&#xff09;实现。以下是完整的介绍和操作步骤&#xff1a; 1. 原理概述 JVM 数据采集依赖于 JMX&#xff08;Java Management Extensions&#xff09;&#xff0c;JVM 提…...

OpenNJet v3.2.0正式发布!

在这个版本中&#xff0c;NJet实现重大突破&#xff0c;提供了动态Upstream的能力。这是一个关键的特性&#xff0c;使得NJet可以按需动态管理上游服务器池&#xff0c;从而使得业务方可以按需配置资源池&#xff0c;实现业务分区、算法切换&#xff1b;结合动态路由技术&#…...

TinaCMS: 革命性的开源内容管理框架

在如今的数字时代&#xff0c;高效的内容管理系统&#xff08;CMS&#xff09;已成为构建内容丰富网站和应用程序的必需品。传统 CMS&#xff0c;如 WordPress 和 Drupal&#xff0c;功能丰富但复杂度高。而新一代 CMS&#xff0c;例如 TinaCMS&#xff0c;以其灵活性和开发者友…...

VuePress2配置unocss的闭坑指南

文章目录 1. 安装依赖&#xff1a;准备魔法材料2. 检查依赖版本一定要一致&#xff1a;确保魔法配方准确无误3. 新建uno.config.js&#xff1a;编写咒语书4. 配置config.js和client.js&#xff1a;完成仪式 1. 安装依赖&#xff1a;准备魔法材料 在开始我们的前端魔法之前&…...

SpringCloud(二)--SpringCloud服务注册与发现

一. 引言 ​ 前文简单介绍了SpringCloud的基本简介与特征&#xff0c;接下来介绍每个组成部分的功能以及经常使用的中间件。本文仅为学习所用&#xff0c;联系侵删。 二. SpringCloud概述 2.1 定义 ​ Spring Cloud是一系列框架的有序集合&#xff0c;它巧妙地利用了Spring…...

JavaVue-Get请求 数组参数(qs格式化前端数据)

前言 现在管理系统&#xff0c;像若依&#xff0c;表格查询一般会用Get请求&#xff0c;把页面的查询条件传递给后台。其中大部分页面会有日期时间范围查询这时候&#xff0c;为了解决请求参数中的数组文件&#xff0c;前台就会在请求前拦截参数中的日期数组数据&#xff0c;然…...

Java-多种方法实现多线程卖票

Java多线程卖票是一个经典的并发编程问题,它展示了如何在多个线程之间安全地共享和修改资 源。以下是几种实现方式: 使用synchronized关键字: 使用synchronized修饰符来同步方法或代码块,确保同一时刻只有一个线程可以访问临界区(即操 作共享资源的代码)。 使用Reen…...

LLVM防忘录

目录 Windows中源码编译LLVMWindows下编译LLVM Pass DLL Windows中源码编译LLVM 直接从llvm-project下载源码, 然后解压后用VS2022打开该目录, 然后利用VS的开发终端执行: cmake -S llvm -B build -G "Visual Studio 17 2022" -DLLVM_ENABLE_PROJECTSclang -DLLVM_…...

Elasticsearch:基础概念

一、什么是Elasticsearch Elasticsearch是基于 Apache Lucene 构建的分布式搜索和分析引擎、可扩展数据存储和矢量数据库。它针对生产规模工作负载的速度和相关性进行了优化。使用 Elasticsearch 可以近乎实时地搜索、索引、存储和分析各种形状和大小的数据。Elasticsearch 是…...

【快速实践】类激活图(CAM,class activation map)可视化

类激活图可视化&#xff1a;有助于了解一张图像的哪一部分让卷积神经网络做出了最终的分类决策 对输入图像生成类激活热力图类激活热力图是与特定输出类别相关的二维分数网格&#xff1a;对任何输入图像的每个位置都要进行计算&#xff0c;它表示每个位置对该类别的重要程度 我…...

从零开始自搭SpringBoot项目 -- Qingluopay项目工程介绍

从零开始自搭项目 – QingLuoPay 一&#xff0c;为什么要从零开始自搭项目 首先在介绍这个项目之前先介绍一下我为什么要选择从零自搭项目&#xff0c;而不是跟着网上哪些视频等做项目。 之前的很长一段时间我也都是在网上找一些做项目的视频就包含黑马的&#xff08;神领物…...

使用 Jupyter Notebook:安装与应用指南

文章目录 安装 Jupyter Notebook1. 准备环境2. 安装 Jupyter Notebook3. 启动 Jupyter Notebook4. 选择安装方式&#xff08;可选&#xff09; 二、Jupyter Notebook 的基本功能1. 单元格的类型与运行2. 可视化支持3. 内置魔法命令 三、Jupyter Notebook 的实际应用场景1. 数据…...

.NET框架用C#实现PDF转HTML

HTML作为一种开放标准的网页标记语言&#xff0c;具有跨平台、易于浏览和搜索引擎友好的特性&#xff0c;使得内容能够在多种设备上轻松访问并优化了在线分享与互动。通过将PDF文件转换为HTML格式&#xff0c;我们可以更方便地在浏览器中展示PDF文档内容&#xff0c;同时也更容…...

使用 httputils + chronicle-bytes 实现金融级 java rpc

1、认识 chronicle-bytes Chronicle-Bytes 是一个类似于 Java NIO 的 ByteBuffer 的高效字节操作库&#xff0c;但它提供了许多扩展功能。这个项目由 OpenHFT 开发并维护&#xff0c;旨在提供高性能、低延迟的数据处理解决方案。Chronicle-Bytes 设计用于高频率交易和其他对性…...

开源模型应用落地-Qwen2.5-7B-Instruct与vllm实现推理加速的正确姿势-利用KOR框架实现结构化输出(七)

一、前言 目前,大语言模型已升级至Qwen2.5版本。无论是语言模型还是多模态模型,均在大规模多语言和多模态数据上进行预训练,并通过高质量数据进行后期微调以贴近人类偏好。在本篇学习中,将集成vllm实现模型推理加速,现在,我们赶紧跟上技术发展的脚步,去体验一下新版本模…...

利用大语言模型解决推理任务

利用大语言模型&#xff08;Large Language Models, LLMs&#xff09;来解决推理任务是目前人工智能领域中的一个重要研究方向。大语言模型&#xff0c;如GPT系列&#xff08;包括ChatGPT&#xff09;和BERT等&#xff0c;具有强大的自然语言理解和生成能力&#xff0c;已经能够…...

修复OpenLinkSaas客户端在使用AtomGit账号时页面崩溃

问题描述&#xff1a;当一个新的AtomGit用户登录OpenLinkSaas客户端后出现了页面崩溃。 从浏览器控制台来看&#xff0c;是gitNoticeList出现了null。 查看代码后发现是请求atomGit api是返回的一个null的列表 接下来我们加下保护性的代码&#xff0c;来兼容null或undefine的情…...

如何使用大语言模型进行事件抽取与关系抽取

诸神缄默不语-个人CSDN博文目录 文章目录 1. 什么是事件抽取与关系抽取&#xff1f;2. 示例&#xff1a;使用大语言模型进行事件抽取与关系抽取 1. 什么是事件抽取与关系抽取&#xff1f; 事件抽取是指从文本中识别出与某些“事件”相关的信息。这些事件通常包括动作、参与者、…...

WebRTC线程的启动与运行

WebRTC线程运行的基本逻辑&#xff1a; while(true) {…Get(&msg, …);…Dispatch(&msg);… }Dispatch(Message *pmsg) {…pmsg->handler->OnMessage(pmsg);… }在执行函数内部&#xff0c;就是一个while死循环&#xff0c;只做两件事&#xff0c;从队列里Get取…...

Unity3D ILRuntime开发原则与接口绑定详解

引言 ILRuntime是一款基于C#的热更新框架&#xff0c;使用IL2CPP技术将C#代码转换成C代码&#xff0c;支持动态编译和执行代码&#xff0c;适用于Unity3D的所有平台&#xff0c;包括Android、iOS、Windows、Mac等。本文将详细介绍ILRuntime在Unity3D中的开发原则及接口绑定技术…...

grouped = df.drop(‘name‘, axis=1).groupby(‘team‘)

这行代码&#xff1a; grouped df.drop(name, axis1).groupby(team)的作用是首先删除 DataFrame 中的 name 列&#xff0c;然后按 team 列进行分组。以下是对每个部分的详细解释&#xff1a; 1. df.drop(name, axis1) df.drop(name, axis1) 这部分代码会从 DataFrame df 中…...