YOLOv8改进 | 2023Neck篇 | 轻量级跨尺度特征融合模块CCFM(附yaml文件+添加教程)

一、本文介绍

本文给大家带来的改进机制是轻量级跨尺度特征融合模块CCFM(Cross-Scale Feature Fusion Module)其主要原理是:将不同尺度的特征通过融合操作整合起来,以增强模型对于尺度变化的适应性和对小尺度对象的检测能力。我将其复现在YOLOv8上,发现其不仅能够降低GFLOPs(成功添加之后,不引入任何其它模块GFLOPs降低至7.3),同时精度上也有很大幅度的提升mAP大概能够提高0.05左右,相对于BiFPN也有一定幅度的上涨。

适用检测目标:所有的目标检测均有一定的提点

推荐指数:⭐⭐⭐⭐⭐

  专栏回顾:YOLOv8改进系列专栏——本专栏持续复习各种顶会内容——科研必备 

效果回顾展示->

图片分析->在我的数据集上大家可以看到mAP50大概增长了0.05左右这个涨点幅度还是可以的,同时该模块是有二次创新的机会的,后期我会在接下来的文章进行二次创新(进行一个融合性的创新),同时希望大家能够尽早关注我的专栏。

下面是参数量和计算量的截图,这个是非常适合轻量化读者的一个Neck结构。

目录

一、本文介绍

二、CCFM的框架原理

2.1、模型概览

2.2、高效混合编码器

2.3、IoU感知查询选择

三、CCFM的核心代码

四、手把手教你添加CCFM

五、完美运行截图 

六、本文总结


二、CCFM的框架原理

 

论文地址:RT-DETR论文地址

代码地址:RT-DETR官方下载地址


CCFM(Cross-Scale Feature Fusion Module)即为跨尺度特征融合模块。这个模块的作用是将不同尺度的特征通过融合操作整合起来,以增强模型对于尺度变化的适应性和对小尺度对象的检测能力。CCFM可以有效地整合细节特征和上下文信息,从而提高模型的整体性能。其是在RT-DETR中提出的,所以其并没有什么原理结构一说,下面附上我个人手撕的CCFM结构图供大家参考。

这里没啥讲的,给大家说一下RT-DETR吧,也是新出的模型,我已经投出一篇一区目前在外审的状态啦,所以给大家介绍一下该模型,该模型目前在实时监测的领域非常的好发论文,当然不感兴趣的读者直接略过下面的部分即可,直接看第三章和第四章。

 

2.1、模型概览

我们提出的RT-DETR包括一个主干网络(backbone)、一个混合编码器(hybrid encoder)和一个带有辅助预测头的变换器解码器(transformer decoder)。模型架构的概览如下面的图片3所示。

具体来说,我们利用主干网络的最后三个阶段的输出特征 {S3, S4, S5} 作为编码器的输入。混合编码器通过内尺度交互(intra-scale interaction)和跨尺度融合(cross-scale fusion)将多尺度特征转换成一系列图像特征(详见第4.2节)。随后,采用IoU感知查询选择(IoU-aware query selection)从编码器输出序列中选择一定数量的图像特征,作为解码器的初始对象查询(详见第4.3节)。最后,带有辅助预测头的解码器迭代优化对象查询,生成边框和置信度分数。

2.2、高效混合编码器

计算瓶颈分析。为了加速训练收敛和提高性能,Zhu等人提出引入多尺度特征,并提出变形注意力机制来减少计算量。然而,尽管注意力机制的改进减少了计算开销,但输入序列长度的显著增加仍使编码器成为计算瓶颈,阻碍了DETR的实时实现。如[21]所报告,编码器占了49%的GFLOPs,但在Deformable-DETR中仅贡献了11%的AP。为了克服这一障碍,我们分析了多尺度变换器编码器中存在的计算冗余,并设计了一系列变体来证明内尺度和跨尺度特征的同时交互在计算上是低效的。

高级特征是从包含图像中对象丰富语义信息的低级特征中提取出来的。直觉上,在连接的多尺度特征上执行特征交互是多余的。为了验证这一观点,我们重新思考了编码器结构,并设计了一系列具有不同编码器的变体,如下图所示。

这一系列变体通过将多尺度特征交互分解为内尺度交互和跨尺度融合的两步操作,逐渐提高了模型精度,同时显著降低了计算成本(详细指标参见下表3)。

我们首先移除DINO-R50中的多尺度变换器编码器作为基线A。接下来,插入不同形式的编码器,基于基线A生成一系列变体,具体如下:

- A → B:变体B插入了一个单尺度变换器编码器,它使用一个变换器块层。每个尺度的特征共享编码器进行内尺度特征交互,然后连接输出的多尺度特征。
- B → C:变体C基于B引入了跨尺度特征融合,并将连接的多尺度特征送入编码器进行特征交互。
- C → D:变体D将内尺度交互和跨尺度融合的多尺度特征解耦。首先使用单尺度变换器编码器进行内尺度交互,然后使用类似PANet的结构进行跨尺度融合。
- D → E:变体E在D的基础上进一步优化

了内尺度交互和跨尺度融合的多尺度特征,采用了我们设计的高效混合编码器(详见下文)。

混合设计。基于上述分析,我们重新思考了编码器的结构,并提出了一种新型的高效混合编码器。如图3所示,所提出的编码器由两个模块组成,即基于注意力的内尺度特征交互模块(AIFI)和基于CNN的跨尺度特征融合模块(CCFM)。AIFI基于变体D进一步减少了计算冗余,它只在S5上执行内尺度交互。我们认为,将自注意力操作应用于具有更丰富语义概念的高级特征,可以捕捉图像中概念实体之间的联系,这有助于后续模块检测和识别图像中的对象。同时,由于缺乏语义概念,低级特征的内尺度交互是不必要的,存在与高级特征交互重复和混淆的风险。为了验证这一观点,我们仅在变体D中对S5执行内尺度交互,实验结果报告在表3中,见DS5行。与原始变体D相比,DS5显著降低了延迟(快35%),但提高了准确度(AP高0.4%)。这一结论对于实时检测器的设计至关重要。CCFM也是基于变体D优化的,将由卷积层组成的几个融合块插入到融合路径中。融合块的作用是将相邻特征融合成新的特征,其结构如图4所示。融合块包含N个RepBlocks,两个路径的输出通过逐元素加法融合。我们可以将此过程表示如下:

Q = K = V = \text{Flatten}(S_5)

F_5 = \text{Reshape}(\text{Attn}(Q, K, V))

\text{Output} = \text{CCFM}(\{S_3, S_4, F_5\})

式中,Attn代表多头自注意力,Reshape代表将特征的形状恢复为与S5相同,这是Flatten的逆操作。

2.3、IoU感知查询选择

DETR中的对象查询是一组可学习的嵌入,由解码器优化并由预测头映射到分类分数和边界框。然而,这些对象查询难以解释和优化,因为它们没有明确的物理含义。后续工作改进了对象查询的初始化,并将其扩展到内容查询和位置查询(锚点)。其中,提出了查询选择方案,它们共同的特点是利用分类分数从编码器中选择排名靠前的K个特征来初始化对象查询(或仅位置查询)。然而,由于分类分数和位置置信度的分布不一致,一些预测框虽有高分类分数,但与真实框(GT)不接近,这导致选择了分类分数高但IoU分数低的框,而丢弃了分类分数低但IoU分数高的框。这降低了检测器的性能。为了解决这个问题,我们提出了IoU感知查询选择,通过在训练期间对模型施加约束,使其对IoU分数高的特征产生高分类分数,对IoU分数低的特征产生低分类分数。因此,模型根据分类分数选择的排名靠前的K个编码

器特征的预测框,既有高分类分数又有高IoU分数。我们重新制定了检测器的优化目标如下:

L(\hat{y}, y) = L_{box}(\hat{b}, b) + L_{cls}(\hat{c}, \hat{b}, y, b)
                = L_{box}(\hat{b}, b) + L_{cls}(\hat{c}, c, IoU)

 其中,\hat{y}y分别代表预测和真实值,hat{y} = \{\hat{c}, \hat{b}\} 和 y = \{c, b\}c 和b 分别代表类别和边界框。我们将IoU分数引入分类分支的目标函数中(类似于VFL),以实现对正样本分类和定位的一致性约束。

效果分析。为了分析所提出的IoU感知查询选择的有效性,我们可视化了在val2017数据集上,由查询选择选出的编码器特征的分类分数和IoU分数,如图6所示。具体来说,我们首先根据分类分数选择排名靠前的K(实验中K=300)个编码器特征,然后可视化分类分数大于0.5的散点图。红点和蓝点分别计算自应用传统查询选择和IoU感知查询选择的模型。点越接近图的右上方,相应特征的质量越高,即分类标签和边界框更有可能描述图像中的真实对象。根据可视化结果,我们发现最显著的特点是大量蓝点集中在图的右上方,而红点集中在右下方。这表明,经IoU感知查询选择训练的模型可以产生更多高质量的编码器特征。

此外,我们对两种类型点的分布特征进行了定量分析。图中蓝点比红点多138%,即更多的红点的分类分数小于或等于0.5,可以被认为是低质量特征。然后,我们分析了分类分数大于0.5的特征的IoU分数,发现有120%的蓝点比红点的IoU分数大于0.5。定量结果进一步证明,IoU感知查询选择可以为对象查询提供更多具有准确分类(高分类分数)和精确位置(高IoU分数)的编码器特征,从而提高检测器的准确度。


三、CCFM的核心代码

下面的代码是RepC3的代码,感兴趣的同学可以用其替换C2f试一试,但是本文介绍的CCFM结构,所以用不到如下的代码,仅供感兴趣的同学使用,该结构的计算量可能很大,我目前还没有尝试在YOLOv8中使用该模块。

import torch
import torch.nn as nn
import numpy as np


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):
        """Initialize Conv layer with given arguments including activation."""
        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):
        """Apply convolution, batch normalization and activation to input tensor."""
        return self.act(self.bn(self.conv(x)))

    def forward_fuse(self, x):
        """Perform transposed convolution of 2D data."""
        return self.act(self.conv(x))


class RepConv(nn.Module):
    """
    RepConv is a basic rep-style block, including training and deploy status.

    This module is used in RT-DETR.
    Based on https://github.com/DingXiaoH/RepVGG/blob/main/repvgg.py
    """
    default_act = nn.SiLU()  # default activation

    def __init__(self, c1, c2, k=3, s=1, p=1, g=1, d=1, act=True, bn=False, deploy=False):
        """Initializes Light Convolution layer with inputs, outputs & optional activation function."""
        super().__init__()
        assert k == 3 and p == 1
        self.g = g
        self.c1 = c1
        self.c2 = c2
        self.act = self.default_act if act is True else act if isinstance(act, nn.Module) else nn.Identity()

        self.bn = nn.BatchNorm2d(num_features=c1) if bn and c2 == c1 and s == 1 else None
        self.conv1 = Conv(c1, c2, k, s, p=p, g=g, act=False)
        self.conv2 = Conv(c1, c2, 1, s, p=(p - k // 2), g=g, act=False)

    def forward_fuse(self, x):
        """Forward process."""
        return self.act(self.conv(x))

    def forward(self, x):
        """Forward process."""
        id_out = 0 if self.bn is None else self.bn(x)
        return self.act(self.conv1(x) + self.conv2(x) + id_out)

    def get_equivalent_kernel_bias(self):
        """Returns equivalent kernel and bias by adding 3x3 kernel, 1x1 kernel and identity kernel with their biases."""
        kernel3x3, bias3x3 = self._fuse_bn_tensor(self.conv1)
        kernel1x1, bias1x1 = self._fuse_bn_tensor(self.conv2)
        kernelid, biasid = self._fuse_bn_tensor(self.bn)
        return kernel3x3 + self._pad_1x1_to_3x3_tensor(kernel1x1) + kernelid, bias3x3 + bias1x1 + biasid

    def _pad_1x1_to_3x3_tensor(self, kernel1x1):
        """Pads a 1x1 tensor to a 3x3 tensor."""
        if kernel1x1 is None:
            return 0
        else:
            return torch.nn.functional.pad(kernel1x1, [1, 1, 1, 1])

    def _fuse_bn_tensor(self, branch):
        """Generates appropriate kernels and biases for convolution by fusing branches of the neural network."""
        if branch is None:
            return 0, 0
        if isinstance(branch, Conv):
            kernel = branch.conv.weight
            running_mean = branch.bn.running_mean
            running_var = branch.bn.running_var
            gamma = branch.bn.weight
            beta = branch.bn.bias
            eps = branch.bn.eps
        elif isinstance(branch, nn.BatchNorm2d):
            if not hasattr(self, 'id_tensor'):
                input_dim = self.c1 // self.g
                kernel_value = np.zeros((self.c1, input_dim, 3, 3), dtype=np.float32)
                for i in range(self.c1):
                    kernel_value[i, i % input_dim, 1, 1] = 1
                self.id_tensor = torch.from_numpy(kernel_value).to(branch.weight.device)
            kernel = self.id_tensor
            running_mean = branch.running_mean
            running_var = branch.running_var
            gamma = branch.weight
            beta = branch.bias
            eps = branch.eps
        std = (running_var + eps).sqrt()
        t = (gamma / std).reshape(-1, 1, 1, 1)
        return kernel * t, beta - running_mean * gamma / std

    def fuse_convs(self):
        """Combines two convolution layers into a single layer and removes unused attributes from the class."""
        if hasattr(self, 'conv'):
            return
        kernel, bias = self.get_equivalent_kernel_bias()
        self.conv = nn.Conv2d(in_channels=self.conv1.conv.in_channels,
                              out_channels=self.conv1.conv.out_channels,
                              kernel_size=self.conv1.conv.kernel_size,
                              stride=self.conv1.conv.stride,
                              padding=self.conv1.conv.padding,
                              dilation=self.conv1.conv.dilation,
                              groups=self.conv1.conv.groups,
                              bias=True).requires_grad_(False)
        self.conv.weight.data = kernel
        self.conv.bias.data = bias
        for para in self.parameters():
            para.detach_()
        self.__delattr__('conv1')
        self.__delattr__('conv2')
        if hasattr(self, 'nm'):
            self.__delattr__('nm')
        if hasattr(self, 'bn'):
            self.__delattr__('bn')
        if hasattr(self, 'id_tensor'):
            self.__delattr__('id_tensor')


class RepC3(nn.Module):
    """Rep C3."""

    def __init__(self, c1, c2, n=3, e=1.0):
        """Initialize CSP Bottleneck with a single convolution using input channels, output channels, and number."""
        super().__init__()
        c_ = int(c2 * e)  # hidden channels
        self.cv1 = Conv(c1, c2, 1, 1)
        self.cv2 = Conv(c1, c2, 1, 1)
        self.m = nn.Sequential(*[RepConv(c_, c_) for _ in range(n)])
        self.cv3 = Conv(c_, c2, 1, 1) if c_ != c2 else nn.Identity()

    def forward(self, x):
        """Forward pass of RT-DETR neck layer."""
        return self.cv3(self.m(self.cv1(x)) + self.cv2(x))


四、手把手教你添加CCFM

CCFM无需要添加任何代码,只需要复制粘贴我的yaml文件运行即可。

# 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, [128, True]]
  - [-1, 1, Conv, [256, 3, 2]]  # 3-P3/8
  - [-1, 6, C2f, [256, True]]
  - [-1, 1, Conv, [512, 3, 2]]  # 5-P4/16
  - [-1, 6, C2f, [512, True]]
  - [-1, 1, Conv, [1024, 3, 2]]  # 7-P5/32
  - [-1, 3, C2f, [1024, True]]
  - [-1, 1, SPPF, [1024, 5]]  # 9

# YOLOv8.0n head
head:
  - [-1, 1, Conv, [256, 1, 1]]  # 10, Y5, lateral_convs.0
  - [-1, 1, nn.Upsample, [None, 2, 'nearest']]

  - [6, 1, Conv, [256, 1, 1, None, 1, 1, False]]  # 12 input_proj.1
  - [[-2, -1], 1, Concat, [1]]
  - [-1, 3, C2f, [256]]  # 14, fpn_blocks.0
  - [-1, 1, Conv, [256, 1, 1]]  # 15, Y4, lateral_convs.1

  - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
  - [4, 1, Conv, [256, 1, 1, None, 1, 1, False]]  # 17 input_proj.0
  - [[-2, -1], 1, Concat, [1]]  # cat backbone P4
  - [-1, 3, C2f, [256]]  # X3 (19), fpn_blocks.1

  - [-1, 1, Conv, [256, 3, 2]]  # 220, downsample_convs.0
  - [[-1, 15], 1, Concat, [1]]  # cat Y4
  - [-1, 3, C2f, [256]]  # F4 (22), pan_blocks.0

  - [-1, 1, Conv, [256, 3, 2]]  # 25, downsample_convs.1
  - [[-1, 10], 1, Concat, [1]]  # cat Y5
  - [-1, 3, C2f, [256]]  # F5 (25), pan_blocks.1

  - [[19, 22, 25], 1, Detect, [nc]]  # Detect(P3, P4, P5)


五、完美运行截图 


六、本文总结

到此本文的正式分享内容就结束了,在这里给大家推荐我的YOLOv8改进有效涨点专栏,本专栏目前为新开的平均质量分98分,后期我会根据各种最新的前沿顶会进行论文复现,也会对一些老的改进机制进行补充,目前本专栏免费阅读(暂时,大家尽早关注不迷路~)如果大家觉得本文帮助到你了,订阅本专栏,关注后续更多的更新~

专栏回顾:YOLOv8改进系列专栏——本专栏持续复习各种顶会内容——科研必备

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

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

相关文章

电子学会C/C++编程等级考试2021年03月(六级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:生日相同 2.0 在一个有180人的大班级中,存在两个人生日相同的概率非常大,现给出每个学生的名字,出生月日。试找出所有生日相同的学生。 时间限制:1000 内存限制:65536输入 第一行为整数n,表示有n个学生,n ≤ 180。此后每…

Linux中的fork()函数

目录 1.现象 2.如何实现的? 1.现象 1.fork()函数是用来创建一个字进程的: 如果这个进程是子进程,那么返回值返回0,如果是父进程的话,那么返回子进程的pid,以便父进程找到子进程,因为子进程的p…

理解数字化转型:3个阶段、2个分类和3类价值

导读:数字化转型是基于IT技术提供业务所需要的支持,让业务和技术真正产生交互而诞生的。我们可以从概念及内涵、分类、价值等多个维度来理解企业数字化转型。 01 数字化转型的概念及内涵 数字化转型运用5G、人工智能、大数据、云计算等新一代数字技术&a…

【信息学奥赛】拼在起跑线上,想入道就别落下自己!

编程无难事,只怕有心人,学就是了! 文章目录 1 信息学奥赛简介2 信息学竞赛的经验回顾3 优秀参考图书推荐《信息学奥赛一本通关》4 高质量技术圈开放 1 信息学奥赛简介 信息学奥赛,作为全国中学生学科奥林匹克“五大学科竞赛”之一…

狗dog目标检测数据集VOC+YOLO格式1W+张

狗,是食肉目犬科 [11]犬属 [13]哺乳动物 [12],别称犬,与马、牛、羊、猪、鸡并称“六畜” [13]。狗的体型大小、毛色因品种不同而不同,体格匀称;鼻吻部较长;眼呈卵圆形;两耳或竖或垂;…

你好!赫夫曼树【JAVA】

目录 1.简单介绍 2.术语 3.构建思路 4.创建节点类 5.创建赫夫曼树 6.前序遍历 7.小玩一把 1.简单介绍 赫夫曼树(Huffman Tree)又称最优二叉树,是一种带权路径长度最短的二叉树。它的构建主要用于数据压缩算法中,根据字…

k8s容器部署mysql5.7全流程分享

文章目录 一、前言二、打开dockerhub 看到mysql的版本为 5.7三、K8S 容器编排3.1、编写POD的相关信息3.2、编写mysql的data存储位置3.3、编写mysql的my.cnf的挂载文件3.4、编写mysql的service端口 四、启动并禁用root账户4.1 登录,默认密码1234564.2 配置账户权限 五…

CSS基础面试题

介绍一下标准css盒子模型与低版本IE的盒子模型? 标准盒子模型:宽度内容的宽度(content) border padding margin 低版本IE盒子模型:宽度内容宽度(contentborderpadding) margin box-sizing 属性…

GroupMixFormer:基于Group-Mix注意力的视觉Transformer

文章目录 摘要1、简介2、相关工作2.1、视觉转换器2.2、全面的自注意力建模 3、组混合注意力和GroupMixFormer3.1. 动机:从个体到群体3.2. GMA: 混合组以获得更好的注意力3.3. 架构配置 4、实验4.1、实现细节4.2. 与最先进模型的比较4.3. 消融实验 5、结论 摘要 htt…

Temu重启诉讼和Shein战火重燃?出海知识产权保护成焦点

撰稿 | 故里 来源 | 亿恩 12月14日,Temu在美重诉Shein称别无选择,并表示Shein反竞争行为愈演愈烈。 对此,一位接近Shein人士称,Temu不但一直大规模抄袭SHEIN自有品牌产品、持续进行不正当竞争,还颠倒黑白、贼喊捉贼&…

LVS负载均衡群集,熟悉LVS的工作模式,了解LVS的调度策略以及ipvsadm工具的命令格式

目录 一、什么是群集 群集的作用: 群集的目的是什么 根据群集所针对的目标差异,可分为三种类型 负载均衡群集(LBC)load balance cluster 高可用群集(HAC)high availability cluster 高性能运算群集&a…

模拟真实内网渗透过程

环境搭建 kali为cs服务器 win11为攻击者主机 DMZ模拟目标web服务器,配置两块网卡,一个连外网,一个连内网域控 最终要求在win11上使用cs对目标域控进行提权 实施过程 一、域控主机搭建域环境,DMZ主机加入域内 搭建域控 w…

SE考研真题总结(二)

接上条,今天继续更新~ SE考研真题总结(一)-CSDN博客文章浏览阅读340次,点赞6次,收藏11次。本帖开始分享考研真题中设计【软件工程】的部分,预计会出5期左右,敬请期待~https://blog.csdn.net/js…

ububtu16.04下安装MQTT服务器

1、mqtt服务器安装 直接上root用户,顺序执行以下命令完成服务器安装: sudo apt-add-repository ppa:mosquitto-dev/mosquitto-ppa sudo apt-get update sudo apt-get install mosquitto …

P21 类神经网络训练不起来怎么办- 自动调整学习率 Adapative learning rate

梯度大,学习率减小梯度小,学习率变大adam随时间变化 , decay / warm up 调整学习率方法一 adagrad 学习率除以 梯度的方差 方法二 RMSProp 目前最常用的: Adam: RMSProp Moment Learning rate schedule : decay/ warm up l…

什么是数据可视化?数据可视化的优势、方法及示例

前言 在当今的数字时代,数据是企业和组织的命脉,生成的数据量呈指数级增长。这种被称为大数据的海量数据在洞察力和决策方面具有巨大的潜力。然而,如果没有一种有效的方法来分析和理解这些数据,它就会变得毫无意义和难以管理。这就…

基于物理的AlGaN/GaN HEMT器件2DEG电荷密度分析模型(文献阅读)

标题:A Physics-Based Analytical Model for 2DEG Charge Density in AlGaN/GaN HEMT Devices (IEEE TRANSACTIONS ON ELECTRON DEVICES) 重要公式 2DEG电荷密度建模的困难源于量子阱中Ef随ns的复杂变化。此关系由给出 n s D V t h [ l n ( l e E f − E 0 V t …

12.15_黑马数据结构与算法笔记Java

目录 144 avl树 balance 145 avl树 put 146 avl树 remove 147 红黑树 概述 148 红黑树 put case1-3 149 红黑树 put case4 150 红黑树 remove case0-1 151 红黑树 remove case2 152 红黑树 remove case3 153 红黑树 remove case4 154 红黑树 remove case5 155 红黑树…

问卷推广策略:如何让问卷被更多人看到

企业想要了解最新客户需求痛点、产品上新、活动营销的时候,往往会采取市场调研的方式。而做市场调研大家通常会采取问卷调查的形式,在这个网络高度发达的时代,大家每天都会被海量的信息淹没,想让自己的问卷让更多的人看到并不容易…

Java小案例-RocketMQ的11种消息类型,你知道几种?(事务消息)

前言 上一节给大家讲了Rocket的延迟消息,这一节和大家聊一下事务消息,关于延迟消息大家可以点下面这个链接直接看。 事务消息 事务消息是RocketMQ提供的一种类似X/Open XA的分布式事务功能。通过RocketMQ的事务消息,可以达到分布式事务的最…