YOLOv9-0.1部分代码阅读笔记-experimental.py
experimental.py
models\experimental.py
目录
experimental.py
1.所需的库和模块
2.class Sum(nn.Module):
3.class MixConv2d(nn.Module):
4.class Ensemble(nn.ModuleList):
5.def attempt_load(weights, device=None, inplace=True, fuse=True):
1.所需的库和模块
import mathimport numpy as np
import torch
import torch.nn as nnfrom utils.downloads import attempt_download
2.class Sum(nn.Module):
# 这段代码定义了一个名为 Sum 的类,它是一个继承自 nn.Module 的 PyTorch 神经网络模块。这个模块的目的是将多个输入张量( x )相加,并且可以选择性地应用权重。
# 这个模块的设计灵感来源于论文 "EfficientDet: Scalable and Efficient Object Detection" 中提到的加权双向特征金字塔网络(Weighted Bi-directional Feature Pyramid Network, BiFPN)。
# 定义了一个继承自 nn.Module 的新类 Sum ,这是一个 PyTorch 神经网络模块的基类。
class Sum(nn.Module):# Weighted sum of 2 or more layers https://arxiv.org/abs/1911.09070 2 层或更多层的加权和 https://arxiv.org/abs/1911.09070。# Sum 类的构造函数,它接受两个参数。# 1.n :输入的数量。# 2.weight :一个布尔值,表示是否应用权重,默认为 False 。def __init__(self, n, weight=False): # n: number of inputs# 调用基类的构造函数,这是 Python 中继承机制的一部分,用于确保基类被正确初始化。super().__init__()# 将传入的 weight 参数保存为类的成员变量。self.weight = weight # apply weights boolean# 创建一个迭代器对象,用于在 forward 方法中迭代输入张量。self.iter = range(n - 1) # iter object# 如果 weight 参数为 True ,则执行以下操作。if weight:# 创建一个可学习的参数 w ,它是一个 PyTorch 参数( nn.Parameter ),这意味着它的值可以在训练过程中被优化。参数的初始值是通过 torch.arange(1.0, n) / 2 生成的,然后取负值。 requires_grad=True 表示需要计算这些权重的梯度。self.w = nn.Parameter(-torch.arange(1.0, n) / 2, requires_grad=True) # layer weights# 定义了 forward 方法,这是神经网络模块的前向传播方法,它接受输入张量 1.x 。def forward(self, x):# 初始化输出 y 为第一个输入张量 x[0] 。y = x[0] # no weight# 如果 weight 为 True ,则执行以下操作。if self.weight:# 权重参数 self.w 通过 sigmoid 函数激活,然后乘以 2,以确保权重在 0 到 2 之间。w = torch.sigmoid(self.w) * 2# 迭代剩余的输入张量,并将它们与对应的权重相乘后累加到 y 。for i in self.iter:y = y + x[i + 1] * w[i]# 如果 weight 为 False ,则执行以下操作。else:# 迭代剩余的输入张量,并将它们直接累加到 y 。for i in self.iter:y = y + x[i + 1]# 返回最终的输出 y 。return y
# 这个模块可以用于将多个输入张量相加,并且可以选择是否对每个输入张量应用不同的权重。如果启用权重,权重将通过训练过程进行优化。
3.class MixConv2d(nn.Module):
# 这段代码定义了一个名为 MixConv2d 的类,它是一个继承自 nn.Module 的 PyTorch 神经网络模块。这个模块实现了混合深度卷积(Mixed Depth-wise Convolution),这是一种在单个卷积操作中混合使用不同核大小的技术。
# 定义了一个名为 MixConv2d 的新类,它继承自 PyTorch 的 nn.Module 类。
class MixConv2d(nn.Module):# Mixed Depth-wise Conv https://arxiv.org/abs/1907.09595# MixConv2d 类的构造函数,它接受以下参数。# 1.c1 :输入通道数。# 2.c2 :输出通道数。# 3.k :一个元组,包含不同的核大小,默认为 (1, 3) 。# 4.s :步长,默认为 1 。# 5.equal_ch :一个布尔值,表示是否每个分组的通道数相等,默认为 True 。def __init__(self, c1, c2, k=(1, 3), s=1, equal_ch=True): # ch_in, ch_out, kernel, stride, ch_strategy# 调用基类的构造函数。super().__init__()# 获取核大小的数量。n = len(k) # number of convolutions# 如果 equal_ch 为 True ,则每个分组的通道数相等。if equal_ch: # equal c_ per group# 生成一个从 0 到 n-1 的等间隔序列,长度为 c2 。i = torch.linspace(0, n - 1E-6, c2).floor() # c2 indices# 计算每个分组的通道数。c_ = [(i == g).sum() for g in range(n)] # intermediate channels# 如果 equal_ch 为 False ,则使用线性方程组求解每个分组的通道数,使得权重数量相等。else: # equal weight.numel() per group# 创建一个列表 b ,其中包含 c2 (总的输出通道数)后面跟着 n 个零。这个列表将作为线性方程组的 b 向量。b = [c2] + [0] * n# 创建一个 n+1 行 n 列的单位矩阵 a ,然后通过 k=-1 参数将矩阵向下移动一个位置,这样可以得到一个除了第一列以外都是零的矩阵。a = np.eye(n + 1, n, k=-1)# 通过 np.roll 函数将矩阵 a 沿列方向向右移动一个位置,然后从原矩阵 a 中减去这个移动后的矩阵。这样做的结果是,除了第一列和最后一列以外,其他列的对角线上的元素会变成 -1 。a -= np.roll(a, 1, axis=1)# 将矩阵 a 中的每个元素乘以对应的核大小的平方( k 是一个包含核大小的元组)。a *= np.array(k) ** 2# 将矩阵 a 的第一行设置为全1,这是因为我们想要在第一组卷积中使用所有的输出通道。a[0] = 1# 使用 numpy 的 linalg.lstsq 函数解决线性方程组 ax = b 。 rcond=None 参数表示不对矩阵进行奇异值截断。函数返回的是方程组的解,我们取第一个返回值(即解向量),并使用 round 函数将解向量中的值四舍五入到最近的整数。这个解向量 c_ 表示每个卷积核大小对应的输出通道数。c_ = np.linalg.lstsq(a, b, rcond=None)[0].round() # solve for equal weight indices, ax = b# 通过这种方式,我们可以确保每个卷积核大小对应的权重数量大致相等,从而在不同的卷积核大小之间平衡模型的复杂度。这种方法在设计深度学习模型时非常有用,因为它可以帮助我们更有效地利用模型的参数。# 创建一个模块列表,包含不同核大小的卷积层。self.m = nn.ModuleList([# groups=math.gcd(c1, int(c_)) :分组数,使用 math.gcd 函数计算输入通道数和输出通道数的最大公约数,这样可以确保每个分组的通道数是整数。# bias=False :不使用偏置项,因为后面会使用批量归一化层,它会包含偏置项。nn.Conv2d(c1, int(c_), k, s, k // 2, groups=math.gcd(c1, int(c_)), bias=False) for k, c_ in zip(k, c_)])# 通过这行代码,为 MixConv2d 类创建了一个包含多个具有不同核大小的卷积层的 ModuleList 。在前向传播时,每个卷积层都会对输入特征图进行卷积操作,然后将结果拼接起来,形成最终的输出特征图。这种方法可以提高模型对不同尺度特征的捕捉能力,同时保持计算效率。# 创建一个批量归一化层。self.bn = nn.BatchNorm2d(c2)# 创建一个激活层,SiLU(也称为Sigmoid-Weighted Linear Unit)。self.act = nn.SiLU()# 定义了前向传播的方法,它接受一个输入。# 1.x :这是一个张量(tensor),代表输入的特征图(feature maps)。def forward(self, x):# [self.m] :这是一个包含多个卷积层的 ModuleList ,每个卷积层都有不同的核大小。# for m in self.m :这是一个循环,遍历 ModuleList 中的每个卷积层。# m(x) :对每个卷积层应用输入 x ,得到每个卷积层的输出。# torch.cat([m(x) for m in self.m], 1) :使用 torch.cat 函数将所有卷积层的输出在通道维度(维度1)上拼接起来。这样,如果每个卷积层的输出通道数不同,它们仍然可以被合并成一个单一的张量。# self.bn(...) :将拼接后的张量传递给批量归一化层( BatchNorm2d ),这有助于规范化数据,使其具有相同的均值和方差,从而提高模型的训练效率和性能。# self.act(...) :最后,将归一化后的张量传递给激活函数层(在这里是 SiLU 即 Sigmoid-Weighted Linear Unit ),这为模型引入非线性,使其能够学习更复杂的特征。return self.act(self.bn(torch.cat([m(x) for m in self.m], 1)))# forward 方法将输入 x 通过不同核大小的卷积层,然后将这些卷积层的输出在通道维度上拼接,接着进行批量归一化和激活,最终输出的结果就是模型的前向传播结果。这种方法允许模型在单个操作中利用不同尺度的局部感受野,从而提高其对不同尺度特征的捕捉能力。
# 这个 MixConv2d 模块可以根据核大小的不同,将输入通道分割成不同的组,并在每个组上应用不同大小的卷积核。这种方法可以提高模型的表达能力,同时保持计算效率。
4.class Ensemble(nn.ModuleList):
# 这段代码定义了一个名为 Ensemble 的类,它继承自 PyTorch 的 nn.ModuleList 。这个类用于实现模型集成(ensemble),即将多个模型的预测结果结合起来以提高性能。
# 定义了一个名为 Ensemble 的新类,它继承自 PyTorch 的 nn.ModuleList 类。
class Ensemble(nn.ModuleList):# Ensemble of models# Ensemble 类的构造函数。def __init__(self):# 调用基类的构造函数,初始化 ModuleList 。super().__init__()# 定义了 forward 方法,这是神经网络模块的前向传播方法。它接受以下参数。# 1.x :输入数据。# 2.augment :一个布尔值,表示是否应用数据增强。# 3.profile :一个布尔值,表示是否进行性能分析。# 4.visualize :一个布尔值,表示是否进行可视化。def forward(self, x, augment=False, profile=False, visualize=False):# 列表推导式,它遍历 Ensemble 中的每个模块(即每个模型),将输入 x 和其他参数传递给每个模型的 forward 方法,并收集每个模型的输出。这里每个模型的 forward 方法返回一个元组,并且只取元组的第一个元素(即预测结果)。y = [module(x, augment, profile, visualize)[0] for module in self]# y = torch.stack(y).max(0)[0] # max ensemble# y = torch.stack(y).mean(0) # mean ensemble# 使用 torch.cat 函数将所有模型的输出在通道维度(维度1)上拼接起来。这种集成方法通常用于非最大抑制(NMS)集成,其中不同模型的预测结果被合并,然后应用 NMS 来去除重叠的检测框。y = torch.cat(y, 1) # nms ensemble# 返回拼接后的输出 y 和一个 None 值,表示没有额外的输出。在 PyTorch 中, None 通常用于表示没有额外的输出或信息。return y, None # inference, train output
# 这个 Ensemble 类提供了一种简单的方式来集成多个模型的预测结果。通过这种方式,可以提高模型的鲁棒性和准确性,特别是在目标检测等任务中。集成方法可以根据具体任务的需求进行调整,例如使用最大值集成( max ensemble )或平均值集成( mean ensemble )。
5.def attempt_load(weights, device=None, inplace=True, fuse=True):
# 这段代码定义了一个名为 attempt_load 的函数,它用于加载一个或多个预训练的模型权重,并创建一个模型集合( Ensemble )。这个函数处理了模型权重的加载、兼容性更新和模型融合。
# 定义了 attempt_load 函数,它接受以下参数。
# 1.weights :模型权重的路径或路径列表。
# 2.device :模型运行的设备,默认为 None 。
# 3.inplace :是否在原地修改模型参数,默认为 True 。
# 4.fuse :是否融合模型中的某些层以提高效率,默认为 True 。
def attempt_load(weights, device=None, inplace=True, fuse=True):# Loads an ensemble of models weights=[a,b,c] or a single model weights=[a] or weights=a# 从 models.yolo 模块导入 Detect 和 Model 类。from models.yolo import Detect, Model# 这段代码是 attempt_load 函数中的一部分,它负责加载一个或多个预训练模型的权重,并对每个模型进行兼容性更新,最后将它们添加到一个 Ensemble 实例中。# 创建一个 Ensemble 实例,这个实例将用来存储多个模型。model = Ensemble()# 遍历 weights 参数。如果 weights 是一个列表,直接遍历它;如果不是列表,将其转换为一个只包含该权重的列表,这样就可以统一处理单个权重和权重列表的情况。for w in weights if isinstance(weights, list) else [weights]:# 对于每个权重文件,首先尝试下载(如果文件不存在),然后使用 torch.load 加载权重文件。 map_location='cpu' 确保权重文件被加载到 CPU 上。# def attempt_download(file, repo='ultralytics/yolov5', release='v7.0'): -> 尝试从 GitHub 仓库的发布资产中下载文件,如果本地找不到该文件。返回处理后的文件路径。返回文件的路径,以字符串形式。 -> return file / return str(file)ckpt = torch.load(attempt_download(w), map_location='cpu') # load# 从加载的权重中,尝试获取 ema (指数移动平均)键对应的模型状态,如果没有,则获取 model 键对应的状态。然后将模型状态转移到指定的 device 上,并转换为浮点数(FP32)。ckpt = (ckpt.get('ema') or ckpt['model']).to(device).float() # FP32 model# Model compatibility updates# 检查加载的模型是否有 stride 属性,如果没有,则为其设置一个默认值。if not hasattr(ckpt, 'stride'):ckpt.stride = torch.tensor([32.])# 检查模型是否有 names 属性,并且该属性是否是列表或元组。如果是,将其转换为字典,其中索引作为键,原始列表或元组中的元素作为值。if hasattr(ckpt, 'names') and isinstance(ckpt.names, (list, tuple)):ckpt.names = dict(enumerate(ckpt.names)) # convert to dict# 如果 fuse 参数为 True 且模型有 fuse 方法,则调用该方法来融合模型中的某些层,然后设置模型为评估模式( eval )。如果没有 fuse 方法或 fuse 参数为 False ,则直接将模型设置为评估模式。最后,将模型添加到 Ensemble 实例中。model.append(ckpt.fuse().eval() if fuse and hasattr(ckpt, 'fuse') else ckpt.eval()) # model in eval mode# 通过这段代码,可以将多个预训练模型的权重加载并集成到一个 Ensemble 实例中,每个模型都被设置为评估模式,并且进行了必要的兼容性更新。这样的集成模型可以用于提高预测的准确性和鲁棒性。# 这段代码是 attempt_load 函数的另一部分,它负责对加载的模型进行模块兼容性更新,并在模型集合中只有一个模型时返回该单个模型。# Module compatibility updates# 模块兼容性更新。# 遍历 Ensemble 实例 model 中的所有模块。 modules() 方法返回模型中所有模块的迭代器。for m in model.modules():# 获取当前模块 m 的类型。t = type(m)# 检查模块类型是否为特定的激活函数类或自定义的 Detect 和 Model 类。如果是,执行以下操作。if t in (nn.Hardswish, nn.LeakyReLU, nn.ReLU, nn.ReLU6, nn.SiLU, Detect, Model):# 设置模块的 inplace 属性。这是为了兼容 PyTorch 1.7.0 版本,因为在新版本中,某些操作默认是原地(in-place)执行的,这可以通过设置 inplace=True 来启用。m.inplace = inplace # torch 1.7.0 compatibility# if t is Detect and not isinstance(m.anchor_grid, list):# delattr(m, 'anchor_grid')# setattr(m, 'anchor_grid', [torch.zeros(1)] * m.nl)# 检查模块类型是否为 nn.Upsample 并且没有 recompute_scale_factor 属性。如果是,执行以下操作。elif t is nn.Upsample and not hasattr(m, 'recompute_scale_factor'):# 为模块添加 recompute_scale_factor 属性并设置为 None 。这是为了兼容 PyTorch 1.11.0 版本,因为在新版本中, Upsample 模块的行为有所变化。# recompute_scale_factor 属性在 PyTorch 的 nn.Upsample 模块中用于控制插值过程中缩放因子( scale_factor )的计算方式。具体来说,这个属性影响如何根据输入和输出张量的大小来计算插值时使用的缩放因子。m.recompute_scale_factor = None # torch 1.11.0 compatibility# Return model# 返回模型。# 检查 Ensemble 实例 model 中是否只有一个模型。if len(model) == 1:# 如果只有一个模型,直接返回该模型。 model[-1] 表示 Ensemble 实例中的最后一个模型,也就是唯一的模型。return model[-1]# 这段代码确保了加载的模型与当前 PyTorch 版本的兼容性,并且提供了一种简洁的方式来处理只包含单个模型的模型集合。通过这种方式, attempt_load 函数可以灵活地处理单个模型和模型集合,同时确保模型在不同版本的 PyTorch 中都能正常工作。# 这段代码是 attempt_load 函数的最后一部分,它负责完成模型集合( Ensemble )的设置,并返回这个集合。# Return detection ensemble# 打印一条消息,表明已经使用提供的权重创建了一个模型集合,并显示这些权重。print(f'Ensemble created with {weights}\n') # 使用 {weights} 创建的集成。# 遍历一个包含属性名称的元组。for k in 'names', 'nc', 'yaml':# 对于每个属性名称,使用 setattr 函数将 Ensemble 实例的对应属性设置为第一个模型( model[0] )的同名属性的值。这样做是为了确保模型集合具有与单个模型相同的属性,例如类别名称( names )、类别数量( nc )和模型配置( yaml )。# setattr(model, k, getattr(model[0], k)) :对于每个属性名称 k ,这行代码执行以下操作 :# getattr(model[0], k) :获取模型集合中第一个模型( model[0] )的属性 k 的值。# setattr(model, k, ...) :将这个值设置为整个模型集合对象( model )的属性 k 。setattr(model, k, getattr(model[0], k))# 计算模型集合中所有模型的最大步长( stride ),并将其设置为模型集合的 stride 属性。 torch.argmax 找到最大步长值的索引,然后通过索引访问对应的模型,并获取其 stride 属性。model.stride = model[torch.argmax(torch.tensor([m.stride.max() for m in model])).int()].stride # max stride# 断言检查模型集合中的所有模型是否具有相同数量的类别( nc )。如果不一致,则抛出异常,并显示每个模型的类别数量。assert all(model[0].nc == m.nc for m in model), f'Models have different class counts: {[m.nc for m in model]}' # 模型有不同的类别数:{[m.nc for m in model]。# 返回最终构建的模型集合( Ensemble )。return model# 这段代码确保了模型集合具有一致的属性,并且所有模型都具有相同数量的类别。通过设置最大步长,它还确保了模型集合可以正确地处理不同分辨率的输入。最后,它返回构建好的模型集合,这个集合可以用于推理或进一步的训练。
# 这个函数提供了一个灵活的方式来加载和集成多个模型,同时处理了模型的兼容性问题。通过这种方式,可以轻松地将多个预训练模型组合起来,以提高模型的性能和鲁棒性。# 模型集合( Ensemble )中包含的每个模型都使用各自的 yaml 属性。当你创建一个模型集合并将多个模型添加到其中时,每个模型都保留自己的配置信息,包括 yaml 属性。
# 在 attempt_load 函数中,代码段:
# for k in 'names', 'nc', 'yaml':
# setattr(model, k, getattr(model[0], k))
# 将模型集合中第一个模型的 yaml 属性复制到 模型集合对象 上,使得你可以通过模型集合对象访问这个属性。但这并不意味着集合中的其他模型的 yaml 属性被修改或覆盖。每个模型仍然保持自己的独立 yaml 配置。
# 如果你需要访问集合中某个特定模型的 yaml 属性,你应该直接访问那个模型实例的属性。例如:
# yaml_config_for_model = model[0].yaml # 获取模型集合中第一个模型的 yaml 配置
# 在这里, model[0] 表示模型集合中的第一个模型,你可以通过索引来访问集合中的其他模型,并获取它们的 yaml 属性。每个模型的 yaml 属性都是独立的,反映了它们各自的配置信息。
相关文章:
YOLOv9-0.1部分代码阅读笔记-experimental.py
experimental.py models\experimental.py 目录 experimental.py 1.所需的库和模块 2.class Sum(nn.Module): 3.class MixConv2d(nn.Module): 4.class Ensemble(nn.ModuleList): 5.def attempt_load(weights, deviceNone, inplaceTrue, fuseTrue): 1.所需的库和模块…...
如何高效获取Twitter数据:Apify平台上的推特数据采集解决方案
引言 在数据分析和市场研究领域,Twitter(现在的X)数据一直是重要的信息来源。但是,自从Twitter更改API定价策略后,获取数据的成本大幅提升。本文将介绍一个经济实惠的替代方案。 为什么需要Twitter数据? …...
【蓝凌表单】JSP组件常用语法整理
JSP组件常用语法整理 必填非必填写法//必填 $("[name=extendDataFormInfo.value(fd_344677482769e2)]").attr("validate","requiredvalue"); //非必填 $(...
设定“例外规则”:不完美也是完美
完美主义是一种追求极致的心态,它驱使我们不断追求更高的标准和更好的结果。然而,生活并不总是按照我们的计划进行,有时候我们需要灵活应对,设定一些“例外规则”来适应那些不完美的时刻。以下是一些实际的例子,展示如…...
01《Python数据分析》数据分析初探章节总结
目录 1 概述1.1 数据分析定义1.2 数据分析目标1.3 数据分析分类 2 数据分析方法3 数据分析流程4 寻找问题原因5 典型问题参考学习 1 概述 1.1 数据分析定义 数据分析1就是:用适当的统计分析方法对收集来的大量数据进行分析,提取有用信息和形成结论&…...
java web 实验五 Servlet控制层设计(设计性)
实验五 Servlet控制层设计(设计性) //代码放在资源包里了 实验目的 熟悉Servlet的基本语法。掌握采用HTML、JS、JDBC、JSP、Servlet和四层结构的综合应用。实验要求 本实验要求每个同学单独完成;调试程序要记录调试过程中出现的问题及解决…...
Timestamp Unix时间戳在线转换 - 加菲工具
Timestamp Unix时间戳在线转换 打开网站 加菲工具 选择“时间戳转换” 或者直接打开: https://www.orcc.online/tools/timestamp 在前半部分输入框输入时间/时间戳,点击“转换>>”按钮,即可转换完成 得到转换结果...
ABAP 订单多次开票,显示多张开票凭证
一、业务背景 在实际业务上,同一笔销售订单可能分多次发货,多次开票,因此再销售订单状态报表上就要体现该过程:对于同一张销售订单,分多次开票时,按照发票和订单行项目,显示开票数量与为开票数…...
源码安装编译gcc-12
下载gcc12 https://link.zhihu.com/?targethttps%3A//github.com/gcc-mirror/gcc/archive/refs/tags/releases/gcc-12.2.0.tar.gz 解压并执行相关依赖下载 ./contrib/download_prerequisites make && make install 默认装在/usr/local下, 如果要自己指定…...
VGGNet:深度学习中的卷积神经网络经典之作
目录 编辑 引言 VGGNet的历史背景 VGGNet的特点 1. 深度网络结构 2. 小卷积核的使用 3. 多尺度训练 4. 参数量的优化 5. 去除局部响应归一化 6. 优秀的特征提取能力 VGGNet的应用案例 VGGNet的代码复现 代码解析 结论 引言 在深度学习的浪潮中,卷积…...
opencv所有常见函数
一、opencv图像操作 二、opencv图像的数值运算 三、opencv图像的放射变换 四、opencv空间域图像滤波 五、图像灰度化与直方图 六、形态学图像处理 七、阈值处理与边缘检测 八、轮廓和模式匹配...
Shell语言基础语法(3)
目录 简介 一、流程控制 1、if 语句 2、case 选择 3、while 循环 4、for 循环 5、扩展使用select 二、函数 1、函数的定义 2、函数的调用 3、函数的传参 4、函数的返回值 5、局部变量 6、全局变量 总结 简介 Shell 脚本是一种强大的工具,广泛用于 Lin…...
Linux CentOS 9搭建Hadoop3集群
1. 引言 本教程旨在介绍在Linux上安装Hadoop 2. 前提条件 2.1 安装JDK 安装Hadoop,必须首先安装JDK,并配置环境变量(此处不做详细描述) Jdk官网(https://www.oracle.com/java/technologies/javase/javase8u211-later-archive…...
加速科技精彩亮相ICCAD 2024
12月11日—12日 ,中国集成电路设计业的年度盛会——ICCAD 2024在上海世博馆隆重举行。本次活动以“智慧上海,芯动世界”为主旨,汇聚了众多业界精英,共同探讨集成电路产业的未来。作为半导体测试行业领军企业,加速科技携…...
canvas(填充描边,绘制矩形、路径、文本、图像,变换,阴影,渐变等)
一、 基本的画布功能 创建 <canvas> 元素时至少要设置其 width 和 height 属性,这样才能告诉浏览器在多大面积上绘 图。出现在开始和结束标签之间的内容是后备数据,会在浏览器不支持 <canvas> 元素时显示。比如: <canv…...
STM8单片机学习笔记·GPIO的片上外设寄存器
目录 前言 IC基本定义 三极管基础知识 单片机引脚电路作用 STM8GPIO工作模式 GPIO外设寄存器 寄存器含义用法 CR1:Control Register 1 CR2:Control Register 2 ODR:Output Data Register IDR:Input Data Register 赋值…...
2-2-18-16 QNX系统架构之自适应分区
阅读前言 本文以QNX系统官方的文档英文原版资料为参考,翻译和逐句校对后,对QNX操作系统的相关概念进行了深度整理,旨在帮助想要了解QNX的读者及开发者可以快速阅读,而不必查看晦涩难懂的英文原文,这些文章将会作为一个…...
【Python网络爬虫笔记】11- Xpath精准定位元素
目录 一、Xpath 在 Python 网络爬虫中的作用(一)精准定位元素(二)应对动态网页(三)数据结构化提取 二、Xpath 的常用方法(一)节点选取(二)谓词筛选࿰…...
Rustdesk 安装客户端以及自己搭建服务器跑通参考资料
Rustdesk 安装客户端以及自己搭建服务器跑通参考资料 下载客户端: rustdesk客户端-github下载地址 windows正常安装就行了,ubuntu安装参考下面: ubuntu安装rustdesk客户端 在centos中利用docker安装rustdesk-server,先进行cento…...
源码编译jdk7 超详细教程 openjdk7
关于源代码 当前的openJDK的源代码已经被发布到了github上了,所以我们可以直接从github上下载到。 OpenJDK7u源码托管地址:https://github.com/openjdk/jdk7u 带后缀U的地址,或者发行的jdk包,表示当前版本下的持续跟新版。而他…...
如何实现日期选择窗口
文章目录 1 概念介绍2 使用方法3 示例代码我们在上一章回中介绍了TimePicker Widget相关的内容,本章回中将介绍DatePickerDialog Widget.闲话休提,让我们一起Talk Flutter吧。 1 概念介绍 我们在这里说的DatePickerDialog是一种弹出窗口,只不过窗口的内容固定显示为日期,它…...
Spring Security 6 系列之一 - 开篇入门
之所以想写这一系列,是因为之前工作过程中使用Spring Security,但当时基于spring-boot 2.3.x,其默认的Spring Security是5.3.x。之后新项目升级到了spring-boot 3.3.0,结果一看Spring Security也升级为6.3.0,关键是其风…...
Spring Cloud概述
1. 认识微服务 1.1 单体架构 很多创业公司早期或者传统企业会把业务的所有功能实现都打包在⼀个项⽬, 这就是单体架构. 业务的所有功能实现都打包在⼀个war包或者Jar包中, 这种⽅式就称为单体架构. 举个例子: 电商系统包括: ⽤⼾管理, 商品管理, 订单管理, ⽀付管理, 库存…...
mvc如何给action传递参数
步骤(常规方法) 新建一个控制器--LarsController.cs using Microsoft.AspNetCore.Mvc; namespace Blog.Controller; public class LarsController:Controller -----继承 {public IActionResult Index(){return View();} }获取id // program.cs中默认值是idpublic IAction…...
【银河麒麟高级服务器操作系统】有关dd及cp测试差异的现象分析详解
了解更多银河麒麟操作系统全新产品,请点击访问 麒麟软件产品专区:https://product.kylinos.cn 开发者专区:https://developer.kylinos.cn 文档中心:https://documentkylinos.cn dd现象 使用银河麒麟高级服务器操作系统执行两次…...
视频智能分析平台LiteAIServer未戴安全帽检测算法助力矿山安全:精准监督矿工佩戴安全帽情况
矿山作业环境复杂多变,安全隐患层出不穷。其中,矿工未佩戴安全帽这一行为,看似微不足道,实则潜藏着巨大的安全风险。一旦发生事故,未佩戴安全帽的矿工将极易受到重创,甚至危及生命。因此,确保每…...
整数的四舍五入----->记录每一点进步
我们知道整数类型的变量对小数部分都不感冒,只要是小数都会舍去,都让他舍去了我们还讲个P,所以接下来就是告诉你怎么不让他全都舍去。 先来试想一下如果这个数字是3.4,存到整数型变量里面是不是直接变成了3,那么我要是…...
Linux栈帧
相关寄存器&指令 寄存器 rax(accumulator):return value rbx(base) rcx(count):4st argument rdx(data):3st argument rsi(sour…...
【代码随想录day59】【C++复健】 47. 参加科学大会(dijkstra(堆优化版)精讲 );94. 城市间货物运输 I
前几天有些事情耽搁了,不过好在图论我完全不会,所以偷看代码思路也没有任何的心理负担,做起来反而相对独立思考更快一点点。 47. 参加科学大会(dijkstra(堆优化版)精讲 ) 本来一开始以为这个堆…...
【网络安全】WIFI WPA/WPA2协议:深入解析与实践
WIFI WPA/WPA2协议:深入解析与实践 1. WPA/WPA2 协议 1.1 监听 Wi-Fi 流量 解析 WPA/WPA2 的第一步是监听 Wi-Fi 流量,捕获设备与接入点之间的 4 次握手数据。然而,设备通常不会频繁连接或重新连接,为了加速过程,攻…...
穷举vs暴搜vs深搜vs回溯vs剪枝专题一>子集
题目: 两个方法本质就是决策树的画法不同 方法一解析: 代码: class Solution {private List<List<Integer>> ret;//返回结果private List<Integer> path;//记录路径,注意返回现场public List<List<Int…...
试题转excel;word转excel;大风车excel
一、问题描述 一名教师朋友,偶尔会需要整理一些高质量的题目到excel中 以往都是手动复制搬运,几百道题几乎需要一个下午的时间 关键这些事,枯燥无聊费眼睛,实在是看起来就很蠢的工作 就想着做一个工具,可以自动处理…...
Unity NTPComponent应用, 实现一个无后端高效获取网络时间的组件
无后端高效获取网络时间的组件 废话不多说,直接上源码m_NowSerivceTime 一个基于你发行游戏地区的时间偏移, 比如北京时区就是 8, 巴西就是-3,美国就是-5using Newtonsoft.Json; 如果这里报错, 就说明项目没有 NewtonsoftJson插件…...
复合机器人为生产提供精准的建议和决策支持
在现代化生产的浪潮中,智能复合机器人以其卓越的性能和高度智能化特点,正成为保障生产安全与可靠性的重要力量。 智能复合机器人具备精确的感知、判断和决策能力,能够在复杂的生产环境中自主导航、精确操作,避免了人为因素可能导致…...
springboot/ssm二手儿童绘本交易系统Java代码编写web项目闲置书籍源码
springboot/ssm二手儿童绘本交易系统Java代码编写web项目闲置书籍源码 基于springboot(可改ssm)vue项目 开发语言:Java package com.controller;import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.Map;import javax.s…...
30. Three.js案例-绘制并渲染圆弧
30. Three.js案例-绘制并渲染圆弧 实现效果 知识点 WebGLRenderer WebGLRenderer 是 Three.js 中用于渲染 3D 场景的核心类。它利用 WebGL 技术在浏览器中渲染 3D 图形。 构造器 new THREE.WebGLRenderer(parameters) 参数类型描述parametersObject可选参数对象ÿ…...
类和对象(2)
大家好,今天我们继续来学习类和对象的知识,那么今天我们来看看类的概念和类的定义相关的知识,那么话不多说,我们直接开始。 2.类定义和使用 面向对象程序设计关注的是对象,而对象是现实生活中的实体,比如:洗衣机,但是…...
240004基于ssm+maven+mysql+Java的房屋租赁系统的设计与实现
基于ssmmavenmysql的房屋租赁系统的设计与实现 1.项目描述2.运行环境3.项目截图4.源码获取 1.项目描述 该项目在原有的基础上进行了优化,包括新增了注册功能,房屋模糊查询功能,管理员和用户信息管理等功能,以及对网站界面进行了优…...
HTTP、WebSocket、gRPC 或 WebRTC:各种协议的区别
在为您的应用程序选择通信协议时,有很多不同的选择。 本文将了解四种流行的解决方案:HTTP、WebSocket、gRPC 和 WebRTC。 我们将通过深入学习其背后原理、最佳用途及其优缺点来探索每个协议。 通信方式在不断改进:变得更快、更方便、更可靠&…...
FlowNex 中的两相建模基础知识
通过 FlowNex 中的两相建模解开高效流体动力学的秘密,彻底改变制造业。 挑战 两相流是指两个不同相(通常是液体和气体)同时流动,它们具有不同的特性和行为。在制造业中,了解两相流对于优化热交换器、化学反应器和流体…...
Mysql笔记
windows安装记录Windows中Mysql安装-CSDN博客 用到的库 通过网盘分享的文件:atguigudb.sql 链接: https://pan.baidu.com/s/1YfC20c2vK9odn-XRJJwUJw 提取码: utk7 --来自百度网盘超级会员v5的分享 Mysql4中表关联关系 1.1对1,比较少用,因为完全可以一张表,当有…...
docker拉取rabbitmq镜像安装延迟队列插件
我这里使用的是rabbitmq:3.12.0-management版本作为示例 1.拉取rabbitmq镜像 docker pull rabbitmq:3.12.0-management 2.启动rabbitmq docker run -d --namerabbitmq --restartalways -p 5672:5672 -p 15672:15672 rabbitmq:3.12.0-management 在咱们拉取时如果出现连接超时可…...
创建一个谷歌插件项目dome上线流程+源码
创建一个简单的 Chrome 扩展程序,其主要功能是 JSON 格式化。用户可以通过点击扩展图标打开一个弹出窗口,在弹出窗口中输入或粘贴 JSON 数据,然后点击格式化按钮来格式化 JSON 数据 谷歌插件(即 Chrome 扩展程序)主要设…...
举例说明如何在linux下检测摄像头设备具备的功能
假设摄像头设备文件为/dev/video1 ,下面是一个专门用于检测 /dev/video1 设备能力的简化程序。这个程序将打印出设备的所有能力、格式和其他相关信息,以帮助你了解设备支持的功能。 检测 /dev/video1 设备能力的程序 #include <fcntl.h> #includ…...
win10配置子系统Ubuntu子系统(无需通过Windows应用市场)实际操作记录
win10配置子系统Ubuntu子系统(无需通过Windows应用市场)实际操作记录 参考教程 : win10配置子系统Ubuntu子系统(无需通过Windows应用市场) - 一佳一 - 博客园 开启虚拟机服务的 以管理员方式运行PowerShell运行命令。 …...
东北大学《2024年839自动控制原理真题》 (完整版)
本文内容,全部选自自动化考研联盟的:《东北大学839自控考研资料》的真题篇。后续会持续更新更多学校,更多年份的真题,记得关注哦~ 目录 2024年真题 Part1:2024年完整版真题 2024年真题...
5G中的ATG Band
Air to Ground Networks for NR是R18 NR引入的。ATG很多部分和NTN类似中的内容类似。比较明显不同的是,NTN的RF内容有TS 38.101-5单独去讲,而ATG则会和地面网络共用某些band,这部分在38.101-1中有描述。 所以会存在ATG与地面网络之间的相邻信…...
nginx负载均衡配置
目录 一、简介 二、nginx下载 二、nginx配置 四、注意点 (1)/api与/api/的区别 (2)http://gatewayserver与http://gatewayserver/的区别 一、简介 Nginx(发音为 "engine-x")是一个高性能的HTTP和反向代理服务器,也是一个IMA…...
【教学类-83-02】20241214立体书三角嘴2.0——青蛙(扁菱形嘴)
背景需求: 制作小鸡立体贺卡三角嘴,它的嘴是正菱形(四条边长度相等,类似正方形) 【教学类-83-01】20241215立体书三角嘴1.0——小鸡(正菱形嘴)-CSDN博客文章浏览阅读744次,点赞22次…...
vscode设置终端代理
转载请标明出处:小帆的帆的博客 设置终端代理 修改项目的.vscode/settings.json {"terminal.integrated.env.windows": {"http_proxy": "http://127.0.0.1:7890","https_proxy": "http://127.0.0.1:7890"}, }…...