深度学习(GoogLeNet)

深度学习(GoogLeNet)1GoogLeNet的介绍1.1GoogLeNet的简介GoogLeNet模型是由谷歌(Google)团队开发出来的卷积神经网络,它是2014年ImageNet挑战赛的冠军模型。相比于AlexNet模型,GoogLeNet模型的网络结构更深,共包括87层。尽管模型结构变得更复杂,但参数量更少了。GoogLeNet模型的参数量为5941552个,仅为AlexNet模型参数量的1/10。这主要归功于GoogLeNet创新性地采用了Inception模块。感兴趣的读者可以阅读原始顶会顶刊http://

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

本篇文章采用百度paddlepaddle深度学习框架,并在百度Ai Studio平台上运行。

本篇文章基于PaddlePaddle2.0-构建卷积网络GoogLeNet,不了解2.0API的读者可以参考深度学习(paddle2.0 API)_无意2121的博客-CSDN博客

目录

1 GoogLeNet的介绍

1.1 GoogLeNet的简介

1.2 GoogLeNet 原始论文

1.2.1 论文标题的来源

1.2.2 GoogLeNet 提出的原因

2 GoogLeNet 创新点

2.1 inception(原生模块)的结构

​2.2 inception(原生模块)的优势

2.3 inception(具有降维功能)的结构

2.4 1*1卷积核的作用

2.5 GAP

2.6 两个辅助分类器

3 GoogLeNet的定义

3.1 GoogLeNet的总体架构

3.2 GoogLeNet的变种

3.3 GoogLeNet的完整代码定义

4 构建GoogLeNet做CIFAR图像识别


1 GoogLeNet的介绍

1.1 GoogLeNet的简介

GoogLeNet模型是由谷歌(Google)团队开发出来的卷积神经网络,它是2014年ImageNet挑战赛的冠军模型。相比于AlexNet模型,GoogLeNet模型的网络结构更深,共包括87层。尽管模型结构变得更复杂,但参数量更少了。GoogLeNet模型的参数量为5941552个,仅为AlexNet模型参数量的1/10。这主要归功于GoogLeNet创新性地采用了Inception模块。感兴趣的读者可以阅读原始顶会顶刊http://arxiv.org/abs/1409.4842

1.2 GoogLeNet 原始论文

1.2.1 论文标题的来源

有趣的是原始论文的标题《Going deeper with convolutions》来自这个表情包

深度学习(GoogLeNet)

1.2.2 GoogLeNet 提出的原因

从 LeNet 开始,卷积神经网络通常有一个标准范式(结构) – 堆叠卷积层(后跟归一化和最大池化),然后跟一个或多个全连接层,这种模式及其优化后的模式确实在图像分类中取得较好的结果。

但为了获得更好的神经网络性能,这时候我们就需要扩大网络规模(增加网络层数及其宽度),但是更大的规模意味着更多的参数,容易出现过拟合,尤其是在训练集中标记示例的数量有限的情况下。增加网络规模的另一个缺点是计算资源的使用急剧增加

为了解决这两个问题,他们将原本密集连接的神经网络转向稀疏连接的神经网络。Aroar基于模仿生物系统的神经网络模型研究结论提出,一个基于稀疏结构的深度、宽度神经网络经过数据信息的输入后,末端神经节点中反映该数据信息特征的节点将总是处于激活状态。假如要识别一只猫,有些神经元是识别猫眼睛,有些是识别猫鼻子、猫尾巴等,如果图像真的是一只猫,这些特征会一起激活。虽然严格的数学证明需要很强的条件,但事实上这个陈述与赫布理论类似。这表明稀疏连接的神经网络具有一定科学性,但是,计算机软硬件对非均匀稀疏数据的计算效率很差

现在的问题是有没有一种方法,既能保持网络结构的稀疏性,又能利用密集矩阵的高计算性能。大量的文献表明可以将稀疏矩阵聚类为较为密集的子矩阵来提高计算性能,据此论文提出了名为inception的结构来实现此目的。

2 GoogLeNet 创新点

2.1 inception(原生模块)的结构

通过赫布理论与多尺度处理,论文提出了一种多通路 (inception) 的设计方案,即在网络同一层将不同尺寸的卷积核并联放置

深度学习(GoogLeNet)

(1) 将不同尺寸的卷积核放在同一层,意味着有不同大小的感受野,可以提取到不同特征,最后拼接特征,相当于对不同特征进行融合。

(2)之所以卷积核大小采用1、3、5,主要是为了输出维度一致。设定卷积核移动步长stride=1之后,只要分别设定padding=0、1、2,那么卷积之后便可以得到相同尺寸的特征,然后这些特征就可以直接聚合在一起了。

(3)论文表明pooling在实验中是有效的,所以Inception里面也有。
(4)网络越到后面,特征越抽象,而且每个特征所涉及的感受野也更大了,因此随着层数的增加,3×3和5×5卷积的比例也要增加。

深度学习(GoogLeNet)

2.2 inception(原生模块)的优势

多个尺寸上进行卷积再聚合的优势

  • 直观感觉上在多个尺度上同时进行卷积,能提取到不同尺度的特征。特征更为丰富也意味着最后分类判断时更加准确。
  • 利用稀疏矩阵分解成密集矩阵计算的原理可以加快收敛速度。用稀疏的分散的网络,对它们进行汇总,就可以取代一些庞大臃肿的网络。稀疏矩阵的分解示意图如下

 深度学习(GoogLeNet)

这个原理在inception中就是在特征维度上进行分解

传统的卷积层的输入数据只与一种尺度(例如3*3)的卷积核进行卷积,输出固定维度(例如192个特征)的数据。而这192个特征是平均分布在3*3的尺度范围上的,这可以理解为输出了一个稀疏均匀分布的特征集。而在inception模块中在多个尺寸的卷积核下提取特征,输出的192个特征不是均匀分布的,而是相关性强的特征聚合在一起。比如3*3的96个特征聚合在一起,5*5的96个特征聚合在一起,这也可以理解为多个密集分布的子集合。由于相关性强的特征聚合在一起,同时相关性弱的特征就被弱化,因此冗余的数据比较少,也就是数据的有效性非常强,这能够加快收敛速度。

深度学习(GoogLeNet)

换句话说,即神经元同时激活的情况下,将联合评判做出结论!意味着神经元传递信息可能不是简单的复制逐层传递,而是并行的同时传递,这也反映着inception更逼近真实生物系统的神经网络。

2.3 inception(具有降维功能)的结构

简单的多通路拼接会造成通道数迅速增长,导致计算量和复杂度增高。在3*3与5*5的卷积核之前,先经过1*1的卷积核,这样的设置能够把通道数减少。在3*3的池化层之后,用1*1卷积核降维。

深度学习(GoogLeNet)

 因此,我们可以看到具有降维功能的inception的最大创新之处是加入了1*1的卷积核。最终GooLeNet 用的inception 是改进后的具有降维功能的inception。代码如下

class Inception(paddle.nn.Layer):
    def __init__(self, in_channels, c1, c2, c3, c4):
        '''
        c1:第一条支路1x1卷积的输出通道数,数据类型是整数
        c2:第二条支路卷积的输出通道数,数据类型是tuple或list,  
            其中c2[0]是1x1卷积的输出通道数,c2[1]是3x3
        c3: 第三条支路卷积的输出通道数,数据类型是tuple或list,  
            其中c3[0]是1x1卷积的输出通道数,c3[1]是3x3
        c4:第四条支路1x1卷积的输出通道数,数据类型是整数
        '''
        super(Inception, self).__init__()
        #路线1,卷积核1x1
        self.route1x1_1 = paddle.nn.Conv2D(in_channels, c1, kernel_size=1)
        #路线2,卷积层1x1、卷积层3x3
        self.route1x1_2 = paddle.nn.Conv2D(in_channels, c2[0], kernel_size=1)
        self.route3x3_2 = paddle.nn.Conv2D(c2[0], c2[1], kernel_size=3, padding=1)
        #路线3,卷积层1x1、卷积层5x5
        self.route1x1_3 = paddle.nn.Conv2D(in_channels, c3[0], kernel_size=1)
        self.route5x5_3 = paddle.nn.Conv2D(c3[0], c3[1], kernel_size=5, padding=2)
        #路线4,池化层3x3、卷积层1x1
        self.route3x3_4 = paddle.nn.MaxPool2D(kernel_size=3, stride=1, padding=1)
        self.route1x1_4 = paddle.nn.Conv2D(in_channels, c4, kernel_size=1)

    def forward(self, x):
        route1 = F.relu(self.route1x1_1(x))
        route2 = F.relu(self.route3x3_2(F.relu(self.route1x1_2(x))))
        route3 = F.relu(self.route5x5_3(F.relu(self.route1x1_3(x))))
        route4 = F.relu(self.route1x1_4(self.route3x3_4(x)))
        out = [route1, route2, route3, route4]
        return paddle.concat(out, axis=1)  #在通道维度(axis=1)上进行连接

def BasicConv2d(in_channels, out_channels, kernel, stride=1, padding=0):
    layer = paddle.nn.Sequential(
                paddle.nn.Conv2D(in_channels, out_channels, kernel, stride, padding), 
                paddle.nn.BatchNorm2D(out_channels, epsilon=1e-3),
                paddle.nn.ReLU())
    return layer

2.4 1*1卷积核的作用

深度学习(GoogLeNet)

(1)1*1的卷积核相当于对所有特征进行一次相同权重的全连接的计算

(2)减少通道数,而不改变输出的宽度与高度,起到降维的作用,减少计算复杂度

(3)只要最后输出的特征数不变,中间的降维类似于压缩的效果,并不影响最终训练的结果

深度学习(GoogLeNet)

第一种没有1*1卷积核的参数量=256*3*3*256=589824

第二种有1*1卷积核的参数量=256*1*1*32+32*3*3*256=81920

可见大大减少参数量

2.5 GAP

无论是 AlexNet 还是 VGG,最后的卷积层和全连接层相连,参数量是巨大的(占网络参数量的 70-90% 左右)。GoogLeNet 采用了全局平均池化 Global Average Pooling 代替全连接

 深度学习(GoogLeNet)

2.6 两个辅助分类器

通过添加连接到这些中间层的辅助分类器,作用是尽快学到可分类的特征,相当于是起到了一个正则化的作用,防止梯度消失。这些分类器采用较小卷积网络的形式,放置在Inception (原生模块) 和 Inception (具有降维功能)模块的输出之上。

3 GoogLeNet的定义

3.1 GoogLeNet的总体架构

拥有上述9个inception

深度学习(GoogLeNet)

局部响应归一化(Local Response Normalization,LRN)技术是首次在 AlexNet 模型中提出这个概念

深度学习(GoogLeNet)

3.2 GoogLeNet的变种

本篇文章主要讲解inception v1,改进的版本这里不再赘述

深度学习(GoogLeNet)

3.3 GoogLeNet的完整代码定义

#构建模型
class Inception(paddle.nn.Layer):
    def __init__(self, in_channels, c1, c2, c3, c4):
        '''
        c1:第一条支路1x1卷积的输出通道数,数据类型是整数
        c2:第二条支路卷积的输出通道数,数据类型是tuple或list,  
            其中c2[0]是1x1卷积的输出通道数,c2[1]是3x3
        c3: 第三条支路卷积的输出通道数,数据类型是tuple或list,  
            其中c3[0]是1x1卷积的输出通道数,c3[1]是3x3
        c4:第四条支路1x1卷积的输出通道数,数据类型是整数
        '''
        super(Inception, self).__init__()
        #路线1,卷积核1x1
        self.route1x1_1 = paddle.nn.Conv2D(in_channels, c1, kernel_size=1)
        #路线2,卷积层1x1、卷积层3x3
        self.route1x1_2 = paddle.nn.Conv2D(in_channels, c2[0], kernel_size=1)
        self.route3x3_2 = paddle.nn.Conv2D(c2[0], c2[1], kernel_size=3, padding=1)
        #路线3,卷积层1x1、卷积层5x5
        self.route1x1_3 = paddle.nn.Conv2D(in_channels, c3[0], kernel_size=1)
        self.route5x5_3 = paddle.nn.Conv2D(c3[0], c3[1], kernel_size=5, padding=2)
        #路线4,池化层3x3、卷积层1x1
        self.route3x3_4 = paddle.nn.MaxPool2D(kernel_size=3, stride=1, padding=1)
        self.route1x1_4 = paddle.nn.Conv2D(in_channels, c4, kernel_size=1)

    def forward(self, x):
        route1 = F.relu(self.route1x1_1(x))
        route2 = F.relu(self.route3x3_2(F.relu(self.route1x1_2(x))))
        route3 = F.relu(self.route5x5_3(F.relu(self.route1x1_3(x))))
        route4 = F.relu(self.route1x1_4(self.route3x3_4(x)))
        out = [route1, route2, route3, route4]
        return paddle.concat(out, axis=1)  #在通道维度(axis=1)上进行连接

def BasicConv2d(in_channels, out_channels, kernel, stride=1, padding=0):
    layer = paddle.nn.Sequential(
                paddle.nn.Conv2D(in_channels, out_channels, kernel, stride, padding), 
                paddle.nn.BatchNorm2D(out_channels, epsilon=1e-3),
                paddle.nn.ReLU())
    return layer

class GoogLeNet(paddle.nn.Layer):
    def __init__(self, in_channel, num_classes):
        super(GoogLeNet, self).__init__()
        self.b1 = paddle.nn.Sequential(
                    BasicConv2d(in_channel, out_channels=64, kernel=7, stride=2, padding=3),
                    paddle.nn.MaxPool2D(3, 2))
        self.b2 = paddle.nn.Sequential(
                    BasicConv2d(64, 64, kernel=1),
                    BasicConv2d(64, 192, kernel=3, padding=1),
                    paddle.nn.MaxPool2D(3, 2))
        self.b3 = paddle.nn.Sequential(
                    Inception(192, 64, (96, 128), (16, 32), 32),
                    Inception(256, 128, (128, 192), (32, 96), 64),
                    paddle.nn.MaxPool2D(3, 2))
        self.b4 = paddle.nn.Sequential(
                    Inception(480, 192, (96, 208), (16, 48), 64),
                    Inception(512, 160, (112, 224), (24, 64), 64),
                    Inception(512, 128, (128, 256), (24, 64), 64),
                    Inception(512, 112, (144, 288), (32, 64), 64),
                    Inception(528, 256, (160, 320), (32, 128), 128),
                    paddle.nn.MaxPool2D(3, 2))
        self.b5 = paddle.nn.Sequential(
                    Inception(832, 256, (160, 320), (32, 128), 128),
                    Inception(832, 384, (182, 384), (48, 128), 128),
                    paddle.nn.AvgPool2D(2))
        self.flatten=paddle.nn.Flatten()
        self.b6 = paddle.nn.Linear(1024, num_classes)
        
    def forward(self, x):
        x = self.b1(x)
        x = self.b2(x)
        x = self.b3(x)
        x = self.b4(x)
        x = self.b5(x)
        x = self.flatten(x)
        x = self.b6(x)
        return x

4 构建GoogLeNet做CIFAR图像识别

自行调整超参数

import paddle
import paddle.nn.functional as F
import numpy as np
from paddle.vision.transforms import Compose, Resize, Transpose, Normalize

t = Compose([Resize(size=96),Normalize(mean=[127.5, 127.5, 127.5], std=[127.5, 127.5, 127.5], data_format='HWC'),Transpose()]) #数据转换

cifar10_train = paddle.vision.datasets.cifar.Cifar10(mode='train', transform=t, backend='cv2')
cifar10_test = paddle.vision.datasets.cifar.Cifar10(mode="test", transform=t, backend='cv2')

#构建模型
class Inception(paddle.nn.Layer):
    def __init__(self, in_channels, c1, c2, c3, c4):
        '''
        c1:第一条支路1x1卷积的输出通道数,数据类型是整数
        c2:第二条支路卷积的输出通道数,数据类型是tuple或list,  
            其中c2[0]是1x1卷积的输出通道数,c2[1]是3x3
        c3: 第三条支路卷积的输出通道数,数据类型是tuple或list,  
            其中c3[0]是1x1卷积的输出通道数,c3[1]是3x3
        c4:第四条支路1x1卷积的输出通道数,数据类型是整数
        '''
        super(Inception, self).__init__()
        #路线1,卷积核1x1
        self.route1x1_1 = paddle.nn.Conv2D(in_channels, c1, kernel_size=1)
        #路线2,卷积层1x1、卷积层3x3
        self.route1x1_2 = paddle.nn.Conv2D(in_channels, c2[0], kernel_size=1)
        self.route3x3_2 = paddle.nn.Conv2D(c2[0], c2[1], kernel_size=3, padding=1)
        #路线3,卷积层1x1、卷积层5x5
        self.route1x1_3 = paddle.nn.Conv2D(in_channels, c3[0], kernel_size=1)
        self.route5x5_3 = paddle.nn.Conv2D(c3[0], c3[1], kernel_size=5, padding=2)
        #路线4,池化层3x3、卷积层1x1
        self.route3x3_4 = paddle.nn.MaxPool2D(kernel_size=3, stride=1, padding=1)
        self.route1x1_4 = paddle.nn.Conv2D(in_channels, c4, kernel_size=1)

    def forward(self, x):
        route1 = F.relu(self.route1x1_1(x))
        route2 = F.relu(self.route3x3_2(F.relu(self.route1x1_2(x))))
        route3 = F.relu(self.route5x5_3(F.relu(self.route1x1_3(x))))
        route4 = F.relu(self.route1x1_4(self.route3x3_4(x)))
        out = [route1, route2, route3, route4]
        return paddle.concat(out, axis=1)  #在通道维度(axis=1)上进行连接

def BasicConv2d(in_channels, out_channels, kernel, stride=1, padding=0):
    layer = paddle.nn.Sequential(
                paddle.nn.Conv2D(in_channels, out_channels, kernel, stride, padding), 
                paddle.nn.BatchNorm2D(out_channels, epsilon=1e-3),
                paddle.nn.ReLU())
    return layer

class GoogLeNet(paddle.nn.Layer):
    def __init__(self, in_channel, num_classes):
        super(GoogLeNet, self).__init__()
        self.b1 = paddle.nn.Sequential(
                    BasicConv2d(in_channel, out_channels=64, kernel=7, stride=2, padding=3),
                    paddle.nn.MaxPool2D(3, 2))
        self.b2 = paddle.nn.Sequential(
                    BasicConv2d(64, 64, kernel=1),
                    BasicConv2d(64, 192, kernel=3, padding=1),
                    paddle.nn.MaxPool2D(3, 2))
        self.b3 = paddle.nn.Sequential(
                    Inception(192, 64, (96, 128), (16, 32), 32),
                    Inception(256, 128, (128, 192), (32, 96), 64),
                    paddle.nn.MaxPool2D(3, 2))
        self.b4 = paddle.nn.Sequential(
                    Inception(480, 192, (96, 208), (16, 48), 64),
                    Inception(512, 160, (112, 224), (24, 64), 64),
                    Inception(512, 128, (128, 256), (24, 64), 64),
                    Inception(512, 112, (144, 288), (32, 64), 64),
                    Inception(528, 256, (160, 320), (32, 128), 128),
                    paddle.nn.MaxPool2D(3, 2))
        self.b5 = paddle.nn.Sequential(
                    Inception(832, 256, (160, 320), (32, 128), 128),
                    Inception(832, 384, (182, 384), (48, 128), 128),
                    paddle.nn.AvgPool2D(2))
        self.flatten=paddle.nn.Flatten()
        self.b6 = paddle.nn.Linear(1024, num_classes)
        
    def forward(self, x):
        x = self.b1(x)
        x = self.b2(x)
        x = self.b3(x)
        x = self.b4(x)
        x = self.b5(x)
        x = self.flatten(x)
        x = self.b6(x)
        return x

epoch_num = 20
batch_size = 256
learning_rate = 0.001

val_acc_history = []
val_loss_history = []

def train(model):
    #启动训练模式
    model.train()

    opt = paddle.optimizer.Adam(learning_rate=learning_rate, parameters=model.parameters())
    train_loader = paddle.io.DataLoader(cifar10_train, shuffle=True, batch_size=batch_size)
    valid_loader = paddle.io.DataLoader(cifar10_test, batch_size=batch_size)

    for epoch in range(epoch_num):
        for batch_id, data in enumerate(train_loader()):
            x_data = paddle.cast(data[0], 'float32')
            y_data = paddle.cast(data[1], 'int64')
            y_data = paddle.reshape(y_data, (-1, 1))

            y_predict = model(x_data)
            loss = F.cross_entropy(y_predict, y_data)
            loss.backward()
            opt.step()
            opt.clear_grad()
        
        print("训练轮次: {}; 损失: {}".format(epoch, loss.numpy()))

        #启动评估模式
        model.eval()
        accuracies = []
        losses = []
        for batch_id, data in enumerate(valid_loader()):
            x_data = paddle.cast(data[0], 'float32')
            y_data = paddle.cast(data[1], 'int64')
            y_data = paddle.reshape(y_data, (-1, 1))

            y_predict = model(x_data)
            loss = F.cross_entropy(y_predict, y_data)
            acc = paddle.metric.accuracy(y_predict, y_data)
            accuracies.append(np.mean(acc.numpy()))
            losses.append(np.mean(loss.numpy()))

        avg_acc, avg_loss = np.mean(accuracies), np.mean(losses)
        print("评估准确度为:{};损失为:{}".format(avg_acc, avg_loss))
        val_acc_history.append(avg_acc)
        val_loss_history.append(avg_loss)
        model.train()

model = GoogLeNet(3, 10)
train(model)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/170454.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • mvel语法指南_日语语法指南app

    mvel语法指南_日语语法指南appmvel受到了java语法的启发,但是存在一些根本性的差异,mvel旨在使其成为更有效的表达式语言.比如直接支持集合、数组和字符串匹配,正则表达式的运算操作等.      mvel2.x有以下几个部分组成: PropertyexpressionsBooleanexpressionsMethodinvocationsVariableassignmentsFunctionde

  • git切换分支并与远程分支关联_git 拉取分支

    git切换分支并与远程分支关联_git 拉取分支git切换远程分支为developgitpush–set-upstreamorigin分支名gitpush–set-upstreamorigindevelop

  • 机房搬迁是什么意思_计算机机房管理规定

    机房搬迁是什么意思_计算机机房管理规定原标题:盘点机房搬迁中最容易出现的五个问题企业要更换办公地址的时候,最头疼的问题就是搬迁机房,机房的搬迁可不是搬家那么简单,是否能顺利搬迁,将成为保障企业业务连续性的关键要素。在企业机房的搬迁中,最容易出现哪些问题?盘点机房搬迁中最容易出现的五个问题(1)领导不明确在规划阶段最常见的错误是未能建立明确的领导。这意味着在迁移过程中的各个阶段中要确定谁负责明确的沟通,带领团队。在一个单一的部门,默认…

    2022年10月30日
  • jQuery中AJAX写法「建议收藏」

    jQuery中AJAX写法「建议收藏」前言  在jQuery中AJAX的写法有3种,$ajax,$post,$get这三种。其中$post和$get是简易写法,高层的实现,在调用他们的时候,会运行底层封装好的$ajax。运用get方式一$.get("test.cgi",{name:"John",time:"2pm"},function(data){alert("DataLoaded:"+data…

  • PhpStorm激活码2021.04(最新序列号破解)

    PhpStorm激活码2021.04(最新序列号破解),https://javaforall.cn/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

  • 天翼1号 2021 5G全网通云手机_2021年再买5g手机

    天翼1号 2021 5G全网通云手机_2021年再买5g手机2021年天翼智能生态博览会期间,展锐基于中国电信的5GSA网络,在天翼1号2021手机上完成了5G网络切片端到端业务验证,成功验证了云监控、云桌面、云手机、天翼超高清、小翼管家、云游戏等业务,这标志着天翼1号2021已具备网络切片能力。演示采用的切片目标方案由展锐和中国电信研究院联合研发,方案基于展锐调制解调器中心化(Modem-Centric)架构设计,中国电信研究院研发了终端切片中间件SDK,天翼1号终端适配开发,成功实现了应用程序未作任何修改的前提下顺利接入5G切片网络。本次业务验证意味着应用

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号