YOLOv8改进 | 融合改进 | C2f融合Faster-GELU模块提升检测速度【完整代码 + 主要代码解析】

news2024/11/25 2:33:12

秋招面试专栏推荐 :深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转


💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡


专栏目录 :《YOLOv8改进有效涨点》专栏介绍 & 专栏目录 | 目前已有100+篇内容,内含各种Head检测头、损失函数Loss、Backbone、Neck、NMS等创新点改进——点击即可跳转


本文介绍一种部分卷积(PConv)以高效提取特征,减少冗余计算和内存访问。基于PConv,构建了FasterNet神经网络,它在多种设备上运行更快,且机会不影响视觉任务的准确性。此外,卷积的机会函数将替换为GELU。文章在介绍主要的原理后,将手把手教学如何进行模块的代码添加和修改,并将修改后的完整代码放在文章的最后,方便大家一键运行,小白也可轻松上手实践。以帮助您更好地学习深度学习目标检测YOLO系列的挑战。 

专栏地址YOLOv8改进——更新各种有效涨点方法——点击即可跳转  

目录

1. 原理

2. 将C2f_Faster添加到yolov8网络中

2.1 C2f_Faster 代码实现

 2.2 Faster_Block_CGLU的神经网络模块代码解析

2.3 更改init.py文件

2.4 添加yaml文件

2.5 注册模块

2.6 执行程序

3. 完整代码分享

4. GFLOPs

5. 进阶

6. 总结


1. 原理

论文地址:GAUSSIAN ERROR LINEAR UNITS (GELUS)——点击即可跳转

官方代码:官方代码仓库——点击即可跳转

GELU(Gaussian Error Linear Unit)激活函数是一种用于神经网络的非线性激活函数。它的主要原理基于将输入按其值进行加权,而不是像ReLU那样通过输入的符号来控制输出。

GELU的主要原理:

  1. 数学表达式:GELU的表达式为\text{GELU}(x) = x \Phi(x),其中\Phi(x) 是标准高斯分布的累积分布函数(CDF)。这意味着GELU函数的输出是输入值与输入值在标准正态分布中小于等于它的概率的乘积。

  2. 输入值的加权:不同于ReLU(直接将输入小于零的部分置为零),GELU通过 \Phi(x) 平滑地控制输入的通过情况。对于较大的正输入,GELU近似为输入本身;对于负输入,GELU将其逐渐减小到接近零,而不是直接变为零。

  3. 近似计算:GELU函数可以近似为以下公式,以便提高计算效率:\text{GELU}(x) \approx 0.5x(1 + \tanh[\sqrt{2/\pi}(x + 0.044715x^3)]) 这种近似形式保留了GELU的核心特性,并在计算速度上有所提升。

  4. 与ReLU和ELU的比较:GELU的非线性特性在多个任务中表现出色,例如计算机视觉、自然语言处理和语音识别。相比于ReLU和ELU,GELU能够更好地处理输入噪声,并且在没有丢弃的情况下表现出更低的训练损失。

通过这种平滑的处理方式,GELU在确保非线性的同时,能够在一定程度上保留输入的特性,这有助于网络更好地拟合复杂的数据分布。

2. 将C2f_Faster添加到yolov8网络中

2.1 C2f_Faster 代码实现

关键步骤一将下面代码粘贴到在/ultralytics/ultralytics/nn/modules/block.py中,并在该文件的__all__中添加“C2f_Faster_CGLU”


from timm.models.layers import DropPath
class Partial_conv3(nn.Module):
    def __init__(self, dim, n_div=4, forward='split_cat'):
        super().__init__()
        self.dim_conv3 = dim // n_div
        self.dim_untouched = dim - self.dim_conv3
        self.partial_conv3 = nn.Conv2d(self.dim_conv3, self.dim_conv3, 3, 1, 1, bias=False)

        if forward == 'slicing':
            self.forward = self.forward_slicing
        elif forward == 'split_cat':
            self.forward = self.forward_split_cat
        else:
            raise NotImplementedError

    def forward_slicing(self, x):
        # only for inference
        x = x.clone()   # !!! Keep the original input intact for the residual connection later
        x[:, :self.dim_conv3, :, :] = self.partial_conv3(x[:, :self.dim_conv3, :, :])
        return x

    def forward_split_cat(self, x):
        # for training/inference
        x1, x2 = torch.split(x, [self.dim_conv3, self.dim_untouched], dim=1)
        x1 = self.partial_conv3(x1)
        x = torch.cat((x1, x2), 1)
        return x

class ConvolutionalGLU(nn.Module):
    def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.) -> None:
        super().__init__()
        out_features = out_features or in_features
        hidden_features = hidden_features or in_features
        hidden_features = int(2 * hidden_features / 3)
        self.fc1 = nn.Conv2d(in_features, hidden_features * 2, 1)
        self.dwconv = nn.Sequential(
            nn.Conv2d(hidden_features, hidden_features, kernel_size=3, stride=1, padding=1, bias=True, groups=hidden_features),
            act_layer()
        )
        self.fc2 = nn.Conv2d(hidden_features, out_features, 1)
        self.drop = nn.Dropout(drop)
    
    # def forward(self, x):
    #     x, v = self.fc1(x).chunk(2, dim=1)
    #     x = self.dwconv(x) * v
    #     x = self.drop(x)
    #     x = self.fc2(x)
    #     x = self.drop(x)
    #     return x

    def forward(self, x):
        x_shortcut = x
        x, v = self.fc1(x).chunk(2, dim=1)
        x = self.dwconv(x) * v
        x = self.drop(x)
        x = self.fc2(x)
        x = self.drop(x)
        return x_shortcut + x

class Faster_Block_CGLU(nn.Module):
    def __init__(self,
                 inc,
                 dim,
                 n_div=4,
                 mlp_ratio=2,
                 drop_path=0.1,
                 layer_scale_init_value=0.0,
                 pconv_fw_type='split_cat'
                 ):
        super().__init__()
        self.dim = dim
        self.mlp_ratio = mlp_ratio
        self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()
        self.n_div = n_div

        self.mlp = ConvolutionalGLU(dim)

        self.spatial_mixing = Partial_conv3(
            dim,
            n_div,
            pconv_fw_type
        )
        
        self.adjust_channel = None
        if inc != dim:
            self.adjust_channel = Conv(inc, dim, 1)

        if layer_scale_init_value > 0:
            self.layer_scale = nn.Parameter(layer_scale_init_value * torch.ones((dim)), requires_grad=True)
            self.forward = self.forward_layer_scale
        else:
            self.forward = self.forward

    def forward(self, x):
        if self.adjust_channel is not None:
            x = self.adjust_channel(x)
        shortcut = x
        x = self.spatial_mixing(x)
        x = shortcut + self.drop_path(self.mlp(x))
        return x

    def forward_layer_scale(self, x):
        shortcut = x
        x = self.spatial_mixing(x)
        x = shortcut + self.drop_path(
            self.layer_scale.unsqueeze(-1).unsqueeze(-1) * self.mlp(x))
        return x

class C3_Faster_CGLU(C3):
    def __init__(self, c1, c2, n=1, shortcut=False, g=1, e=0.5):
        super().__init__(c1, c2, n, shortcut, g, e)
        c_ = int(c2 * e)  # hidden channels
        self.m = nn.Sequential(*(Faster_Block_CGLU(c_, c_) for _ in range(n)))

class C2f_Faster_CGLU(C2f):
    def __init__(self, c1, c2, n=1, shortcut=False, g=1, e=0.5):
        super().__init__(c1, c2, n, shortcut, g, e)
        self.m = nn.ModuleList(Faster_Block_CGLU(self.c, self.c) for _ in range(n))

 2.2 Faster_Block_CGLU的神经网络模块代码解析

这段代码定义一个名为Faster_Block_CGLU的神经网络模块,主要包括了卷积操作、空间混合操作以及层级缩放。卷积函数使用的是带有GELU激活函数的ConvolutionalGLU

代码结构和关键部分:

  1. 构造函数 (__init__):

    • inc: 输入通道数。

    • dim: 输出通道数。

    • n_div: 空间混合操作中使用的通道划分因子,默认值为4。

    • mlp_ratio: MLP(多层感知器)中通道的扩展比例。

    • drop_path: DropPath的概率,用于随机丢弃通道以增强模型的鲁棒性。

    • layer_scale_init_value: 用于层级缩放的初始化值。

    • pconv_fw_type: 部分卷积的前向传播类型(split_cat是默认值)。

  2. ConvolutionalGLU (Gated Linear Unit with Convolution):

    • self.mlp = ConvolutionalGLU(dim):这是一个使用GELU激活函数的卷积操作,通常用于引入非线性特性。

    • GELU在这里用作激活函数,可以帮助网络更有效地捕捉输入特征的细微变化。

  3. 空间混合 (Partial_conv3):

    • self.spatial_mixing = Partial_conv3(dim, n_div, pconv_fw_type):这部分处理输入特征的空间信息,通过部分卷积操作实现。

  4. 通道调整 (adjust_channel):

    • 如果输入通道数inc与输出通道数dim不匹配,会通过一个1x1卷积层调整通道数,以便匹配后续操作。

  5. 层级缩放 (layer_scale):

    • 如果layer_scale_init_value大于0,将初始化一个可训练的缩放参数self.layer_scale。这部分通过在前向传播时对特征进行缩放来增强模型的学习能力。

前向传播 (forward) 和带层级缩放的前向传播 (forward_layer_scale):

  • forward:

    • 如果通道数需要调整,首先会通过adjust_channel进行处理。

    • 然后通过spatial_mixing进行空间信息的混合。

    • 最后通过mlp(此处即使用了GELU激活函数的卷积层)处理,并加上shortcut连接(残差连接)后的结果返回。

  • forward_layer_scale:

    • 这一部分与forward类似,不同的是,mlp输出会先乘以layer_scale再进行残差连接。这样可以对特征进行更加精细的控制。

总结:

这段代码实现了一个基于卷积的模块Faster_Block_CGLU,其中卷积操作采用了GELU激活函数。GELU使得这个模块能够更灵活地处理输入特征,尤其是在处理具有复杂模式的数据时。

2.3 更改init.py文件

关键步骤二:修改modules文件夹下的__init__.py文件,先导入函数   

 然后在下面的__all__中声明函数 

2.4 添加yaml文件

关键步骤三:在/ultralytics/ultralytics/cfg/models/v8下面新建文件yolov8_Faster_Block_CGLU.yaml文件,粘贴下面的内容

  • OD【目标检测】
# 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 GFLOPs
  s: [0.33, 0.50, 1024]  # YOLOv8s summary: 225 layers, 11166560 parameters, 11166544 gradients,  28.8 GFLOPs
  m: [0.67, 0.75, 768]   # YOLOv8m summary: 295 layers, 25902640 parameters, 25902624 gradients,  79.3 GFLOPs
  l: [1.00, 1.00, 512]   # YOLOv8l summary: 365 layers, 43691520 parameters, 43691504 gradients, 165.7 GFLOPs
  x: [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_Faster_CGLU, [128, True]]
  - [-1, 1, Conv, [256, 3, 2]]  # 3-P3/8
  - [-1, 6, C2f_Faster_CGLU, [256, True]]
  - [-1, 1, Conv, [512, 3, 2]]  # 5-P4/16
  - [-1, 6, C2f_Faster_CGLU, [512, True]]
  - [-1, 1, Conv, [1024, 3, 2]]  # 7-P5/32
  - [-1, 3, C2f_Faster_CGLU, [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_Faster_CGLU, [512]]  # 12

  - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
  - [[-1, 4], 1, Concat, [1]]  # cat backbone P3
  - [-1, 3, C2f_Faster_CGLU, [256]]  # 15 (P3/8-small)

  - [-1, 1, Conv, [256, 3, 2]]
  - [[-1, 12], 1, Concat, [1]]  # cat head P4
  - [-1, 3, C2f_Faster_CGLU, [512]]  # 18 (P4/16-medium)

  - [-1, 1, Conv, [512, 3, 2]]
  - [[-1, 9], 1, Concat, [1]]  # cat head P5
  - [-1, 3, C2f_Faster_CGLU, [1024]]  # 21 (P5/32-large)

  - [[15, 18, 21], 1, Detect, [nc]]  # Detect(P3, P4, P5)
  • Seg【语义分割】
# 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 GFLOPs
  s: [0.33, 0.50, 1024]  # YOLOv8s summary: 225 layers, 11166560 parameters, 11166544 gradients,  28.8 GFLOPs
  m: [0.67, 0.75, 768]   # YOLOv8m summary: 295 layers, 25902640 parameters, 25902624 gradients,  79.3 GFLOPs
  l: [1.00, 1.00, 512]   # YOLOv8l summary: 365 layers, 43691520 parameters, 43691504 gradients, 165.7 GFLOPs
  x: [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_Faster_CGLU, [128, True]]
  - [-1, 1, Conv, [256, 3, 2]]  # 3-P3/8
  - [-1, 6, C2f_Faster_CGLU, [256, True]]
  - [-1, 1, Conv, [512, 3, 2]]  # 5-P4/16
  - [-1, 6, C2f_Faster_CGLU, [512, True]]
  - [-1, 1, Conv, [1024, 3, 2]]  # 7-P5/32
  - [-1, 3, C2f_Faster_CGLU, [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_Faster_CGLU, [512]]  # 12

  - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
  - [[-1, 4], 1, Concat, [1]]  # cat backbone P3
  - [-1, 3, C2f_Faster_CGLU, [256]]  # 15 (P3/8-small)

  - [-1, 1, Conv, [256, 3, 2]]
  - [[-1, 12], 1, Concat, [1]]  # cat head P4
  - [-1, 3, C2f_Faster_CGLU, [512]]  # 18 (P4/16-medium)

  - [-1, 1, Conv, [512, 3, 2]]
  - [[-1, 9], 1, Concat, [1]]  # cat head P5
  - [-1, 3, C2f_Faster_CGLU, [1024]]  # 21 (P5/32-large)

  - [[15, 18, 21], 1, Segment, [nc, 32, 256]] # Segment(P3, P4, P5)

温馨提示:因为本文只是对yolov8基础上添加模块,如果要对yolov8n/l/m/x进行添加则只需要指定对应的depth_multiple 和 width_multiple。不明白的同学可以看这篇文章: yolov8yaml文件解读——点击即可跳转  


2.5 注册模块

关键步骤四:在task.py的parse_model函数中注册

2.6 执行程序

在train.py中,将model的参数路径设置为yolov8_Faster_Block_CGLU.yaml的路径

建议大家写绝对路径,确保一定能找到

from ultralytics import YOLO
import warnings
warnings.filterwarnings('ignore')
from pathlib import Path
 
if __name__ == '__main__':
 
 
    # 加载模型
    model = YOLO("ultralytics/cfg/v8/yolov8.yaml")  # 你要选择的模型yaml文件地址
    # Use the model
    results = model.train(data=r"你的数据集的yaml文件地址",
                          epochs=100, batch=16, imgsz=640, workers=4, name=Path(model.cfg).stem)  # 训练模型

 🚀运行程序,如果出现下面的内容则说明添加成功🚀 

                   from  n    params  module                                       arguments
  0                  -1  1       464  ultralytics.nn.modules.conv.Conv             [3, 16, 3, 2]
  1                  -1  1      4672  ultralytics.nn.modules.conv.Conv             [16, 32, 3, 2]
  2                  -1  1      3448  ultralytics.nn.modules.block.C2f_Faster_CGLU [32, 32, 1, True]
  3                  -1  1     18560  ultralytics.nn.modules.conv.Conv             [32, 64, 3, 2]
  4                  -1  2     18296  ultralytics.nn.modules.block.C2f_Faster_CGLU [64, 64, 2, True]
  5                  -1  1     73984  ultralytics.nn.modules.conv.Conv             [64, 128, 3, 2]
  6                  -1  2     71536  ultralytics.nn.modules.block.C2f_Faster_CGLU [128, 128, 2, True]
  7                  -1  1    295424  ultralytics.nn.modules.conv.Conv             [128, 256, 3, 2]
  8                  -1  1    207868  ultralytics.nn.modules.block.C2f_Faster_CGLU [256, 256, 1, True]
  9                  -1  1    164608  ultralytics.nn.modules.block.SPPF            [256, 256, 5]
 10                  -1  1         0  torch.nn.modules.upsampling.Upsample         [None, 2, 'nearest']
 11             [-1, 6]  1         0  ultralytics.nn.modules.conv.Concat           [1]
 12                  -1  1     85176  ultralytics.nn.modules.block.C2f_Faster_CGLU [384, 128, 1]
 13                  -1  1         0  torch.nn.modules.upsampling.Upsample         [None, 2, 'nearest']
 14             [-1, 4]  1         0  ultralytics.nn.modules.conv.Concat           [1]
 15                  -1  1     21564  ultralytics.nn.modules.block.C2f_Faster_CGLU [192, 64, 1]
 16                  -1  1     36992  ultralytics.nn.modules.conv.Conv             [64, 64, 3, 2]
 17            [-1, 12]  1         0  ultralytics.nn.modules.conv.Concat           [1]
 18                  -1  1     60600  ultralytics.nn.modules.block.C2f_Faster_CGLU [192, 128, 1]
 19                  -1  1    147712  ultralytics.nn.modules.conv.Conv             [128, 128, 3, 2]
 20             [-1, 9]  1         0  ultralytics.nn.modules.conv.Concat           [1]
 21                  -1  1    240636  ultralytics.nn.modules.block.C2f_Faster_CGLU [384, 256, 1]
 22        [15, 18, 21]  1    897664  ultralytics.nn.modules.head.Detect           [80, [64, 128, 256]]
YOLOv8_faster_CGLU summary: 265 layers, 2349204 parameters, 2349188 gradients, 6.8 GFLOPs

3. 完整代码分享

https://pan.baidu.com/s/1WKs66u904YmY2wZOlCdYDw?pwd=3kg6

 提取码: 3kg6 

4. GFLOPs

关于GFLOPs的计算方式可以查看百面算法工程师 | 卷积基础知识——Convolution

未改进的YOLOv8nGFLOPs

img

改进后的GFLOPs

5. 进阶

可以与其他的注意力机制或者损失函数等结合,进一步提升检测效果

6. 总结

Faster_Block_CGLU 是一个神经网络模块,结合了卷积、空间混合和层级缩放操作。它使用GELU激活函数来增强卷积层的非线性表达能力,能够灵活处理复杂输入特征。模块中的卷积操作由 `ConvolutionalGLU` 实现,并通过 `Partial_conv3` 进行空间信息的混合。当输入通道数与输出通道数不匹配时,使用 1x1 卷积进行调整。此外,通过残差连接和可选的层级缩放机制,模块能够在前向传播中更加精细地控制特征流,从而提高模型的学习能力。

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

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

相关文章

Unity URPShader支持多光源处理

//声明变体并且引用文件 #pragma shader_feature _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" //在数据结构体中声明需要使用的数据 struct Attributes {float4 posit…

如何写一份简单的3C产品说明书?五步让你留住客源

在撰写3C(计算机、通信、消费电子)产品说明书时,清晰、简洁且全面的信息传递至关重要。本文将首先介绍产品说明书的基本结构,随后探讨视觉阅读的重要性,并通过实例展示如何撰写一份优秀的产品说明书。最后,…

SpringBoot2:学SpringBoot前的知识准备-用IDEA创建传统的webapp工程,并整合SpringMVC

1、IDEA创建工程 基于Maven模板创建的SpringMVC工程 工程创建好后,只有webapp目录 这里,我们需要手动创建java目录和resources配置文件目录 创建好后,配置下目录属性 最终结构 至此,工程就创建好了 2、配置Tomcat 参考&am…

LabVIEW中10μs方波生成问题

在LabVIEW中使用NI PCIe-6353卡生成并控制10μs级别的方波输出可能遇到频率调整的问题。下面将详细分析常见问题的原因,如采样率设置、时钟源配置、波形生成方式等,并提供具体的解决方案,帮助用户成功生成并调整高精度方波信号。 为了在LabVI…

孙悟空求药的深刻反思

孙悟空求药的深刻反思 - 孔乙己大叔引言:孙悟空的求药之旅 在古老的神话故事中,孙悟空为了拯救乌鸡国国王的生命,不惜跨越千山万水,前往太上老君的仙宫,祈求那传说中的九转还魂丹。面对孙悟空那看似贪婪的一千…

【案例65】WebSphere启动比tomcat启动慢的测试

以下为多次测试的一些结论,谨慎使用,请一定做好测试后在使用。 1.在原先慢的WAS环境下,添加-Dsun.reflect.inflationThreshold15,可以有效提升was下的响应速度,和Tomcat下速度相当,但该参数15的情况我们Tomcat以前还没…

FastGPT:利用大模型重新定义传统知识库

引言 传统知识库的痛点 传统知识库广泛应用于企业文档管理、客户支持等场景,但随着信息量和复杂度的增加,存在以下显著问题: 数据难整合: 结构化与非结构化数据分散,更新维护成本高。检索不精准: 依赖关…

day03-面向对象-内部类泛型常用API

一、内部类 内部类是类中的五大成分之一(成员变量、方法、构造器、代码块、内部类) 如果一个类定义在另一个类的内部,这个类就是内部类。 场景:当一个类的内部,包含了一个完整的事物,且这个事物没有必要单…

Go发布自定义包

1、初始化go.mod go mod init github.com/xumeng03/images2、编写包内容 这里只是一个简单的压缩jpg/jpeg图片例子,代码参考 https://github.com/disintegration/imaging 2.1、fs.go package imagesimport ("image""io""os""p…

利用通义灵码实现我的第一次开源贡献

作者:重庆邮电大学计算机学院李逸雄 结缘开源 最早了解开源是从学校的兴趣组织开始的。2023 年 10 月 21 日,openSUSE 亚洲峰会在我们学校召开,这次会议汇聚了许多来自 openSUSE 社区贡献者以及对开源感兴趣的爱好者们。我第一次知道有这么…

postman使用记录

输入密码,地址 然后输入格式为json 在 body里写入传参 然后点击发送即可

裸机:SD卡启动详解

内存和外存的区别 内存和外存在计算机系统中扮演着不同的角色,它们之间存在显著的差异。以下是内存和外存之间几个主要方面的区别: 存储特性与易失性 内存(Memory):通常指的是随机存取存储器(RAM&#x…

Java面试题·区别题·JavaSE部分

系列文章目录 总章 Java区别题 文章目录 系列文章目录前言private/默认/protected/public权限修饰符的区别&和&&区别和联系,I和II区别和联系if和switch的不同之处和equals的区别和联系数组做形参和可变参数做形参联系和区别接口和抽象类的异同之处面向…

Android设备如何异地访问本地部署的code-server随时随地远程开发

文章目录 前言1.Ubuntu本地安装code-server2. 安装cpolar内网穿透3. 创建隧道映射本地端口4. 安卓平板测试访问5.固定域名公网地址6.结语 前言 本文主要介绍如何在Linux Ubuntu系统安装code-server,并结合cpolar内网穿透工具配置公网地址,轻松实现使用安…

企业级开发——Git使用

一 Git介绍 1 什么是版本控制 版本控制是指对软件开发过程中各种程序代码、配置文件及说明文档等文件变更的管理,是软件配置管理的核心思想之一。 2 为什么使用版本控制 采用手动复制的方式管理版本,会造成版本管理混乱,而通过版本控制管…

测试使用开源异构迁移工具dbswitch

dbswitch: 异构数据库迁移同步(搬家)工具 (base) rootnode13:~# cat /etc/issue Ubuntu 20.04.5 LTS \n \l (base) rootnode13:~# curl -k -sSL https://gitee.com/dromara/dbswitch/attach_files/1878800/download > /tmp/dbswitch_install.sh && bash /tmp/dbsw…

地级市地理相邻矩阵(地级市名称版、行政区划代码版)

地级市地理相邻矩阵(地级市名称版、行政区划代码版) 范围:294个地级市 格式:地级市名称版、行政区划代码版 说明:数据为同省下城市之间的相邻矩阵,表示同一省份内各个城市相互之间邻近关系。如果同一省份…

VTK+Qt+Cmake+VS的环境搭建

VTKQtCmakeVS的环境搭建 一、准备工作二、VTK源码安装过程三、错误排查四、Cmake中引用VTK五、代码示例 本文的主要内容:简单介绍如何使用Cmake编译安装VTK源代码;如何配置VTK在Qt中的使用环境;如何以VS作为IDE在C下使用QtVTK。 哪些人适合阅…

android studio .android和.gradle迁移到其他盘

操作 可以看到gradle和android占用不小 .android 将C盘的.android迁移到D盘 切换到.android下面的avd目录,修改ini文件 .gradle 将.gradle复制到D盘 在Android studio的文件夹下面新建一个文件夹,我这里命名androidcache。接着在Android studio的…