YOLOv10-1.1部分代码阅读笔记-utils.py

news2025/1/5 8:24:12

utils.py

ultralytics\nn\modules\utils.py

目录

utils.py

1.所需的库和模块

2.def _get_clones(module, n): 

3.def bias_init_with_prob(prior_prob=0.01): 

4.def linear_init(module): 

5.def inverse_sigmoid(x, eps=1e-5): 

6.def multi_scale_deformable_attn_pytorch(value: torch.Tensor, value_spatial_shapes: torch.Tensor, sampling_locations: torch.Tensor, attention_weights: torch.Tensor,) -> torch.Tensor: 


1.所需的库和模块

# Ultralytics YOLO 🚀, AGPL-3.0 license
"""Module utils."""

import copy
import math

import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.nn.init import uniform_

# 这段代码定义了一个名为 __all__ 的元组,它包含了一系列的类名。这个元组通常用于Python模块中,以明确指出该模块对外公开的接口或类。当某个模块被导入时,如果使用了 from module import * 这样的导入语句, __all__ 元组中列出的名称将会被导入。
__all__ = "multi_scale_deformable_attn_pytorch", "inverse_sigmoid"

2.def _get_clones(module, n): 

# 这段代码定义了一个名为 _get_clones 的类,它用于创建指定模块( module )的多个副本,并返回这些副本组成的列表。这个函数通常在深度学习中用于复制相同的模块多次,以构建序列模型或实现特定的网络结构。
# 定义了一个名为 _get_clones 的函数,它接受两个参数。
# 1.module :是一个神经网络模块。
# 2.n :是一个整数,表示要复制模块的次数。
def _get_clones(module, n):
    # 从给定的模块创建克隆模块列表。
    """Create a list of cloned modules from the given module."""
    #  这行代码执行了实际的复制操作,并返回一个结果。
    # copy.deepcopy(module) :使用 copy 模块的 deepcopy 函数来创建 module 的一个深拷贝。深拷贝意味着创建一个新的对象,并递归复制其所有元素,确保新对象和原始对象完全独立。
    # for _ in range(n) :这是一个列表推导式,用于生成一个列表,其中包含 n 个 module 的深拷贝。 _ 是一个占位符,表示我们不关心循环的索引,只关心迭代的次数。
    # nn.ModuleList([...]) :将上述生成的列表包装成一个 ModuleList 对象。 ModuleList 是PyTorch中的一个类,用于存储一个模块列表,并且可以像常规Python列表一样进行索引和迭代,但它还具有一些额外的功能,比如在模型的参数中注册每个模块的参数。
    return nn.ModuleList([copy.deepcopy(module) for _ in range(n)])
# _get_clones 函数的作用是复制一个神经网络模块 n 次,并返回一个包含所有复制模块的 ModuleList 。这在深度学习中很有用,比如在实现某些特定的网络结构时,可能需要多个相同的模块。通过这种方式,可以确保每个模块都有独立的参数,同时便于管理和使用。

3.def bias_init_with_prob(prior_prob=0.01): 

# 这段代码定义了一个名为 bias_init_with_prob 的函数,它用于计算和返回一个初始化偏置值,这个值通常用于神经网络中偏置项的初始化。
# 定义了一个名为 bias_init_with_prob 的函数,它接受一个参数。
# 1.prior_prob :是一个浮点数,默认值为 0.01 ,表示某个事件发生的先验概率。
def bias_init_with_prob(prior_prob=0.01):
    # 根据给定的概率值初始化 conv/fc 偏差值。
    """Initialize conv/fc bias value according to a given probability value."""
    # 计算并返回一个浮点数,这个数是根据 prior_prob 计算得到的初始化偏置值。
    # 1 - prior_prob :计算 prior_prob 的补数,即不发生该事件的概率。
    # (1 - prior_prob) / prior_prob :计算不发生该事件的概率与发生该事件的概率之比。
    # -np.log(...) :计算上述比值的负对数。这里使用的是自然对数 np.log ,它是 NumPy 库中的一个函数,用于计算自然对数(以 e 为底的对数)。
    # float(...) :将计算结果转换为浮点数,以确保返回值的类型是 float 。
    return float(-np.log((1 - prior_prob) / prior_prob))  # return bias_init
# bias_init_with_prob 函数根据给定的先验概率 prior_prob 计算一个初始化偏置值。这个值通常用于初始化神经网络中的偏置项,以便在训练开始时对特定事件的发生概率进行调整。通过设置偏置项,可以影响网络的输出,使其更倾向于或更不倾向于激活某个神经元。这种方法在处理类别不平衡问题时特别有用,因为它可以帮助模型在训练过程中更加关注少数类别。

4.def linear_init(module): 

# 这段代码定义了一个名为 linear_init 的函数,它用于初始化线性层(例如全连接层)的权重和偏置。
# 定义了一个名为 linear_init 的函数,它接受一个参数。
# 1.module :指的是一个线性层模块,比如 PyTorch 中的 nn.Linear 。
def linear_init(module):
    # 初始化线性模块的权重和偏差。
    """Initialize the weights and biases of a linear module."""
    # 计算了一个边界值 bound ,用于初始化权重。
    # module.weight.shape[0] :获取线性层权重矩阵的第一个维度的大小,即输入特征的数量。
    # 1 / math.sqrt(...) :计算输入特征数量的平方根的倒数,这个值将用作权重初始化的范围的边界。这是一种常见的权重初始化策略,称为 Xavier/Glorot 初始化,它有助于保持激活函数输出的方差在网络的各层之间相对一致。
    bound = 1 / math.sqrt(module.weight.shape[0])

    # torch.nn.init.uniform_(tensor, a=0.0, b=1.0)
    # 在PyTorch中, nn.init.uniform_() 是一个用于初始化张量参数的函数,它将张量中的元素值从均匀分布中随机采样。这个函数通常用于初始化神经网络中的权重和偏置参数。
    # 参数 :
    # tensor  ( torch.Tensor ): 需要被初始化的张量。
    # a ( float , 可选): 均匀分布的下限,默认为0.0。
    # b ( float , 可选): 均匀分布的上限,默认为1.0。
    # 功能 :
    # nn.init.uniform_() 函数的主要功能是为张量提供一个随机的初始值,这些值是从指定的均匀分布中采样的。
    # 这种初始化方法可以帮助打破对称性,使得神经网络的权重在训练开始时具有不同的值,从而有助于训练过程的收敛。均匀初始化是一种常用的初始化方法,特别是在没有特定先验知识的情况下。

    # 使用均匀分布来初始化权重。
    # uniform_(...) :这是一个函数,用于将张量(Tensor)的元素值从均匀分布中随机采样。
    # module.weight :指定要初始化的权重张量。
    # -bound 和 bound :指定均匀分布的下限和上限,即权重的取值范围。
    uniform_(module.weight, -bound, bound)
    # 检查线性层是否有偏置项,并且偏置项是否不为 None 。 hasattr 函数用于检查对象是否有指定的属性, module.bias 检查是否存在偏置项。
    if hasattr(module, "bias") and module.bias is not None:
        # 如果存在偏置项,使用与权重相同的均匀分布范围来初始化偏置项。
        uniform_(module.bias, -bound, bound)
# linear_init 函数用于对线性层的权重和偏置进行初始化。权重使用 Xavier/Glorot 初始化策略,即从 [-bound, bound] 范围内的均匀分布中采样,其中 bound 是根据权重矩阵的输入特征数量计算得到的。如果线性层有偏置项,偏置项也会被以相同的方式初始化。这种初始化方法有助于在训练神经网络时保持激活函数输出的稳定性。

5.def inverse_sigmoid(x, eps=1e-5): 

# 这段代码定义了一个名为 inverse_sigmoid 的函数,它用于计算输入 x 的 Sigmoid 函数的逆函数。
# 定义了一个名为 inverse_sigmoid 的函数,它接受两个参数。
# 1.x :是输入值。
# 2.eps 是一个很小的数,用于防止除以零的错误,默认值为 1e-5 。
def inverse_sigmoid(x, eps=1e-5):
    # 计算张量的逆 sigmoid 函数。
    """Calculate the inverse sigmoid function for a tensor."""

    # torch.clamp(input, min=None, max=None)
    # torch.clamp() 是 PyTorch 库中的一个函数,用于将张量中的元素限制在指定的范围内。如果元素超出了这个范围,它们将被设置为范围的上限或下限。
    # 参数 :
    # input :要进行裁剪的输入张量。
    # min :元素的最小值。默认为 None ,表示不设置下界。
    # max :元素的最大值。默认为 None ,表示不设置上界。
    # 返回值 :
    # 返回一个新的张量,其中的元素被限制在 [min, max] 范围内。
    # 注意事项 :
    # torch.clamp() 函数返回的是新张量,原始输入张量不会被修改。
    # 如果需要在原地修改张量,可以使用 clamped_() 方法,例如 tensor.clamp_(0, 3) 。
    # torch.clamp() 可以用于多维张量,并且可以指定不同的 min 和 max 值用于不同的维度。
    # min 和 max 参数也可以是标量值,或者与输入张量形状相同的张量,用于对不同元素应用不同的限制。

    # 使用 clamp 方法将 x 的值限制在 [0, 1] 范围内。这是因为 Sigmoid 函数的输出值应该在这个区间内, clamp 方法确保即使输入值超出这个范围,函数也能正常工作。
    x = x.clamp(min=0, max=1)
    # 再次使用 clamp 方法,将 x 的值限制在 [eps, 1] 范围内。这是为了防止在计算 x1 / x2 时, x 接近 0 导致除以一个非常小的数,从而产生数值不稳定。
    x1 = x.clamp(min=eps)
    # 计算 1 - x 并将结果限制在 [eps, 1] 范围内。这是出于与 x1 相同的理由,确保在计算 x1 / x2 时, 1 - x 接近 0 也不会导致除以一个非常小的数。
    x2 = (1 - x).clamp(min=eps)
    # 计算 x1 除以 x2 的自然对数,并返回结果。这个计算实际上是 Sigmoid 函数的逆操作。Sigmoid 函数将任意实数映射到 (0, 1) 区间,其逆函数可以将 (0, 1) 区间内的值映射回原始的实数空间。
    return torch.log(x1 / x2)
# inverse_sigmoid 函数计算输入 x 的 Sigmoid 逆值。它首先确保输入值在 [0, 1] 区间内,然后计算 x 和 1 - x 的值,并将它们限制在一个非常小的正数 eps 以上,以避免数值计算中的不稳定。最后,它返回 x 和 1 - x 的比值的自然对数,这个值是 x 的 Sigmoid 逆值。这种逆 Sigmoid 转换在某些机器学习任务中很有用,比如在处理经过 Sigmoid 函数的输出时,需要将其转换回原始的预测值。

6.def multi_scale_deformable_attn_pytorch(value: torch.Tensor, value_spatial_shapes: torch.Tensor, sampling_locations: torch.Tensor, attention_weights: torch.Tensor,) -> torch.Tensor: 

# 这段代码定义了一个名为 multi_scale_deformable_attn_pytorch 的函数,它实现了多尺度可变形注意力机制(Multi-Scale Deformable Attention),这是一种在计算机视觉任务中,特别是在目标检测和图像分割中使用的高级注意力机制。
# 定义了函数 multi_scale_deformable_attn_pytorch ,它接受四个参数。
# 1.value :值特征图。
# 2.value_spatial_shapes :不同尺度值特征图的空间形状。
# 3.sampling_locations :采样位置。
# 4.attention_weights :注意力权重
# 返回一个 torch.Tensor 类型的输出。
def multi_scale_deformable_attn_pytorch(
    value: torch.Tensor,
    value_spatial_shapes: torch.Tensor,
    sampling_locations: torch.Tensor,
    attention_weights: torch.Tensor,
) -> torch.Tensor:
    # 多尺度可变形注意力。
    """
    Multiscale deformable attention.

    https://github.com/IDEA-Research/detrex/blob/main/detrex/layers/multi_scale_deform_attn.py
    """

    # 从 value 张量中提取出 批量大小 bs 、 多头注意力的头数 num_heads 和 嵌入维度 embed_dims 。
    bs, _, num_heads, embed_dims = value.shape
    # 从 sampling_locations 张量中提取出 查询的数量 num_queries 、 多头注意力的头数 num_heads 、 尺度级别 num_levels 和 每个查询点的采样点数 num_points 。
    _, num_queries, num_heads, num_levels, num_points, _ = sampling_locations.shape
    # 将 value 张量按照 value_spatial_shapes 中的形状分割成多个子张量,每个子张量对应不同尺度的特征图。
    value_list = value.split([H_ * W_ for H_, W_ in value_spatial_shapes], dim=1)
    # 这行代码是将采样位置从某种归一化的坐标系转换到 grid_sample 函数所需要的坐标系。在 PyTorch 中, grid_sample 函数期望的输入坐标范围是 [-1, 1] ,这对应于输入特征图的归一化坐标,其中 -1 表示特征图的最左边(或最顶部), 1 表示最右边(或最底部)。
    # sampling_locations :这是一个包含采样位置的张量,其坐标可能是相对于特征图的中心点归一化的,范围在 [0, 1] 之间。例如,如果 sampling_locations 中的值为 0 ,则表示特征图的中心点; 0.5 表示特征图的右边缘(或下边缘); -0.5 表示特征图的左边缘(或上边缘)。
    # 2 * sampling_locations - 1 :这个表达式将 [0, 1] 范围的坐标转换为 [-1, 1] 范围。具体来说,它首先将坐标乘以 2 ,这样原来 [0, 1] 的范围就变成了 [0, 2] ,然后减去 1 ,使得范围最终变为 [-1, 1] 。
    # 这种转换是必要的,因为 grid_sample 函数使用 [-1, 1] 范围的坐标来确定采样点在特征图上的位置。通过这种方式,采样点的坐标可以正确地映射到特征图的边界上,从而允许 grid_sample 函数进行双线性插值并获取正确的像素值。
    sampling_grids = 2 * sampling_locations - 1
    # 初始化一个空列表,用于存储每个尺度的采样值。
    sampling_value_list = []
    # 这段代码是多尺度可变形注意力机制中的一部分,用于对每个尺度的特征图进行采样。
    # 开始一个循环,遍历每个尺度的特征图。 level 是当前尺度的索引, (H_, W_) 是当前尺度特征图的高度和宽度。
    for level, (H_, W_) in enumerate(value_spatial_shapes):
        # bs, H_*W_, num_heads, embed_dims ->
        # bs, H_*W_, num_heads*embed_dims ->
        # bs, num_heads*embed_dims, H_*W_ ->
        # bs*num_heads, embed_dims, H_, W_
        # 对当前尺度的特征图进行一系列变换。
        # flatten(2) :将 value_list[level] 的最后两个维度( num_heads 和 embed_dims )合并。
        # transpose(1, 2) :交换合并后的维度和 H_*W_ 维度的位置。
        # reshape(bs * num_heads, embed_dims, H_, W_) :将张量重塑为 (batch_size * num_heads, embed_dims, H_, W_) 的形状,以适应 grid_sample 函数的输入要求。
        value_l_ = value_list[level].flatten(2).transpose(1, 2).reshape(bs * num_heads, embed_dims, H_, W_)
        # bs, num_queries, num_heads, num_points, 2 ->
        # bs, num_heads, num_queries, num_points, 2 ->
        # bs*num_heads, num_queries, num_points, 2
        # 对当前尺度的采样网格进行变换。
        # sampling_grids[:, :, :, level] :选择当前尺度的采样网格。
        # transpose(1, 2) :交换 num_heads 和 num_queries 维度。
        # flatten(0, 1) :将 batch_size 和 num_heads 维度合并,并与 num_queries 维度一起展平。
        sampling_grid_l_ = sampling_grids[:, :, :, level].transpose(1, 2).flatten(0, 1)

        # torch.nn.functional.grid_sample(input, grid, mode='bilinear', padding_mode='zeros', align_corners=None)
        # torch.nn.functional.grid_sample 是 PyTorch 中的一个函数,它用于根据给定的坐标网格对输入张量进行采样。这个函数常用于图像变形、数据增强等任务。
        # 参数说明 :
        # input : 输入张量,可以是 4D 张量(N, C, H, W)或 5D 张量(N, C, D, H, W),分别代表批量图像或体积数据。
        # grid : 坐标网格张量,用于指定采样位置。对于 4D 输入, grid 的形状为(N, H_out, W_out, 2),对于 5D 输入, grid 的形状为(N, D_out, H_out, W_out, 3)。
        # mode : 采样模式,可以是 'bilinear'(双线性插值)或 'nearest'(最近邻插值)。
        # padding_mode : 填充模式,可以是 'zeros'(用 0 填充)或 'border'(用边界值填充)。
        # align_corners : 布尔值,指示是否将网格坐标与输入张量的角点对齐。如果设置为 True,则网格坐标被视为指向像素的角点;如果设置为 False,则网格坐标被视为指向像素之间的中心点。默认值为 None,此时与 align_corners=False 相同。
        # 功能描述 :
        # F.grid_sample 函数根据 grid 中的坐标网格对 input 张量进行采样。坐标网格的值通常在 [-1, 1] 之间,(-1, -1) 表示输入张量左上角的元素,(1, 1) 表示右下角的元素。该函数可以使用双线性插值或最近邻插值来计算采样点的值。
        # 返回值 :
        # 返回采样后的输出张量,其形状为(N, C, H_out, W_out)或(N, C, D_out, H_out, W_out),取决于输入张量和网格的形状。

        # bs*num_heads, embed_dims, num_queries, num_points
        # 使用 grid_sample 函数对当前尺度的特征图 value_l_ 进行采样,采样位置由 sampling_grid_l_ 指定。采样模式为双线性插值( bilinear ),填充模式为零( zeros ),并且不使用对齐角( align_corners=False )。
        sampling_value_l_ = F.grid_sample(
            value_l_, sampling_grid_l_, mode="bilinear", padding_mode="zeros", align_corners=False
        )
        # 将当前尺度的采样值 sampling_value_l_ 添加到列表 sampling_value_list 中。
        sampling_value_list.append(sampling_value_l_)
        # 这个循环对每个尺度的特征图进行采样,得到每个查询点的采样值。这些采样值将用于后续的加权求和,以生成最终的注意力输出。通过在每个尺度上进行采样,模型能够捕捉到不同尺度的特征信息,从而提高对空间关系的感知能力。
    # 这段代码是多尺度可变形注意力机制中的最后几步,用于计算最终的输出。
    # (bs, num_queries, num_heads, num_levels, num_points) ->
    # (bs, num_heads, num_queries, num_levels, num_points) ->
    # (bs, num_heads, 1, num_queries, num_levels*num_points)
    # 对注意力权重进行转置和重塑,以适应后续的计算。
    # attention_weights.transpose(1, 2) :将 attention_weights 张量进行转置,交换 num_queries 和 num_heads 维度的位置。
    # reshape(bs * num_heads, 1, num_queries, num_levels * num_points) :将转置后的张量重塑为新的维度,其中 bs * num_heads 是批量大小和头数的乘积, 1 是一个额外的维度, num_queries 是查询的数量, num_levels * num_points 是所有级别的采样点总数。
    attention_weights = attention_weights.transpose(1, 2).reshape(
        bs * num_heads, 1, num_queries, num_levels * num_points
    )
    # 计算加权和,并将结果重塑为最终输出的形状。
    # torch.stack(sampling_value_list, dim=-2) :将 sampling_value_list 中的张量沿着倒数第二个维度堆叠起来,形成一个新维度。
    # flatten(-2) :将堆叠后的张量在倒数第二个维度上展平,即将 num_levels 和 num_points 合并。
    # * attention_weights :将展平后的采样值张量与 attention_weights 张量相乘,执行逐元素的乘法。
    # .sum(-1) :沿着最后一个维度(即 num_levels * num_points )对乘积进行求和,将所有采样点的贡献聚合起来。
    # .view(bs, num_heads * embed_dims, num_queries) :将求和后的张量重塑为最终的输出形状,其中 bs 是批量大小, num_heads * embed_dims 是合并后的嵌入维度, num_queries 是查询的数量。
    output = (
        (torch.stack(sampling_value_list, dim=-2).flatten(-2) * attention_weights)
        .sum(-1)
        .view(bs, num_heads * embed_dims, num_queries)
    )
    # 将输出张量进行转置,并确保其在内存中是连续的,然后返回,形状为 (batch_size, num_queries, num_heads * embed_dims) 。
    # output.transpose(1, 2) :将输出张量再次转置,交换 num_heads * embed_dims 和 num_queries 维度的位置。
    # .contiguous() :确保张量在内存中是连续存储的,这对于某些 PyTorch 操作是必要的,特别是当张量需要被传递给 CUDA 时。
    return output.transpose(1, 2).contiguous()
    # 这段代码将不同尺度的采样值与对应的注意力权重相乘,然后对所有采样点的贡献进行求和,最后将结果重塑并转置为最终的输出张量。这个输出张量包含了每个查询在所有尺度上的加权特征表示,可以用于后续的网络层。
# multi_scale_deformable_attn_pytorch 函数实现了多尺度可变形注意力机制,它通过在不同尺度的特征图上采样并加权,生成最终的输出。这种机制能够捕捉到不同尺度的特征信息,增强模型对空间关系的感知能力。

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

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

相关文章

如何在鸿蒙本地模拟器中使用HDC工具

引言 HDC是指华为设备连接(Huawei Device Connector)工具。它的作用类似Android开发的ADB工具。在华为鸿蒙(HarmonyOS)操作系统的开发过程中,HDC工具起到了至关重要的作用。它允许开发者在开发主机(如 PC&…

ruoyi 分页 查询超出后还有数据; Mybatis-Plus 分页 超出后还有数据

修改:MybatisPlusConfig 类中 分页合理化修改为:paginationInnerInterceptor.setOverflow(false);

Unity中实现转盘抽奖效果(二)

如果要使转盘停止时转到到指定位置,应该如何做? 实现思路: 也就是在需要停止的分数的区间范围内,随机一个角度值,然后反推需要在哪个角度开始减速,如果转盘的当前角度和需要开始减速的角度有差值&#xf…

苍穹外卖04——Redis初入门 在店铺打烊or营业状态管理功能中的使用

Redis入门 redis简介 它以键值对的形式存储数据在内存中,并且以极高的性能和灵活性而著称,通常用于缓存、消息代理以及持久化数据。 - 基于内存存储,读写性能高- 适合存储热点数据(热点商品、资讯、新闻)- 企业应用广泛Windows版下载地址:https://github.com/microsoft…

深度学习每周学习总结R2(RNN-天气预测)

🍨 本文为🔗365天深度学习训练营 中的学习记录博客R5中的内容,为了便于自己整理总结起名为R2🍖 原作者:K同学啊 | 接辅导、项目定制 目录 0. 总结1. RNN介绍a. 什么是 RNN?RNN 的一般应用场景 b. 传统 RNN …

CUDA与Microsoft Visual Studio不兼容问题

简介:在安装一些 python库时,涉及到第三方库(特别是需要引用 C 代码)时,通常的安装方式会涉及到编译过程,通常称为"源代码安装"(source installation),或是 “…

WordPress网站中如何修复504错误

504网关超时错误是非常常见的一种网站错误。这种错误发生在上游服务器未能在规定时间内完成请求的情况下,对访问者而言,出现504错误无疑会对访问体验大打折扣,从而对网站的转化率和收入造成负面影响。 504错误通常源于服务器端或网站本身的问…

Springboot 升级带来的Swagger异常

当升级到Springboot 2.6.0 以上的版本后,Swagger 就不能正常工作了, 启动时报如下错误。当然如果你再使用sping boot Actuator 和 Springfox, 也会引起相关的NPE error. (github issue: https://github.com/springfox/springfox/issues/3462) NFO | jvm 1 | 2022/04…

发现API安全风险,F5随时随地保障应用和API安全

分析数据显示,目前超过90%的基于Web的网络攻击都以API端点为目标,试图利用更新且较少为人所知的漏洞,而这些漏洞通常是由安全团队未主动监控的API所暴露。现代企业需要一种动态防御策略,在风险升级成代价高昂、令人警惕且往往无法…

【数据结构】(Python)差分数组。差分数组与树状数组结合

差分数组: 基于原数组构造的辅助数组。用于区间修改、单点查询。区间修改的时间复杂度O(1)。单点查询的时间复杂度O(n)。差分数组的元素:第一个元素等于原数组第一个元素,从第二个元素开始是原数组对应下标的元素与前一个元素的差&#xff0…

12.30-1-5学习周报

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 文章链接摘要Abstract一、方法介绍1.HAT-CIR2.Horde3.DWGRNet 二、实验总结 文章链接 https://arxiv.org/pdf/2405.04101 摘要 本博客介绍了论文《Continual lea…

Android OpenGl(二) Shader

一、Shader 1、什么是Shader,为什么要使用Shder (1)shader运行在gpu上的小程序 (2)以前使用固定管线,但缺点是灵活度不够,无法满足复杂需求,为了解决固定管线的缺点,出…

【LeetCode】200、岛屿数量

【LeetCode】200、岛屿数量 文章目录 一、并查集1.1 并查集1.2 多语言解法 二、洪水填充 DFS2.1 洪水填充 DFS 一、并查集 1.1 并查集 // go var sets int var father [90000]intfunc numIslands(grid [][]byte) int {n, m : len(grid), len(grid[0])build(grid, n, m)for i …

[最佳方法] 如何将视频从 Android 发送到 iPhone

概括 将大视频从 Android 发送到 iPhone 或将批量视频从 iPhone 传输到 Android 并不是一件容易的事情。也许您已经尝试了很多关于如何将视频从 Android 发送到 iPhone 15/14 的方法,但都没有效果。但现在,通过本文中的这 6 种强大方法,您可…

MetaRename for Mac,适用于 Mac 的文件批量重命名工具

在处理大量文件时,为每个文件手动重命名既耗时又容易出错。对于摄影师、设计师、开发人员等需要频繁处理和整理文件的专业人士来说,找到一款能够简化这一过程的工具是至关重要的。MetaRename for Mac 就是这样一款旨在提高工作效率的应用程序&#xff0c…

QEMU网络配置简介

本文简单介绍下qemu虚拟机网络的几种配置方式。 通过QEMU的支持,常见的可以实现以下4种网络形式: 基于网桥(bridge)的虚拟网络。基于NAT(Network Addresss Translation)的虚拟网络。QEMU内置的用户模式网…

Elasticsearch向量检索需要的数据集以及768维向量生成

Elasticsearch8.17.0在mac上的安装 Kibana8.17.0在mac上的安装 Elasticsearch检索方案之一:使用fromsize实现分页 快速掌握Elasticsearch检索之二:滚动查询(scrool)获取全量数据(golang) Elasticsearch检索之三:官方推荐方案search_after…

MySQL:安装配置(完整教程)

这里写目录标题 一、MySQL 简介二、下载 MySQL三、安装 MySQL四、配置环境变量五、配置 MySQL5.1 初始化 MySQL5.2 启动 MySQL 服务 六、修改 MySQL 密码七、卸载 MySQL八、结语 一、MySQL 简介 MySQL 是一款广泛使用的开源关系型数据库管理系统(RDBMS)…

您的公司需要小型语言模型

当专用模型超越通用模型时 “越大越好”——这个原则在人工智能领域根深蒂固。每个月都有更大的模型诞生,参数越来越多。各家公司甚至为此建设价值100亿美元的AI数据中心。但这是唯一的方向吗? 在NeurIPS 2024大会上,OpenAI联合创始人伊利亚…

如何用CSS3创建圆角矩形并居中显示?

在网页设计中,圆角矩形因其美观和现代感而被广泛使用,居中显示元素也是一个常见的需求。今天,我们将学习如何使用CSS3的border-radius属性来创建圆角矩形,并将其居中显示在页面上。 如果你正在学习CSS,那么这个实例将非…