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

news2024/11/26 4:39:23

在这里插入图片描述

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 GFLOPs
  s: [0.33, 0.50, 1024]  # YOLOv8s概览:225层, 11166560参数, 11166544梯度, 28.8 GFLOPs
  m: [0.67, 0.75, 768]   # YOLOv8m概览:295层, 25902640参数, 25902624梯度, 79.3 GFLOPs
  l: [1.00, 1.00, 512]   # YOLOv8l概览:365层, 43691520参数, 43691504梯度, 165.7 GFLOPs
  x: [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:包含卷积层、BN(批量归一化)和激活函数(如SiLU),用于提取特征。
  • 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 outputs
    if d > 1:
        k = d * (k - 1) + 1 if isinstance(k, int) else [d * (x - 1) + 1 for x in k]  # actual kernel-size
    if p is None:
        p = k // 2 if isinstance(k, int) else [x // 2 for x in k]  # auto-pad
    return p

class Conv(nn.Module):
    # Standard convolution with args(ch_in, ch_out, kernel, stride, padding, groups, dilation, activation)
    default_act = nn.SiLU()  # default activation

    def __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 convolutions
    def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):  # ch_in, ch_out, number, shortcut, groups, expansion
        super().__init__()
        c_ = int(c2 * e)  # hidden channels
        self.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 convolutions
    def __init__(self, c1, c2, n=1, shortcut=False, g=1, e=0.5):  # ch_in, ch_out, number, shortcut, groups, expansion
        super().__init__()
        self.c = int(c2 * e)  # hidden channels
        self.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 bottleneck
    def __init__(self, c1, c2, shortcut=True, g=1, k=(3, 3), e=0.5):  # ch_in, ch_out, shortcut, groups, kernels, expand
        super().__init__()
        c_ = int(c2 * e)  # hidden channels
        self.cv1 = Conv(c1, c_, k[0], 1)
        self.cv2 = Conv(c_, c2, k[1], 1, g=g)
        self.add = shortcut and c1 == c2

    def 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 Jocher
    def __init__(self, c1, c2, k=5):  # equivalent to SPP(k=(5, 9, 13))
        super().__init__()
        c_ = c1 // 2  # hidden channels
        self.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 models
    dynamic = False  # force grid reconstruction
    export = False  # export mode
    shape = None
    anchors = torch.empty(0)  # init
    strides = torch.empty(0)  # init

    def __init__(self, nc=80, ch=()):  # detection layer
        super().__init__()
        self.nc = nc  # number of classes
        self.nl = len(ch)  # number of detection layers
        self.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 anchor
        self.stride = torch.zeros(self.nl)  # strides computed during build

        c2, c3 = max((16, ch[0] // 4, self.reg_max * 4)), max(ch[0], self.nc)  # channels
        self.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  # BCHW
        for i in range(self.nl):
            x[i] = torch.cat((self.cv2[i](x[i]), self.cv3[i](x[i])), 1)
        if self.training:
            return x
        elif 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 = shape

        if self.export and self.format == 'edgetpu':  # FlexSplitV ops issue
            x_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.strides
        y = torch.cat((dbox, cls.sigmoid()), 1)
        return y if self.export else (y, x)

    def bias_init(self):
        # Initialize Detect() biases, WARNING: requires stride availability
        m = 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 frequency
        for a, b, s in zip(m.cv2, m.cv3, m.stride):  # from
            a[-1].bias.data[:] = 1.0  # box
            b[-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/9792391
    def __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 = c1

    def forward(self, x):
        b, c, a = x.shape  # batch, channels, anchors
        return 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)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1669387.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

单调栈问题

原理 单调栈的核心原理是:在栈内保持元素的单调性(递增或递减) 单调递增栈: 用于处理“下一个更小的元素”问题。当新元素比栈顶元素小或等于时,直接入栈;否则,一直从栈顶弹出元素&#xff0c…

会声会影2024中文汉化补丁器附免费激活码序列号

会声会影是一款由加拿大Corel公司发布的视频编辑软件,它以其功能丰富和用户友好的界面而闻名。会声会影2024是该系列的最新版本,它不仅继承了之前版本的强大功能,还引入了一系列新的特性和工具,使得视频编辑更加简单、高效且富有创…

【简单讲解下Fine-tuning BERT】

🎥博主:程序员不想YY啊 💫CSDN优质创作者,CSDN实力新星,CSDN博客专家 🤗点赞🎈收藏⭐再看💫养成习惯 ✨希望本文对您有所裨益,如有不足之处,欢迎在评论区提出…

【图解计算机网络】TCP 重传、滑动窗口、流量控制、拥塞控制

TCP 重传、滑动窗口、流量控制、拥塞控制 TCP 重传超时重传快速重传 滑动窗口流量控制拥塞控制慢启动拥塞避免拥塞发生快速恢复 TCP 重传 TCP重传是当发送的报文发生丢失的时候,重新发送丢失报文的一种机制,它是保证TCP协议可靠性的一种机制。 TCP重传…

【Oracle篇】rman物理备份工具的基础理论概述(第一篇,总共八篇)

☘️博主介绍☘️: ✨又是一天没白过,我是奈斯,DBA一名✨ ✌✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux,也在扩展大数据方向的知识面✌✌️ ❣️❣️❣️大佬们都喜欢静静的看文章&am…

试衣不再有界:Tunnel Try-on开启视频试衣应用新纪元

论文:https://arxiv.org/pdf/2404.17571 主页:https://mengtingchen.github.io/tunnel-try-on-page/ 一、摘要总结 随着虚拟试衣技术的发展,消费者和时尚行业对于能够在视频中实现高质量虚拟试衣的需求日益增长。这项技术允许用户在不实际穿…

云计算十三课

centos安装 点击左上角文件 点击新建虚拟机 点击下一步 点击稍后安装操作系统,下一步 选择Linux(l)下一步 设置虚拟机名称 点击浏览选择安装位置 新建文件夹设置名称不能为中文,点击确定 点击下一步 设置磁盘大小点击下一步…

修改MTU值解决Linux下运行top命令卡死问题

上周明月的Linux服务器上运行top命令总是莫名的出现卡死现象,甚至是CtrlC都无法终止进程,今天终于抽空找到了解决办法,原来是需要修改Linux的MTU值,将服务器操作系统数据包调小,加上VxLAN数据包小于1500即可。 top命令…

HCIP【BGP综合实验】

目录 一、实验拓扑图: 二、实验要求: 三、实验思路: 四、实验步骤: 1、进行网段的子网划分(整个实验总共有19条网段): (1)首先,根据实验要求,将172.16.0.0/16全部划…

英伟达发布AM-RADIO高效视觉基础模型,推理速度提升6倍,性能超CLIP、DINOv2、SAM

前言 近年来,视觉基础模型 (VFM) 在众多下游任务中取得了巨大成功,例如图像分类、目标检测和图像生成等。然而,现有的 VFM 通常专注于特定领域,例如 CLIP 擅长零样本视觉语言理解,DINOv2 擅长语义分割,SAM…

C控制语句:分支和跳转

1.1if语句 //colddays.c --找出0摄氏度以下的天数占总天数的百分比 #include <stdio.h>int main(void) {const int FREEZING 0;float temperature;int cold_days 0;int all_days 0;printf("Enter the list of daily low temperature.\n");printf("Use…

C++内存管理new/delete和new[ ]/delete[ ]

1.c/c内存分布 首先看一段代码 int globalVar 1; static int staticGlobalVar 1; void Test() { static int staticVar 1; int localVar 1; int num1[10] { 1, 2, 3, 4 }; char char2[] "abcd";const char* pChar3 "abcd"; //这里不加const会导致…

整理好的宁夏光伏发电数据集(2007-2020年)

1、包含指标&#xff1a;采样结束时刻、采样起始时刻、时间间隔、气温、方位角、云层不透明度、露点温度、DHI&#xff08;太阳散射辐射指数&#xff09;、DNI&#xff08;太阳直接辐射指数&#xff09;、GHI&#xff08;太阳总水平辐射&#xff09;、GTI&#xff08;固定倾角辐…

06-Fortran基础--Fortran模块化编程

06-Fortran基础--Fortran模块化编程 1 模块的定义和使用2 接口和模块间通信3 模块化编程的优势&#xff1a;4 模块使用示例5 结语 Fortran的模块化编程是一种组织和管理代码的方法&#xff0c;它包括模块的定义和使用、接口和模块间通信以及模块化编程的优势。 1 模块的定义和…

外网如何访问内网?快解析

由于公网IP资源短缺&#xff0c;我们的电脑大多处于内网环境&#xff0c;如何在外网访问内网电脑&#xff0c;成为一个令人头疼的问题&#xff0c;下面我给大家推荐一个非常实用的方法。 1&#xff1a;访问快解析下载安装快解析服务器 2&#xff1a;运行软件&#xff0c;点击“…

匿名管道及其应用

目录 一、什么是匿名管道&#xff1f; 三、创建与使用匿名管道 三、匿名管道的特点 匿名管道的四种情况 匿名管道的五种特性 四、匿名管道的实践应用---进程池 在编程的世界中&#xff0c;匿名管道是一种非常重要的通信机制。今天&#xff0c;让我们一起来深入探讨一下匿…

Spring WebFlux-响应式编程-019

&#x1f917; ApiHug {Postman|Swagger|Api...} 快↑ 准√ 省↓ GitHub - apihug/apihug.com: All abou the Apihug apihug.com: 有爱&#xff0c;有温度&#xff0c;有质量&#xff0c;有信任ApiHug - API design Copilot - IntelliJ IDEs Plugin | Marketplace The Nex…

Redis-发布与订阅

发布与订阅 什么是发布与订阅 Redis 发布订阅 (pub/sub) 是一种消息通信模式&#xff1a;发送者 (pub) 发送消息&#xff0c;订阅者 (sub) 接收消息。 Redis 客户端可以订阅任意数量的频道。 Redis的发布与订阅 客户端订阅频道 当给这个频道发送消息后&#xff0c;消息就会…

Java | Leetcode Java题解之第86题分隔链表

题目&#xff1a; 题解&#xff1a; class Solution {public ListNode partition(ListNode head, int x) {ListNode small new ListNode(0);ListNode smallHead small;ListNode large new ListNode(0);ListNode largeHead large;while (head ! null) {if (head.val < x…

LwIP 之九 详解 UDP RAW 编程、示例、API 源码、数据流

我们最为熟知的网络通信程序接口应该是 Socket。LwIP 自然也提供了 Socket 编程接口,不过,LwIP 的 Socket 编程接口都是使用最底层的接口来实现的。我们这里要学习的 UDP RAW 编程则是指的直接使用 LwIP 的最底层 UDP 接口来直接实现应用层功能。这里先来一张图,对 LwIP 内部…