即插即用|XBN让ResNet、ShuffleNet彻底解决BN的局限和缺点

OpenCV学堂 2022-04-01 22:34


BN是深度学习中的一项里程碑技术。它在训练过程中使用small-batch-size统计来标准化激活的输出,但在推理过程中使用的是总体统计。

本文主要研究统计数据的估计。定义了BN的估计偏移的幅度来定量地测量其估计的统计量和预期的统计量之间的差异。本文的主要观察结果是:由于网络中BN的堆栈作用,估计偏移会被累积,这对测试性能有不利的影响

作者进一步发现,batch-free normalization(BFN)可以阻止这种估计偏移的累计。这些观察结果也促使了XBNBlock的设计,该模块可以在残差网络的bottleneck块中用BFN替换一个BN。

在ImageNet和COCO基准测试上的实验表明,XBNBlock持续地提高了不同架构的性能,包括ResNet和ResNeXt,并且似乎对分布式偏移更稳健。

1简介

输入标准化在神经网络训练中广泛应用了几十年,在线性模型优化中显示了良好的理论特性。它使用统计数据进行标准化,而这些统计量可以直接从可用的训练数据中计算出来。

一个很自然的想法是扩展网络中激活输出的标准化。然而,由于内部激活的分布不同,标准化激活更具有挑战性,因为激活导致了对标准化的统计量估计不准确。通过总体统计标准化的激活网络显示了训练不稳定性。

BN在训练期间使用mini-Batch统计来对激活输出进行标准化,但在推理/测试期间使用估计的总体统计。BN确保了每次迭代的标准化mini-Batch输出标准化,实现了稳定的训练、高效的优化和潜在的泛化。它已被广泛应用于各种体系结构,并成功地在的不同领域扩散。

尽管BN取得了普遍的成功,但在某些场景时仍然存在问题。BN的限制是它的mini-Batch问题——随着Batch规模变小,BN的误差迅速增加。此外,如果训练数据和测试数据之间存在协变量偏差,则具有朴素BN的网络就会得到显著的退化性能。虽然这些问题在不同的场景和上下文中提出,但用于推理的BN的统计量估计似乎是它们之间的联系:

  1. 如果在测试中修正其统计量的估计,则BN的mini-Batch问题可以得到缓解;
  2. 如果根据可用的测试数据调整统计量的估计,则模型对不可见域数据(损坏的图像)更鲁棒。

本文系统地研究了统计量的估计问题。作者引入了BN的预期统计数据,考虑到在训练过程中具有不同分布激活的模糊统计数据。如果BN的估计总体统计量不等于其期望的总体统计量,将其称为估计偏差,并设计实验来定量研究估计偏差如何对批量归一化网络的影响。

主要观察结果是,BN的估计偏差可以在一个网络中积累(图1(a))。

这一观察结果为解释为什么具有BN的网络在small-batch-size训练下的性能显著退化,以及为什么如果在测试过程中存在输入数据的分布偏移,则需要调整BN的总体统计数据提供了线索。

作者进一步发现BFN对每个样本进行独立归一化,而不需要跨Batch维数,可以阻止BN估计偏差的积累。如果发生了分布偏移,这就缓解了网络的性能退化。

这些观察结果促使了XBNBlock的诞生,可以在残差网络的bottleneck中用BFN取代了一个BN。

作者将所提出的XBNBlock应用于ResNet和ResNeXt体系结构,并在ImageNet和COCO基准测试上进行了实验。XBNBlock持续提高架构的性能。

2相关工作

2.1 估计和使用统计量

BN存在小批量的问题,因为统计量的估计可能不准确。为了解决这个问题,很多研究提出了各种BFN,例如,层归一化(LN)和组归一化(GN)。这些工作在训练和推理过程中对每个样本都执行相同的归一化操作。

另一种减少训练和推理之间差异的方法是将估计的总体统计量与小批量统计数据结合起来,在训练期间进行归一化。这些工作可能优于在small-batch-size下训练的BN,其中估计是主要问题,但当批处理大小中等时,它们的性能通常较差。

一些工作只集中在推理过程中估计校正后的归一化统计量,无论是领域自适应、鲁棒性还是小批量训练。这些策略并不影响模型的训练方案。

  • Li等人提出了域自适应的自适应批归一化(AdaBN),其中在测试过程中对可用目标域的BN统计量的估计进行调制。进一步利用这一思想提高输入数据在协变量偏移下的鲁棒性。

  • 另一种工作通过在推理过程中优化样本权重来纠正小批量训练的归一化统计,寻求总体统计的归一化输出与在训练过程中使用小批量统计观察到的相似。

  • 此外,还考虑了深度生成模型的预测时间batch量设置,并防止测试数据的协变量偏移,其中使用来自测试数据的小批量统计数据进行推断。

与上面显示的工作相比,本文的工作重点是研究网络中BN的估计偏移。设计了将BN和BFN混合的XBN-Block,以阻止BNs估计偏移的积累。

2.2 将BN与其他归一化方法相结合

研究人员还通过结合不同的标准化策略来构建一层的标准化模块。

Luo等人提出了可切换归一化(SN),它通过学习不同的Softmax的重要性权重,将引入的稀疏性约束、白化操作等操作进行动态计算。

其他方法解决了特定场景中归一化方法的组合,包括图像风格转移、图像到图像转换、域泛化和元学习场景。

与这些旨在在一个层中构建规范化模块的方法不同,本文提出的XBN-Block是一个混合在不同层中的BN和BFN的构建块。此外,作者观察到,BFN可以阻断网络中BNs估计偏移的积累,这为解释上述方法与其他归一化方法相结合的成功提供了一个新的观点。

本文工作与IBN-Net密切相关,它仔细地将实例规范化(IN)和BN集成为构建块,并可以封装到几个深度网络中,以提高它们的性能。

请注意,IBNNet仔细设计了IN的位置及其通道号,而XBNBlock的设计被简化了。此外,IBN-Net的动机是IN可以学习样式不变特征,从而有利于泛化,而XBNBlock的动机是BFN可以缓解BN的估计偏移,从而避免其在估计不准确时的测试性能退化的问题。

在这里,作者强调了BFN(例如,IN)可以阻止BNs估计偏移的累计,这也为IBN-Net测试性能的成功提供了一个合理的解释,特别是在分布位移的情况下。

3理论前提

3.1 Batch normalization

是给定的多层感知器(MLP)的输入。在训练过程中,批归一化将m个小批数据中的每个神经元/通道归一化为:

其中,分别是每个神经元的均值和方差,是一个很小的数字,以防止数值不稳定。

在推理/测试过程中,BN需要层输入的总体均值和方差来进行确定性预测为:

尽管层输入的总体统计量{}是不明确的,它们的估计量{}通常在上式中使用。通过计算更新因子α在不同训练迭代t上的小批统计数据的运行平均值,如下:

BN在训练和推理过程中的差异限制了其在递归神经网络中的使用,或者有损小批量训练的性能,因为估计可能不准确。

3.2 Batch-free normalization

Batch-free normalization避免沿Batch维度归一化,从而避免了统计量估计的问题。这些方法在训练和推理过程中使用了一致的操作。一种代表性的方法是层归一化(LN),它对每个训练样本神经元的层输入进行标准化,如下:

式中,分别为每个样本的均值和方差。LN通过进一步推广为组归一化(GN),将神经元划分为组,并分别在各组神经元内进行标准化。

通过改变组数,GN比LN更灵活,使其能够在小批量训练(如目标检测和分割)上获得良好的性能。虽然这些BFN方法可以在某些场景中很好地工作,但在大多数情况下,它们无法匹配BN的性能,并且在CNN架构中并不常用。

4BN的估计偏移

4.1 BN的预期统计数据

设S是训练集,是训练过程中采样的小批量数据。考虑一个带有BN的神经网络,这里定义

某些训练集S的总体统计量是定义良好的,并且可以利用的小批量统计量直接很好地估计它们。然而,激活的总体统计量是不明确的,因为X在训练过程中由于每次迭代中参数θ的更新而发生变化。

事实上,X的小批样本是,它不仅依赖于小批输入,还依赖于模型序列。因此,X的期望统计量应该是训练集S和训练过程中变化的模型序列的函数。

尽管很难从统计视图中明确定义X的总体统计量,但注意到子网络的小批输入总是每次迭代的标准化分布。因此,X的期望统计量应该确保在测试集上的标准化输出的标准化。作者隐式地定义了BN的期望统计量如下。

是训练集S上的训练模型。给定测试集,参考是BN的期望统计量,其中分别是BN的输入的均值(方差)。

注意,期望统计量的定义在训练模型条件输入测试集S的而不是训练集S',因为统计量只考虑最后训练的模型,而不是模型序列

事实上,一旦模型被训练好,的统计数据就可以很容易地计算出来。然而,它们的泛化性能通常比Eqn3中显示的运行平均性能要差。

4.2 对估计偏移的研究

给定定义的BN的期望统计量,如果其估计的统计量不等于其期望的统计量,称为BN的估计偏移

研究BN的估计偏移如何影响批处理归一化网络的性能是很重要的。因此,作者尝试寻求定量地衡量估计的统计量与其预期的统计量之间的差异的大小。

为BN的期望均值(方差),是估计的BN的期望均值(方差)。将估计偏移幅度(ESM)定义为它们的差值的l2-范数。例如,

在接下来的部分中,将设计实验来研究BN的估计偏移如何影响批处理归一化网络的性能,以及如何对其进行修正。

1、网络中估计偏移的累积

作者考虑了2个实验设置:

  1. 在设置1中,使用等于测试集S'的训练集S来研究在没有输入数据分布偏移的情况下BN的估计偏移
  2. 在设置2中,训练集S从测试集S'中采样。通过改变S的大小来调节训练集和测试集之间的分布偏移。

第1步:

实验配置的细节和结果如图2所示。可以观察到,在前30个Epoch,训练误差和测试误差之间存在显著的差距。

请注意,如果BN在训练和推理过程中采用了相同的操作,那么这个设置中的训练和测试误差应该是相同的。

在图2(b)和(c)中,某些层中BN的在前30个Epoch显著大于0,然后逐渐收敛到0。这一现象清楚地表明,训练和测试之间的误差差距主要是由于BN的总体统计量估计不准确造成的。

一个重要的观察结果是:较深层BN的在前30个Epoch可能具有更高的值。这意味着浅层的估计会影响深层的估计。如果浅层的BN发生估计偏移,则深层的BN的估计偏移就会被放大。因此,由于BN层的堆栈,对统计数据的不准确估计可能会被积累放大。

第2步:

在这个设置中,训练集S从测试集S'中采样,改变训练集|S|的大小来调节训练集和测试集之间的分布位移。希望看到不同的分布变化如何影响在一个网络中对BN的统计量的估计。

实验设置和结果的细节如图3所示。当减少图3(b)中采样训练集的大小时,分布差异可能更大,所有BN层的都显著大于零,而在样本较少的模型中,BN层的更高。

此外,在图3(a)中,可以看到所有的模型都可以用零训练误差进行训练,而如果一个模型在样本较少的训练集上进行训练,测试误差显著更高。这些观察结果表明,训练集和测试集之间的输入分布偏差会导致BN的估计偏差,从而对测试性能产生不利影响。

例如,作者发现不使用BN的模型的检验误差为57.73%,而使用BN模型的检验误差为73.02%。

一个重要的观察结果是,更深层的BN的在训练结束时可能具有更高的价值。这一观察结果显示了显著的证据,支持BN的估计偏移可以由于BN层的叠加而积累。此外,如果训练样本较少,输入数据的分布偏移更强,估计偏移更严重。

在这里,作者强调了定义而不是上的BN的期望统计量是很重要的。作者注意到,在这个实验中,BN的逐渐收敛到一个稳定的值(图3(c)),这表明均值所使用的估计收敛于在训练集上对训练模型的估计。如果在上定义了,则将为零。这不是所期望的,因为它没有提供任何信息来诊断在训练集上训练的模型的退化测试性能,并且在测试集上遭受更大的分布偏移。

综上所述,根据上述实验,作者认为BN的估计偏移可能会在具有BN叠加的网络中累积,这可能会对网络的测试性能产生不利影响,特别是在发生分布不同的情况下。

2、阻止估计偏移的累积

实验表明,如果在网络中插入一个BFN,则可以一定程度上缓解BN估计偏移的积累问题。作者把奇数层的BN替换为GN,并将这个网络称为“GNBN”。遵循第4.2.1节中所示的前2个实验设置,分别显示图4和图5的结果。

在图4(a)中的前30个Epoch,训练和测试之间的误差差距显著减少,重要的是图4(b)中观察到,在训练过程中,所有层中BN的几乎相同这意味着奇数层中的GN可能会阻碍其相邻2层中BN的估计偏移的积累。

在图5(a)中可以观察到“GNBN”中的BNs的显著低于原始网络(“BN”)。此外,在训练结束时,不同层间BN的没有显著差异。这些观察结果进一步证实了GN可以阻断相邻2层BN的估计位移的积累。

作者将此归因于训练和推理之间(对于每个样本)的GN的一致操作,这确保了后期层的输入具有几乎相同的分布。如图5(b)中的“GNBN”和“BN”的比较所示,估计位移的阻塞积累确保了网络性能的显著提高。

根据以上实验,作者认为BFN(如GN)可以阻断网络中BN估计位移的积累,如果存在分布偏移,也可以缓解网络的性能退化。

5XBN Block的实现

def GroupNorm(num_features, num_groups=64, eps=1e-5, affine=True, *args, **kwargs):
    if num_groups > num_features:
        print('------arrive maxum groub numbers of:', num_features)
        num_groups = num_features
    return nn.GroupNorm(num_groups, num_features, eps=eps, affine=affine)

5.1 ResNet + XBN Block

class BasicBlock_XBNBlock_P2(nn.Module):
    expansion = 1

    def __init__(self, inplanes, planes, stride=1, downsample=None):
        super(BasicBlock_XBNBlock_P2, self).__init__()
        self.conv1 = conv3x3(inplanes, planes, stride)
        # 原始ResNet
        #self.bn1 = nn.BatchNorm2d(planes)
        # ResNet XBNBlock
        self.bn1 = GroupNorm(planes, num_groups=32)
        self.relu = nn.ReLU(inplace=True)
        self.conv2 = conv3x3(planes, planes)
        self.bn2 = nn.BatchNorm2d(planes)
        self.downsample = downsample
        self.stride = stride

    def forward(self, x):
        residual = x

        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)

        out = self.conv2(out)
        out = self.bn2(out)

        if self.downsample is not None:
            residual = self.downsample(x)

        out += residual
        out = self.relu(out)

        return out

5.2 MobileNet v2 + XBN Block

class InvertedResidual_XBNBlock(nn.Module):
    def __init__(self, inp, oup, stride, expand_ratio):
        super(InvertedResidual_XBNBlock, self).__init__()
        self.stride = stride
        assert stride in [12]

        hidden_dim = int(inp * expand_ratio)
        self.use_res_connect = self.stride == 1 and inp == oup

        if expand_ratio == 1:
            self.conv = nn.Sequential(
                # dw
                nn.Conv2d(hidden_dim, hidden_dim, 3, stride, 1, groups=hidden_dim, bias=False),
                # nn.BatchNorm2d(hidden_dim),
                GroupNorm(hidden_dim, num_groups=16),
                nn.ReLU6(inplace=True),
                # pw-linear
                nn.Conv2d(hidden_dim, oup, 110, bias=False),
                nn.BatchNorm2d(oup),
            )
        else:
            self.conv = nn.Sequential(
                # pw
                nn.Conv2d(inp, hidden_dim, 110, bias=False),
                nn.BatchNorm2d(hidden_dim),
                nn.ReLU6(inplace=True),
                # dw
                nn.Conv2d(hidden_dim, hidden_dim, 3, stride, 1, groups=hidden_dim, bias=False),
                # nn.BatchNorm2d(hidden_dim),
                GroupNorm(hidden_dim, num_groups=16),
                nn.ReLU6(inplace=True),
                # pw-linear
                nn.Conv2d(hidden_dim, oup, 110, bias=False),
                nn.BatchNorm2d(oup),
            )

    def forward(self, x):
        if self.use_res_connect:
            return x + self.conv(x)
        else:
            return self.conv(x)

5.3 ShuffleNet v2 + XBN Block

class ShuffleV2XBNBlock(nn.Module):
    def __init__(self, inp, oup, mid_channels, *, ksize, stride):
        super(ShuffleV2XBNBlock, self).__init__()
        self.stride = stride
        assert stride in [12]

        self.mid_channels = mid_channels
        self.ksize = ksize
        pad = ksize // 2
        self.pad = pad
        self.inp = inp

        outputs = oup - inp

        branch_main = [
            # pw
            nn.Conv2d(inp, mid_channels, 110, bias=False),
            nn.BatchNorm2d(mid_channels),
            nn.ReLU(inplace=True),
            # dw
            nn.Conv2d(mid_channels, mid_channels, ksize, stride, pad, groups=mid_channels, bias=False),
            #nn.BatchNorm2d(mid_channels),
            GroupNorm(mid_channels, num_groups=8),
            # pw-linear
            nn.Conv2d(mid_channels, outputs, 110, bias=False),
            nn.BatchNorm2d(outputs),
            nn.ReLU(inplace=True),
        ]
        self.branch_main = nn.Sequential(*branch_main)

        if stride == 2:
            branch_proj = [
                # dw
                nn.Conv2d(inp, inp, ksize, stride, pad, groups=inp, bias=False),
                #nn.BatchNorm2d(inp),
                GroupNorm(inp, num_groups=8),
                # pw-linear
                nn.Conv2d(inp, inp, 110, bias=False),
                nn.BatchNorm2d(inp),
                nn.ReLU(inplace=True),
            ]
            self.branch_proj = nn.Sequential(*branch_proj)
        else:
            self.branch_proj = None

    def forward(self, old_x):
        if self.stride==1:
            x_proj, x = self.channel_shuffle(old_x)
            return torch.cat((x_proj, self.branch_main(x)), 1)
        elif self.stride==2:
            x_proj = old_x
            x = old_x
            return torch.cat((self.branch_proj(x_proj), self.branch_main(x)), 1)

    def channel_shuffle(self, x):
        batchsize, num_channels, height, width = x.data.size()
        assert (num_channels % 4 == 0)
        x = x.reshape(batchsize * num_channels // 22, height * width)
        x = x.permute(102)
        x = x.reshape(2-1, num_channels // 2, height, width)
        return x[0], x[1]

6实验

OpenCV学堂 专注计算机视觉开发技术分享,技术框架使用,包括OpenCV,Tensorflow,Pytorch教程与案例,相关算法详解,最新CV方向论文,硬核代码干货与代码案例详解!作者在CV工程化方面深度耕耘15年,感谢您的关注!
评论
  • 临近春节,各方社交及应酬也变得多起来了,甚至一月份就排满了各式约见。有的是关系好的专业朋友的周末“恳谈会”,基本是关于2025年经济预判的话题,以及如何稳定工作等话题;但更多的预约是来自几个客户老板及副总裁们的见面,他们为今年的经济预判与企业发展焦虑而来。在聊天过程中,我发现今年的聊天有个很有意思的“点”,挺多人尤其关心我到底是怎么成长成现在的多领域风格的,还能掌握一些经济趋势的分析能力,到底学过哪些专业、在企业管过哪些具体事情?单单就这个一个月内,我就重复了数次“为什么”,再辅以我上次写的:《
    牛言喵语 2025-01-22 17:10 299浏览
  • 随着AI大模型训练和推理对计算能力的需求呈指数级增长,AI数据中心的网络带宽需求大幅提升,推动了高速光模块的发展。光模块作为数据中心和高性能计算系统中的关键器件,主要用于提供高速和大容量的数据传输服务。 光模块提升带宽的方法有两种:1)提高每个通道的比特速率,如直接提升波特率,或者保持波特率不变,使用复杂的调制解调方式(如PAM4);2)增加通道数,如提升并行光纤数量,或采用波分复用(CWDM、LWDM)。按照传输模式,光模块可分为并行和波分两种类型,其中并行方案主要应用在中短距传输场景中成本
    hycsystembella 2025-01-25 17:24 112浏览
  • 项目展示①正面、反面②左侧、右侧项目源码:https://mbb.eet-china.com/download/316656.html前言为什么想到要做这个小玩意呢,作为一个死宅,懒得看手机,但又想要抬头就能看见时间和天气信息,于是就做个这么个小东西,放在示波器上面正好(示波器外壳有个小槽,刚好可以卡住)功能主要有,获取国家气象局的天气信息,还有实时的温湿度,主控采用ESP32,所以后续还可以开放更多奇奇怪怪的功能,比如油价信息、股票信息之类的,反正能联网可操作性就大多了原理图、PCB、面板设计
    小恶魔owo 2025-01-25 22:09 169浏览
  • 故障现象 一辆2007款日产天籁车,搭载VQ23发动机(气缸编号如图1所示,点火顺序为1-2-3-4-5-6),累计行驶里程约为21万km。车主反映,该车起步加速时偶尔抖动,且行驶中加速无力。 图1 VQ23发动机的气缸编号 故障诊断接车后试车,发动机怠速运转平稳,但只要换挡起步,稍微踩下一点加速踏板,就能感觉到车身明显抖动。用故障检测仪检测,发动机控制模块(ECM)无故障代码存储,且无失火数据流。用虹科Pico汽车示波器测量气缸1点火信号(COP点火信号)和曲轴位置传感器信
    虹科Pico汽车示波器 2025-01-23 10:46 165浏览
  • 不让汽车专美于前,近年来哈雷(Harley-Davidson)和本田(Honda)等大型重型机车大厂的旗下车款皆已陆续配备车载娱乐系统与语音助理,在路上也有越来越多的普通机车车主开始使用安全帽麦克风,在骑车时透过蓝牙连线执行语音搜寻地点导航、音乐播放控制或免持拨打接听电话等各种「机车语音助理」功能。客户背景与面临的挑战以本次分享的客户个案为例,该客户是一个跨国车用语音软件供货商,过往是与车厂合作开发前装车机为主,且有着多年的「汽车语音助理」产品经验。由于客户这次是首度跨足「机车语音助理」产品,因
    百佳泰测试实验室 2025-01-24 17:00 82浏览
  • 前篇文章中『服务器散热效能不佳有解吗?』提到气冷式的服务器其散热效能对于系统稳定度是非常重要的关键因素,同时也说明了百佳泰对于散热效能能提供的协助与服务。本篇将为您延伸说明我们如何进行评估,同时也会举例在测试过程中发现的问题及改善后的数据。AI服务器的散热架构三大重点:GPU导风罩:尝试不同的GPU导风罩架构,用以集中服务器进风量,加强对GPU的降温效果。GPU托盘:改动GPU托盘架构,验证出风面积大小对GPU散热的影想程度。CPU导风罩:尝试封闭CPU导风罩间隙,集中风流,验证CPU降温效果。
    百佳泰测试实验室 2025-01-24 16:58 67浏览
  • 书接上回:【2022年终总结】阳光总在风雨后,启航2023-面包板社区  https://mbb.eet-china.com/blog/468701-438244.html 总结2019,松山湖有个欧洲小镇-面包板社区  https://mbb.eet-china.com/blog/468701-413397.html        2025年该是总结下2024年的喜怒哀乐,有个好的开始,才能更好的面对2025年即将
    liweicheng 2025-01-24 23:18 136浏览
  • 高速先生成员--黄刚这不马上就要过年了嘛,高速先生就不打算给大家上难度了,整一篇简单但很实用的文章给大伙瞧瞧好了。相信这个标题一出来,尤其对于PCB设计工程师来说,心就立马凉了半截。他们辛辛苦苦进行PCB的过孔设计,高速先生居然说设计多大的过孔他们不关心!另外估计这时候就跳出很多“挑刺”的粉丝了哈,因为翻看很多以往的文章,高速先生都表达了过孔孔径对高速性能的影响是很大的哦!咋滴,今天居然说孔径不关心了?别,别急哈,听高速先生在这篇文章中娓娓道来。首先还是要对各位设计工程师的设计表示肯定,毕竟像我
    一博科技 2025-01-21 16:17 197浏览
  •     IPC-2581是基于ODB++标准、结合PCB行业特点而指定的PCB加工文件规范。    IPC-2581旨在替代CAM350格式,成为PCB加工行业的新的工业规范。    有一些免费软件,可以查看(不可修改)IPC-2581数据文件。这些软件典型用途是工艺校核。    1. Vu2581        出品:Downstream     
    电子知识打边炉 2025-01-22 11:12 227浏览
  • 飞凌嵌入式基于瑞芯微RK3562系列处理器打造的FET3562J-C全国产核心板,是一款专为工业自动化及消费类电子设备设计的产品,凭借其强大的功能和灵活性,自上市以来得到了各行业客户的广泛关注。本文将详细介绍如何启动并测试RK3562J处理器的MCU,通过实际操作步骤,帮助各位工程师朋友更好地了解这款芯片。1、RK3562J处理器概述RK3562J处理器采用了4*Cortex-A53@1.8GHz+Cortex-M0@200MHz架构。其中,4个Cortex-A53核心作为主要核心,负责处理复杂
    飞凌嵌入式 2025-01-24 11:21 167浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦