细粒度图像分类论文阅读笔记

细粒度图像分类论文阅读笔记

  • 摘要
  • Abstract
  • 1. 用于细粒度图像分类的聚合注意力模块
    • 1.1 文献摘要
    • 1.2 研究背景
    • 1.3 本文创新点
    • 1.4 计算机视觉中的注意力机制
    • 1.5 模型方法
      • 1.5.1 聚合注意力模块
      • 1.5.2 通道注意力模块
        • 通道注意力代码实现
      • 1.5.3 空间注意力模块
        • 空间注意力代码实现
      • 1.5.4 CBAM注意力机制
        • CBAM注意力代码实现
      • 1.5.5 本文模型整体架构
    • 1.6 实验
      • 1.6.1 数据集
      • 1.6.1 实施细节
      • 1.6.2 实验结果
    • 1.7 结论
  • 总结

摘要

本周阅读了SCI二区的文章 Aggregate attention module for fine‑grained image classification,该论文解决了以往网络中的参数过多、计算过多的问题,提出了一种名为聚合注意力模块的注意力机制,可以用更少的参数对细粒度图像进行准确分类。所提出的注意力模块将通道注意力与空间注意力并行结合,有效地学习关键特征,并且可以轻松扩展到其他神经模型。本文将详细介绍该模型。

Abstract

This week I read the SCI Region 2 article Aggregate attention module for fine-grained image classification, which solves the problem of too many parameters and too much computation in the previous network by proposing an attention mechanism called aggregated attention module that can accurately classify fine-grained images with fewer parameters. The proposed attention module combines channel attention and spatial attention in parallel to learn key features efficiently and can be easily extended to other neural models. In this paper, the model is described in detail.

文献出处:Aggregate attention module for fine‑grained image classification

1. 用于细粒度图像分类的聚合注意力模块

1.1 文献摘要

注意力机制对于聚合特征和发现有区别的局部细节非常有用。网络中参数的增加会导致不必要的计算。本文提出了一种名为聚合注意力模块的注意力机制,可以用更少的参数对细粒度图像进行准确分类。 具体来说,为了平衡性能和复杂性之间的权衡,所提出的注意力模块将通道注意力与空间注意力并行结合,有效地学习关键特征,并且可以轻松扩展到其他神经模型。 与最先进的模型相比,实验表明,作者提出的模型可以使用不同的细粒度图像基准(CUB-200-2011、FGVC Aircraft 和Stanford Cars)实现卓越的精度。

1.2 研究背景

细粒度图像分类就是将同一物种进行细分,比如将猫的种类细分,同一类别的图像之间的差异就比较小,由于特定细粒度子类别之间的类间差异较小,以及类内差异较大,因此它不同于传统的图像分析问题。由于细粒度图像具有标记粒度细的特点,因此直接利用整个图像级别的所有特征来识别细粒度图像是很不合理的,如下图所示:
在这里插入图片描述
上图每行的三张图片属于同一鸟类。 可以观察到,同一物种的鸟类受拍摄角度和环境的影响也有很大差异。我们很容易看出,即使属于同一子类别的图像本身在形态、姿势、背景等方面也存在巨大差异,基于这个研究背景,我们需要有效解决类别内差异问题。

针对这个问题,本文作者提出一种 利用注意力机制的细粒度图像分类 方法。 该方法在提取图像的细粒度特征的同时,消除了有害特征对分类性能的影响。 训练时尽量少使用细粒度的标记数据,以提高细粒度图像分类的效果。

1.3 本文创新点

  1. 提出了聚合注意力模块来平衡细粒度图像分类任务的性能和复杂性之间的权衡,该模块可广泛应用于神经网络中。
  2. 设计并在整个网络中使用跨通道损失函数,以提高深度卷积神经网络的特征学习和表达能力。
  3. 在四个不同的公共基准数据集上针对细粒度图像分类任务进行了广泛的实验,模型的性能优秀。

1.4 计算机视觉中的注意力机制

注意力思想已被应用于计算机视觉任务,包括图像标记、目标检测等,特别是图像分类。 2019年,注意力网络模型CBAM被开发出来,其中 Convolutional block attention module 和 Attention-based label consistency for semi-supervised deep learning based image classification 将通道注意力与空间注意力相结合,下周将详细介绍这两篇论文。视觉注意机制通过通道或空间尺度操作来探索图像关键部分的特征。 但对于类内差异而言,一般的视觉注意机制并不能表现出突出的效果。

本文作者提出了一种简单有效的注意力单元,称为聚合注意力模块,具有跨通道损失函数。 创新的注意力模块擅长发现细微差异,并且优于其他注意力机制。

1.5 模型方法

SENet专注于通道维度的注意力计算,对通道之间的相互依赖关系进行建模,并通过网络的全局损失函数自适应地重新校正通道之间特征的相应强度。 它的目的是有选择地增强有用的特征并抑制不太有用的特征。 尽管SE块表现良好,但整个模型的成本增加了,这体现在参数数量以及额外的训练周期上。

ECA-Net是一种超通道注意力模块,仅涉及k(k≤9)个参数,但却带来了显着的性能提升,ECA-Net一味追求减少通道注意力中的参数数量,而忽略了空间注意力的有效性,这在一定程度上影响了模型的准确性。

作者提出的模型综合解决了上述两个网络模型的缺陷,将通道注意力和空间注意力的有效使用结合起来。 在保证优异性能的同时最大限度地减少参数数量。 对于细粒度的图像分类任务,具有出色的学习能力和泛化能力。

1.5.1 聚合注意力模块

作者将 ResNet 修改为深度神经网络架构中的骨干网络。 给定中间生成的特征矩阵 F ∈ R C × H × W R^{C×H×W} RC×H×W 作为模块输入,所提出的 AAM 并行生成 1D 通道注意力图 M c ∈ R C × 1 × 1 M_c ∈ R^{C×1×1} McRC×1×1 和 2D 空间注意力图 M s ∈ R 1 × H × W M_s ∈ R^{1×H×W} MsR1×H×W 。 整个注意力过程表示为:在这里插入图片描述

1.5.2 通道注意力模块

为了平衡通道注意力的额外计算成本和提高的模型精度,当我们利用特征通道之间的相关性生成通道注意力特征图时,本文仅提取k个通道的相关信息。 k 个通道与当前通道相邻。 此外,全局最大池化可以提取有效的空间特征。输入特征图矩阵通过通道全局最大池化进行操作,并通过 sigmoid 函数在 0 和 1 之间生成。

因此,对输入的原始特征图进行全局最大池化,提取并学习相邻k通道信息。 生成的通道注意力张量按元素相加。 通过sigmoid函数并通过复制路径进行相应的广播,最终与原始输入特征图矩阵逐个相乘。 这是通道注意力模块的输出。 图4展示了通道注意力模块的结构。 简而言之,通道注意力表示为:在这里插入图片描述
下图为通道注意力模块的结构。 给定输入特征图,该模块通过大小为 k 的全局最大池化操作生成通道权重,其中 k 由经验确定
在这里插入图片描述
通道注意力机制的核心思想是让模型自动学习每个通道的重要性,并根据通道的贡献调整输入数据的表示。通过引入通道注意力机制,模型可以更加有效地利用每个通道的信息,提高模型对输入数据的表征能力,从而改善模型在各种任务中的性能。

如下图:先将输入特征图分别进行全局最大池化和全局平均池化(是在特征层的高和宽上进行池化),得到两张不同维度的特征描述。然后池化后的特征图共用一个多层感知器网络,先通过一个全连接层进行特征降维,再通过全连接层进行特征升维。将两张特征图在通道维度堆叠,经过 sigmoid 激活函数将特征图的每个通道的权重归一化到0-1之间。最后,将归一化后的权重和输入特征图相乘,得到处理好的特征图。
在这里插入图片描述

通道注意力代码实现
import torch.nn as nn
import torch
import torch.nn.functional as f
 
print("************************通道注意力机制*********************")
 
 
# 通道注意力机制
class ChannelAttention(nn.Module):
    # 初始化,in_planes参数指定了输入特征图的通道数,ratio参数用于控制通道注意力机制中特征降维和升维过程中的压缩比率。默认值为8
    def __init__(self, in_planes, ratio=8):
        # 继承父类初始化方法
        super().__init__()
        # 全局最大池化 [b,c,h,w]==>[b,c,1,1]
        self.avg_pool = nn.AdaptiveAvgPool3d((4, 1, 1)) # C*H*W
        # 全局平均池化 [b,c,h,w]==>[b,c,1,1]
        self.max_pool = nn.AdaptiveMaxPool3d((4, 1, 1)) # C*H*W
 
        # 使用1x1x1卷积核代替全连接层进行特征降维
        self.fc1 = nn.Conv3d(in_planes, in_planes // ratio, 1, bias=False)
        # 激活函数
        self.relu1 = nn.ReLU()
        # 使用1x1x1卷积核进行特征升维
        self.fc2 = nn.Conv3d(in_planes // ratio, in_planes, 1, bias=False)
 
        self.sigmoid = nn.Sigmoid()
 
    def forward(self, x):
        # 通过平均池化和最大池化后的特征进行卷积、激活、再卷积操作
        avg_out = self.fc2(self.relu1(self.fc1(self.avg_pool(x)))) # 平均池化-->卷积-->RELu激活-->卷积
        max_out = self.fc2(self.relu1(self.fc1(self.max_pool(x)))) # 最大池化-->卷积-->RELu激活-->卷积
        # 将两个输出相加
        out = avg_out + max_out
        # 应用Sigmoid函数
        return self.sigmoid(out)
 
# 创建ChannelAttention模型的实例,输入通道数为256
model = ChannelAttention(256)
# 打印模型结构
print(model)
# 创建一个形状为[2, 256, 4, 8, 8]的输入张量,所有元素初始化为1
inputs = torch.ones([2, 256, 4, 8, 8]) # 2是批次大小(batch size),256是通道数,4、8、8分别是深度、高度和宽度的维度
# 将输入张量传递给模型,并获取输出
outputs = model(inputs)
# 打印输入张量的形状
print(inputs.shape) # [2, 256, 4, 8, 8]
# 打印输出张量的形状
print(outputs.shape) # [2, 256, 4, 1, 1]

输出结果
在这里插入图片描述

1.5.3 空间注意力模块

与通道注意力不同,空间注意力提供了更有用的信息,重点关注图像的不同位置。 由于基于空间尺度的全局最大池化操作,可以有效地提取特征图的关键特征。 就全局平均池化操作而言,一方面可以尽可能保存特征图的整体信息。 另一方面,同一类别差异可能较大,关键部位可能会受到光照、遮挡等因素的影响,可能导致学习效果不足。 全局平均池化操作可以在一定程度上缓解这一障碍。

本文将特征图的空间注意力分布逐个元素地传递、复制并与原始输入特征图矩阵相乘,即为空间注意力模块 M s ( F ) ∈ R 1 × H × W M_s(F) ∈ R^{1×H×W} Ms(F)R1×H×W 的输出。 空间注意力模块的结构如下图所示。我们使用两次池化计算来合成当前特征矩阵的空间值,获得两个2D中间图 M s a v g ∈ R 1 × H × W M^{avg}_{s} ∈ R^{1×H×W} MsavgR1×H×W M s m a x ∈ R 1 × H × W M^{max}_{s} ∈ R^{1×H×W} MsmaxR1×H×W。 每个特征图代表通道中的平均池化特征以及最大池化特征。 该模块通过标准卷积层将它们连接起来并进行卷积以生成2D空间注意力分布。 简而言之,空间注意力定义为:在这里插入图片描述
在这里插入图片描述

空间注意力代码实现
import torch.nn as nn
import torch
import torch.nn.functional as f
 
print("************************空间注意力机制*********************")
 
 
# 空间注意力机制
class SpatialAttention(nn.Module):
    def __init__(self, kernel_size=3):
        super().__init__()
 
        # 断言法:kernel_size必须为3或7
        assert kernel_size in (3, 7),'kernel size must be 3 or 7'
        # 三元操作:如果kernel_size的值等于7,则padding被设置为3;否则(即kernel_size的值为3),padding被设置为1。
        padding = 3 if kernel_size == 7 else 1
        # 定义一个卷积层,输入通道数为2,输出通道数为1
        self.conv1 = nn.Conv3d(2, 1, kernel_size, padding=padding, bias=False)
        self.sigmoid = nn.Sigmoid()
 
    def forward(self, x):
        # (N, C, H, W),dim=1沿着通道维度C,计算张量的平均值和最大值
        avg_out = torch.mean(x, dim=1, keepdim=True)
        max_out, _ = torch.max(x, dim=1, keepdim=True)
        # 将平均值和最大值在通道维度上拼接
        x = torch.cat([avg_out, max_out], dim=1)
        x = self.conv1(x)
        return self.sigmoid(x)
 
model = SpatialAttention(kernel_size=7)
print(model)
inputs = torch.ones([2, 256, 4, 8, 8])
outputs = model(inputs)
print(inputs.shape)
print(outputs.shape)

输出结果
在这里插入图片描述

空间注意力机制(Spatial Attention Module)是一种用于处理空间信息的注意力机制,主要用于在深度学习模型中动态地调整输入数据的不同空间位置的重要性,以增强有用信息并抑制无用信息。在图像处理等领域,空间注意力机制可以帮助模型更好地关注图像中不同区域的特征,从而提高模型的表征能力和性能。

1.5.4 CBAM注意力机制

CBAM(Convolutional Block Attention Module)模块是一种结合了通道注意力和空间注意力机制的注意力模块,旨在提高卷积神经网络(CNN)对图像特征的表征能力。CBAM模块通过同时关注通道维度和空间维度的特征信息,实现了对图像特征的全局感知和重要性调整。

CBAM模块通常由两个子模块组成:通道注意力模块(Channel Attention Module)和空间注意力模块(Spatial Attention Module)。这两个子模块分别用于对通道维度和空间维度的特征进行加权调整,从而提高特征表示的表征能力。(两个Attention进行串联,Channel 在前,Spatial在后)如下图:
在这里插入图片描述
模块会沿着两个独立的维度(通道和空间)依次推断注意力图,然后将注意力图乘以输入特征图以进行自适应特征修饰。 由于CBAM是轻量级的通用模块,因此可以以可忽略的开销将其无缝集成到任何CNN架构中,并且可以与基础CNN一起进行端到端训练。

CBAM注意力代码实现
import torch.nn as nn
import torch
import torch.nn.functional as f
 
print("************************通道注意力机制*********************")
 
 
# 通道注意力机制
class ChannelAttention(nn.Module):
    # 初始化,in_planes参数指定了输入特征图的通道数,ratio参数用于控制通道注意力机制中特征降维和升维过程中的压缩比率。默认值为8
    def __init__(self, in_planes, ratio=8):
        # 继承父类初始化方法
        super().__init__()
        # 全局最大池化 [b,c,h,w]==>[b,c,1,1]
        self.avg_pool = nn.AdaptiveAvgPool3d((4, 1, 1)) # C*H*W
        # 全局平均池化 [b,c,h,w]==>[b,c,1,1]
        self.max_pool = nn.AdaptiveMaxPool3d((4, 1, 1)) # C*H*W
 
        # 使用1x1x1卷积核代替全连接层进行特征降维
        self.fc1 = nn.Conv3d(in_planes, in_planes // ratio, 1, bias=False)
        # 激活函数
        self.relu1 = nn.ReLU()
        # 使用1x1x1卷积核进行特征升维
        self.fc2 = nn.Conv3d(in_planes // ratio, in_planes, 1, bias=False)
 
        self.sigmoid = nn.Sigmoid()
 
    def forward(self, x):
        # 通过平均池化和最大池化后的特征进行卷积、激活、再卷积操作
        avg_out = self.fc2(self.relu1(self.fc1(self.avg_pool(x)))) # 平均池化-->卷积-->RELu激活-->卷积
        max_out = self.fc2(self.relu1(self.fc1(self.max_pool(x)))) # 最大池化-->卷积-->RELu激活-->卷积
        # 将两个输出相加
        out = avg_out + max_out
        # 应用Sigmoid函数
        return self.sigmoid(out)
 
# 创建ChannelAttention模型的实例,输入通道数为256
model = ChannelAttention(256)
# 打印模型结构
print(model)
# 创建一个形状为[2, 256, 4, 8, 8]的输入张量,所有元素初始化为1
inputs = torch.ones([2, 256, 4, 8, 8]) # 2是批次大小(batch size),256是通道数,4、8、8分别是深度、高度和宽度的维度
# 将输入张量传递给模型,并获取输出
outputs = model(inputs)
# 打印输入张量的形状
print(inputs.shape) # [2, 256, 4, 8, 8]
# 打印输出张量的形状
print(outputs.shape) # [2, 256, 4, 1, 1]
 
print("************************空间注意力机制*********************")
 
 
# 空间注意力机制
class SpatialAttention(nn.Module):
    def __init__(self, kernel_size=3):
        super().__init__()
 
        # 断言法:kernel_size必须为3或7
        assert kernel_size in (3, 7),'kernel size must be 3 or 7'
        # 三元操作:如果kernel_size的值等于7,则padding被设置为3;否则(即kernel_size的值为3),padding被设置为1。
        padding = 3 if kernel_size == 7 else 1
        # 定义一个卷积层,输入通道数为2,输出通道数为1
        self.conv1 = nn.Conv3d(2, 1, kernel_size, padding=padding, bias=False)
        self.sigmoid = nn.Sigmoid()
 
    def forward(self, x):
        # (N, C, H, W),dim=1沿着通道维度C,计算张量的平均值和最大值
        avg_out = torch.mean(x, dim=1, keepdim=True)
        max_out, _ = torch.max(x, dim=1, keepdim=True)
        # 将平均值和最大值在通道维度上拼接
        x = torch.cat([avg_out, max_out], dim=1)
        x = self.conv1(x)
        return self.sigmoid(x)
 
model = SpatialAttention(kernel_size=7)
print(model)
inputs = torch.ones([2, 256, 4, 8, 8])
outputs = model(inputs)
print(inputs.shape)
print(outputs.shape)
 
 
print("************************CBAM模块*********************")
class CBAM_Block(nn.Module):
    def __init__(self, channel, ratio=8, kernel_size=3):
        super().__init__()
        # 初始化通道注意力模块
        self.channelAttention = ChannelAttention(channel, ratio=ratio)
        # 初始化空间注意力模块
        self.SpatialAttention = SpatialAttention(kernel_size=kernel_size)
 
    def forward(self, x):
        # 应用通道注意力和空间注意力
        x = x * self.channelAttention(x)
        x = x * self.SpatialAttention(x)
        return x
 
model = CBAM_Block(256)
print(model)
inputs = torch.ones([2, 256, 4, 8, 8])
outputs = model(inputs)
print(inputs.shape)
print(outputs.shape)

输出结果
在这里插入图片描述

1.5.5 本文模型整体架构

该方法的架构如下图所示。给定前面的卷积块获得的特征图,聚合注意力模块将通道注意力和空间注意力结合起来计算注意力分布。 生成的最终分布被输入到下一个卷积块。 网络的整体损失是通过提出的跨通道损失和交叉熵损失来计算的。
在这里插入图片描述

1.6 实验

1.6.1 数据集

作者在四个广泛采用的细粒度基准上验证了模型。 实验期间的基准数据是 Caltech-UCSD-Birds (CUB-200-2011)、FGVC-Aircraft (Maji et al. 2013)、Stanford Cars 和 Stanley Dogs (Khosla et al. 2011)。 数据集的详细介绍如下表所示。
在这里插入图片描述

1.6.1 实施细节

采用 PyTorch 框架来实现我们提出的方法。 随机梯度下降优化器与“poly”的学习率策略一起使用(动量参数设置为0.8,初始学习率设置为1e−4,终止学习率设置为1e−6,并且 权重衰减设置为 2.5e−4)。 我们在并行 Titan XP GPU 上训练我们提出的模型 200 个时期。 训练图像的批量大小设置为 16。所有原始图像都经过随机重新缩放、裁剪和翻转。 然后将输入训练图像的大小调整为 224 × 224,而用于验证和测试的图像根本不必改变。 经过实验验证,不同的 η 值以及数据集相应的训练效果如表 2 所示。请注意,我们从头开始训练我们的网络,这意味着除了官方提供的数据集中的标记图像之外,我们不需要使用任何额外的数据 。 此外,我们将超参数μ设置为0.01。

1.6.2 实验结果

如下表所示,AAM 方法比其他 SOTA 模型表现更好。 具体来说,我们提出的方法显示,CUB-200-2011 上的结果明显改善了 0.7%,FGVC-Aircraft 上改善了 1.5%,Stanford Cars 上改善了 0.2%,Stanford Dogs 上改善了 2.7%。 这项工作提供了图 7,将所提出的 CC-Loss 与中心损失(Wen et al. 2016)和交叉熵损失(CE 损失)进行比较。 在这个实验中,模型都是从头开始训练的。
在这里插入图片描述

1.7 结论

在本文中,作者提出了用于细粒度图像分类任务的 AAM。 在这个注意力模块中,作者并行地将通道注意力和空间注意力结合起来。 此外,作者还开发了 CC-Loss 来最大化细粒度图像类别之间的差异。 大量实验表明,无论骨干网络如何,所提出的 AAM 的性能都比其他最近使用的模型好得多。

总结

本周学习了AAM模型,聚合注意力模块、通道注意力、空间注意力模块,同时也进行了代码实践,下周将继续学习细粒度图像相关的文献模型。加油~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

20240624 每日AI必读资讯

🤖AI学会篡改奖励函数、欺骗研究者!Claude团队:无法根除的行为,令人不安 - 实验中让AI可以访问自己的强化学习代码,并且提问:目前为止,我们总共进行了几轮强化学习?AI在自以为不会被…

三十八篇:架构大师之路:探索软件设计的无限可能

架构大师之路:探索软件设计的无限可能 1. 引言:架构的艺术与科学 在软件工程的广阔天地中,系统架构不仅是设计的骨架,更是灵魂所在。它如同建筑师手中的蓝图,决定了系统的结构、性能、可维护性以及未来的扩展性。本节…

测试测量-DMM直流精度

测试测量-DMM直流精度 最近去面试,发现了自己许多不足,比如我从未考虑过万用表准或者不准,或者万用表有多准? 在过去的实验室中,常用的DMM有KEYSIGHT 34401A以及 KEITHLEY THD2015,就以这两台为例&#x…

Typora + Hexo 图片路径问题(Typedown)

文章目录 1. 冲突来源2. 解决思路3. 实现1. typora图片路径2. hexo脚本 1. 冲突来源 Hexo上对于图片在md中的引用,使用了post_asset_folder: true配置,来更好的管理图片。 当一篇名为xxx.md的文章引用1.png图片时,默认让1.png保持在xxx文件夹…

eNSP启动设备失败,错误代码40,网卡配置正常,虚拟机导致的错误解决过程

安装eNSP后出现以下错误。 按照帮助文档,查看了相关软件,尤其是vitualbox的版本以及网卡问题。网卡设置正常,vitualbox也匹配成功。 附:vitualbox各个版本的下载地址: 关于网卡名称的修改方法,参照博客 …

【驱动篇】龙芯LS2K0300之单总线驱动

实验过程 实验目的: 在龙芯开发板上面使用单总线驱动DS18B20温度传感器 ① 根据原理图连接DS18B20模块 ② 将i2c0引脚的功能复用为GPIO ③ 注册字符设备,按照DS18B20的读写时序编写读写驱动接口 ④ 编写测试用例解析传感器的数值 原理图 将板子上…

【chatgpt】train_split_test的random_state

在使用train_test_split函数划分数据集时,random_state参数用于控制随机数生成器的种子,以确保划分结果的可重复性。这样,无论你运行多少次代码,只要使用相同的random_state值,得到的训练集和测试集划分就会是一样的。…

Linux_软硬链接

目录 1、软链接 2、软链接的使用方式 3、软链接的删除 4、硬链接 5、硬链接的使用方式 6、软硬链接的使用场景 7、软硬链接的区别 结语 前言: 在Linux操作系统中,有软链接和硬链接,他们是一种特殊的文件引用,主要用于与…

破碎的像素地牢探险:游戏分享

软件介绍 《破碎的像素地牢》是开源一款地牢冒险探索类的游戏,融合了日系RPG经典风格,玩家将控制主角进行未知场景的探索。除了经典地牢玩法外,游戏还添加了更多创意内容,如黑屏状态前的挑战性等,使得游戏更加富有挑战…

git 初基本使用-----------笔记

Git命令 下载git 打开Git官网(git-scm.com),根据自己电脑的操作系统选择相应的Git版本,点击“Download”。 基本的git命令使用 可以在项目文件下右击“Git Bash Here” ,也可以命令终端下cd到指定目录执行初始化命令…

【React】登录-封装Token的存取删方法--共享复用

在token.js中 // 封装存取方法const TOKENKEY token_keyfunction setToken (token) {return localStorage.setItem(TOKENKEY, token) }function getToken () {return localStorage.getItem(TOKENKEY) }function clearToken () {return localStorage.removeItem(TOKENKEY) }ex…

springboot3多模块实践

先帖下目录结构&#xff0c;直接在idea里面新建就行&#xff0c;删掉多余的文件 子模块的新建 根目录pom文件&#xff0c;注意modules、packaging&#xff0c;dependencyManagement统一管理依赖&#xff0c;子模块添加依赖的时候就不用加版本号 <?xml version"1.0…

富文本编辑器CKEditor

介绍 富文本编辑器不同于文本编辑器,它提供类似于 Microsoft Word 的编辑功能 在Django中,有可以现成的富文本三方模块django-ckeditor,具体安排方式: pip install django-ckeditor==6.5.1官网:Django CKEditor — Django CKEditor 6.7.0 documentation 使用方式 创建项…

I2C总线8位IO扩展器PCF8574

PCF8574用于I2C总线的远程8位I/O扩展器 PCF8574国产有多个厂家有替代产品&#xff0c;图示为其中一款HT8574 1 产品特点 低待机电流消耗&#xff1a;10 uA&#xff08;最大值&#xff09; I2C 转并行端口扩展器 漏极开路中断输出 与大多数微控制器兼容 具有大电流驱动能力的闭…

在linux系统中使用docker、mysql实例

systemctl 是一个命令行工具&#xff0c;用于控制和管理基于 systemd 的 Linux 发行版中的系统和服务。 启动服务 &#xff1a;使用 systemctl start [service-name] 开始一个服务。 如启动docker&#xff1a;systemctl start docker 停止服务 &#xff1a;使用 systemctl st…

JAVA期末复习题1

目录 Java 填空题整理及解析 1. 说出Java的特点&#xff1a; 2. Java的运行机制是先编译再解释运行。 3. 请按照以下分类补全对应的数据类型&#xff1a; 4. 在有限次数循环时&#xff0c;一般选择for循环结构&#xff1b;未知循环次数时&#xff0c;可以选择while循环结构…

预备资金有5000-6000买什么电脑比较好?大学生电脑选购指南

小新pro14 2024 处理器&#xff1a;采用了英特尔酷睿Ultra5 125H或Ultra9 185H两种处理器可选&#xff0c;这是英特尔最新的高性能低功耗处理器&#xff0c;具有18个线程&#xff0c;最高可达4.5GHz的加速频率&#xff0c;支持PCIe 4.0接口&#xff0c;内置了强大的ARC核芯显卡…

如何使用ig507金融数据库的股票接口,股票API来获取MACD指标

一、MACD指标简介 MACD&#xff08;Moving Average Convergence Divergence&#xff0c;移动平均收敛/发散&#xff09;是一种趋势跟踪动量指标&#xff0c;用于分析股票或其他金融产品的价格趋势。MACD由两部分组成&#xff1a;差离值&#xff08;DIF&#xff09;和信号线&am…

【FreeRTOS】任务管理与调度

文章目录 调度&#xff1a;总结 调度&#xff1a; 相同优先级的任务轮流运行最高优先级的任务先运行 可以得出结论如下&#xff1a; a 高优先级的任务在运行&#xff0c;未执行完&#xff0c;更低优先级的任务无法运行b 一旦高优先级任务就绪&#xff0c;它会马上运行&#xf…

笔记本更换固态,保留数据,无需重装系统和软件

一、问题描述&#xff1a; 原有一块128GB的固态硬盘作为c盘使用&#xff0c;由于工作学习需要&#xff0c;经常跑虚拟机&#xff0c;现在需要升级容量。 二、解决思路&#xff1a; 硬件 购买一款大容量的固态硬盘 不同的容量有不同的价格&#xff0c;这个根据预算和实际需要来…