Press "Enter" to skip to content

深入浅出计算机视觉

本站内容均来自兴趣收集,如不慎侵害的您的相关权益,请留言告知,我们将尽快删除.谢谢.

本文通过案例引入计算机视觉基本知识,并浅析其基本任务中的图像分类、图像分割进展及应用。

 

历史文章回顾: HBase Replication详解

 

Foreword

 

前言

 

先上几个计算机视觉应用的案例:

 

 

6月6日至8日,在第23届圣彼得堡国际经济论坛上,新华社、俄罗斯塔斯社和搜狗公司联合推出了全球首个俄语AI合成主播,未来它将被应用于塔斯社的新闻报道中。塔斯社是俄罗斯的国家通讯社,作为全球五大通讯社之一,对外向115个国家和地区提供新闻信息,在全球范围都具有广泛影响力。

 

 

MAGIC短视频智能生产平台由新华社和阿里巴巴联合成立的新华智云科技有限公司独立研发。在世界杯期间,通过MAGIC生产的短视频达到了37581 条,平均一条视频耗时50.7秒,全网实现了116604975次播放!而其中制作速度 快的一段视频《俄罗斯2:0领先埃及》,仅耗时6秒!

 

 

上面的人脸都是AI生成的假脸,这些人都是不存在的,是英伟达的利用GAN模型(生成对抗网络)生成的数据。

 

Computer Vision

 

 

 

计算机视觉的研究目标是使计算机程序能够解读和理解图片,不仅是理解图片的颜色,而且是更高层地理解图片的语义及特征,通俗的点说就是让计算机睁眼“看”世界。人类大脑皮层的70%活动都在处理视觉信息,所以从感知的角度来讲,视觉是重要的信息感知功能。

 

如下几件事推动了视觉的发展:

 

1、深度学习领域的突破,深度学习搭建在神经网络之上,而神经网络的概念则脱胎于上世纪50年代科研人员对人类脑神经系统的研究和模拟。神经网络的理论在上世纪50年代就有了,但是一直处于浅层的应用状态,人们没有想到多层会带来什幺新的变化。

 

2、 英伟达研发了GPU,持续的提高了算力,由于天然的并行计算和矩阵处理能力,大大加速了图像处理的过程和神经网络的计算过程。 至今,在2012 年训练AlexNet模型需要使用两块GPU,花费6天时间,到今天做同样的事情只需要一块 新GPU,十几分钟就能搞定。

 

3、斯坦福大学教授李飞飞创建了ImageNet,她把数百万张照片发到了网络上并发动群众做了标注。真正引起大家注意的就是2012年斯坦福的实验,过去实验的图像样本数多是“万”这个级别,斯坦福用了1000万,用多层神经网络来做,结果发现在人脸、人体、猫脸三个图像类别中,这个模型的识别率大概有7%-10%的提高。这给大家非常大的震动,因为通常识别率要提高1%要做好多努力,现在只是把层数增加了,竟然发生两大变化,一个是识别率提高这幺多;第二个是能处理这幺大数据。这两个变化给大家非常大的鼓舞,何况在2012年之前,人工智能没有解决过实际问题。2015 年12月,微软通过152层的深度网络,将图像识别错误率在ImageNet上降至3.57%,低于人类的误识率5.1%。

 

下图是ImageNet上图片分类的进展情况,柱状图越低代表错误率越低:

 

 

Deep Learning

 

深度学习

 

 

我们现在处于人工智能的第三次崛起。 前两波发生在1950-1960年代和1980-1990 年代,当时都产生了相当大的影响,却也都慢慢冷却下来。 这是因为当时的神经网络既没有实现本该达成的性能提升,也没有帮助我们理解生物的视觉系统。 第三次浪潮21世纪初至今,此次与前两次不同,深度学习在很多基准测试和现实应用上已经大幅超越了生物的能力。

 

深度学习一般是指的深度神经网络,也称DNN(Deep Neural Networks),神经网络在20世纪50年代就被提出来了,但是由于他本身固有的梯度消失,大量参数导致过拟合和计算量太大等问题,导致实际应用效果一直不好。因此在此之前机器学习几乎一直是SVM一统天下的局面。

 

深度学习是在2006年Hinton等人被提出以来的,但是其真正的兴起,或者说重大影响工作的出现,是在2012年之后,比如,Krizhevsky等用深度学习大幅度提高了图片分类的准确率,也就是Alex Net的工作。

 

深度学习在图像领域应用技术主要是卷积神经网络CNN(Convolutional Neural Network)。之所以CNN在计算机视觉应用的非常成功,传统机器学习方法基本被弃之不用。其中 大的一个原因就是,图像数据的特征设计,即特征描述,一直是计算机视觉头痛的问题,在深度学习突破之前10多年, 成功的图像特征设计(hand crafted feature)是SIFT,还有着名的BOW(bag ofvisual words),这些都是花了很长时间,需要非常专业的领域知识才设计出来的,这些高成本的模型迭代,使得的过去视觉算法的发展非常缓慢。可以参考如下的流程图,上面是传统的机器学习流程:

 

 

关于深度学习的热门的应用领域可以参考下图(2018年根据paperswithcode的统计结果)

 

 

现在深度学习应该比较成功的领域是计算机视觉、语音识别和自研语言处理,随着AlphaGo和OpenAI的成功,增强学习也慢慢在兴起。

 

Basic Tasks

 

基本任务

 

计算机视觉领域包含很多任务,但是基本的任务是图像分类、图像检测/定位,图像关键点定位,图像分割,这些任务已经发展多年,而且因为其基础的地位,会深刻影响其他领域(比如人脸识别、OCR)的发展,下面分别简单的介绍下各个任务的新进展情况。

 

图像分类进展

 

 

 

图像分类是指给定一张输入图像,判断该图像所属类别,通俗点说就是让机器理解这个图像是什幺或者说有什幺(猫、狗等)。图像分类是计算机视觉中基础的一个任务,也是几乎所有的基准模型进行比较的任务。从 开始比较简单的10分类的灰度图像手写数字识别任务mnist,到后来更大一点的10 分类的cifar10和100分类的cifar100 任务,到后来的imagenet 任务,图像分类模型伴随着数据集的增长,一步一步提升到了今天的水平。现在,在 imagenet 这样的超过1000万图像,超过2万类的数据集中,计算机的图像分类水准已经超过了人类。

 

根据图片内容的不同,可以分为物体分类、场景分类和行为事件分类。

 

根据分类的精细程度,可以分为粗粒度分类和细粒度分类。

 

根据分类标签的相关性,可以分为单标签分类和多标签分类。

 

图像分类问题的困难和挑战:刚体&非刚体的变化、多视角、尺度、遮挡、光照条件、类内差异,参考下图:

 

 

> > > >

 

单标签分类

 

单标签分类是 简单的分类任务,图片的内容相对简单,只包含一个物体或者场景。ImageNet就属于单标签分类的数据集。下面通过ImageNet比赛的时间脉络,介绍下单标签分类的进展情况。

 

AlexNet: 2012年提出的AlexNet网络结构模型引爆了神经网络的应用热潮,并赢得了2012届图像识别大赛的冠军,使得CNN成为在图像分类上的核心算法模型。

 

ZFNet: 2013年ILSVRC分类任务冠军网络是Clarifai,不过更为我们熟知的是ZFNet。Hinton的学生Zeiler和Fergus在研究中利用反卷积技术引入了神经网络的可视化,对网络的中间特征层进行了可视化,为研究人员检验不同特征激活及其与输入空间的关系成为了可能。在这个指导下对AlexNet网络进行了简单改进,包括使用了更小的卷积核和步长,将11×11的卷积核变成7×7的卷积核,将stride从4变成了2,性能超过了原始的AlexNet网络。

 

VGGNet: 2014年的亚军,VGGNet包括16层和19层两个版本,共包含参数约为550M。全部使用3×3的卷积核和2×2的 大池化核,简化了卷积神经网络的结构。VGGNet很好的展示了如何在先前网络架构的基础上通过简单地增加网络层数和深度就可以提高网络的性能。虽然简单,但是却异常的有效,在今天,VGGNet仍然被很多的任务选为基准模型。

 

GoogLeNet: 来自于Google的Christian Szegedy等人提出的22层的网络,其top-5分类错误率只有6.7%。GoogleNet的核心是Inception Module,它采用并行的方式。一个经典的inception结构,包括有四个成分。1×1,3×3卷积,5×5卷积,3×3大池化,后对四个成分运算结果进行通道上组合。这就是Inception Module的核心思想。通过多个卷积核提取图像不同尺度的信息然后进行融合,可以得到图像更好的表征。自此,深度学习模型的分类准确率已经达到了人类的水平(5%~10%)。

 

ResNet: 2015年获得了分类任务冠军。它以3.57%的错误率表现超过了人类的识别水平,并以152层的网络架构创造了新的模型记录。由于ResNet 采用了跨层连接的方式,它成功的缓解了深层神经网络中的梯度消散问题,为上千层的网络训练提供了可能。

 

ResNeX t : 2016年依旧诞生了许多经典的模型,包括赢得分类比赛第二名的ResNeXt,101层的ResNeXt可以达到ResNet152的精确度,却在复杂度上只有后者的一半,核心思想为分组卷积。即首先将输入通道进行分组,经过若干并行分支的非线性变换,后合并。

 

DenseNet: 在ResNet基础上,密集连接的DenseNet在前馈过程中将每一层与其他的层都连接起来。对于每一层网络来说,前面所有网络的特征图都被作为输入,同时其特征图也都被后面的网络层作为输入所利用。DenseNet中的密集连接还可以缓解梯度消失的问题,同时相比ResNet,可以更强化特征传播和特征的复用,并减少了参数的数目。DenseNet相较于ResNet所需的内存和计算资源更少,并达到更好的性能。

 

SeNet: 2017年也是ILSVRC图像分类比赛的 后一年,SeNet获得了冠军。这个结构,仅仅使用了“特征重标定”的策略来对特征进行处理,通过学习获取每个特征通道的重要程度,根据重要性去降低或者提升相应的特征通道的权重。

 

至此,图像分类的比赛基本落幕,也接近算法的极限。但是,在实际的应用中,却面临着比比赛中更加复杂和现实的问题,需要大家不断积累经验。

 

目前,随着NASNet(Neural Architecture Search Network)的崛起,效果好的基本都是这些网络比如:NASNet、PNasNet、AmoebaNet,尤其是近Google新出的EfficientNet,更是对其他网络有碾压式的提升,下面的图片一目了然:

 

 

> > > >

 

细粒度图像分类

 

细粒度图像分类 (Fine-Grained Image Categorization),是对属于同一基础类别的图像(汽车、狗、花、鸟等)进行更加细致的子类划分(比如:区分狗的种类萨摩还是哈士奇)。细粒度分类有很多实际的应用场景,比如区分在交通监控中,识别不同的车型。

 

由于分类的粒度很小,子类之间差异细微,只在某个局部上有细微差异(如狗的眼睛),甚至在某些类别上甚至专家都难以区分,再加上子类内部差异巨大,如姿态、背景带来的差异,还有受视角、背景、遮挡的干扰等,所以细粒度图像分类比粗粒度分类要困难,也因此还是目前比较热门的研究领域。

 

由于深度卷积网络能够学习到非常鲁棒的图像特征表示,对图像进行细粒度分类的方法,大多都是以深度卷积网络为基础的,这些方法大致可以分为以下四个方向:

 

1、基于常规图像分类网络的微调方法

 

这一类方法大多直接采用常见的深度卷积网络来直接进行图像细粒度分类,比如ResNet、DenseNet、SENet等。由于这些分类网络具有较强的特征表示能力,因此在常规图像分类中能取得较好的效果。然而在细粒度分类中,不同物种之间的差异其实十分细微,因此,直接将常规的图像分类网络用于对细粒度图像的分类,效果并不理想。受迁移学习理论启发,一种方法是将大规模数据上训练好的网络迁移到细粒度分类识别任务中来。常用的解决方法是采用在ImageNet上预训练过的网络权值作为初始权值,然后再通过在细粒度分类数据集上对网络的权值进行微调(FineTune),得到 终的分类网络。

 

2、基于基于网络集成的方法

 

比较有代表性的是双线性卷积神经网络模型(Bilinear CNN),该方法使用VGG-D和VGG-M两个网络作为基准网络,通过Bilinear Pooling得到两个特征融合后的向量,进而用来分类。在不使用Bounding Box (边框)标注信息的情况下,在CUB200-2011数据集上到达了84.1%的分类精度,而使用

 

BoundingBox时,其分类精度高达85.1%。

 

3、基于目标块的检测(part detection)和对齐(alignment)的方法

 

基 于目标块(object part)检测的方法思路是: 先在图像中检测出目标所在的位置,然后再检测出目标中有区分性区域的位置,然后将目标图像(即前景)以及具有区分性的目标区域块同时送入深度卷积网络进行分类。 但是,基于目标块检测的方法,往往在训练过程中需要用到目标的Bounding box标注信息,甚至是目标图像中的关键特征点信息,而在实际应用中,要想获取到这些标注信息是非常困难的。 比较有代表性的是2014年ECCV中提出来的Part-RCNN方法。

 

4、基于视觉注意机制(visual attention)的方法

 

视觉注意机制(Vision Attention Mechanism)是人类视觉所特有的信号处理机制。 具体表现为视觉系统在看东西的时候,先通过快速扫描全局图像获得需要关注的目标区域,而后抑制其他无用信息以获取感兴趣的目标。 在深度卷积网络中,同样能够利用注意模型来寻找图像中的感兴趣区域或区分性区域,并且对于不同的任务,卷积网络关注的感兴趣区域是不同的。 由于基于视觉注意模型(Vision Attention Model)的方法可以在不需要额外标注信息(比如目标位置标注框和重要部件的位置标注信息)的情况下,定位出图像中有区分性的区域,近年来被广泛应用于图像的细粒度分类领域。 代表性的工作是17年CVPR中提出的循环注意卷积神经网络(Recurrent Attention Convolutional Neural Network, RA-CNN)。

 

目前所有细粒度图像识别任务均需借助大量、甚至海量的标注数据。对于细粒度图像而言,其图像收集和标注成本巨大。如此便限制了细粒度研究相关的发展及其在现实场景下的应用。反观人类,我们则具备在极少监督信息的条件下学习新概念的能力,例如,对于一个普通成年人可仅借助几张图像便学会识别鸟类的一个新物种。为了使细粒度级别图像识别模型也能像人类一样拥有少量训练样本下的学习能力,研究人员也在研究细粒度级别图像识别的少量样本学习任务,这可能也是将来的发展趋势。

 

> > > >

 

多标签分类

 

前面所说的分类,全部都是单标签分类问题,即每一个图只对应一个类别,而很多的任务,其实是多标签分类问题,一张图可以对应多个标签,相比于多类别图像分类,多标签任务的难度更大,因为其输出空间随着类别数目呈指数增大。多标签分类问题通常有如下的策略:一阶策略:朴素的方法,忽略和其它标签的相关性,分离地看待各个目标,比如把多标签分解成多个独立的二分类问题(简单高效)。

 

二阶策略:考虑标签之间的成对关联,比如为相关标签和不相关标签排序。

 

高阶策略:考虑多个标签之间的关联,比如对每个标签考虑所有其它标签的影响(效果优)。

 

稍微展开讲讲高阶策略:由于现实世界中很多物体通常会同时出现,因此对标签之间的相关性进行建模就成了多标签图像识别的关键,如下图所示:

 

 

大体上有两个方向,可以对多个角度探索标签之间相关性进行建模。 一个是基于概率图模型或循环神经网络(RNN),显式地对标签依赖性进行建模。 另一个是通过注意力机制来对标签相关性进行隐式建模。 该方法考虑的是图像中被注意区域之间的关系(可视为局部相关性)。 不过即便如此,该方法还是忽略了图像中标签之间的全局相关性(全局相关性需要通过单张图像之外的知识才能推断出来)。

 

例如:ML-GCN使用图(Graph)来对标签之间的相互依赖关系进行建模。能够灵活地获取标签空间中的拓扑结构,在MS-COCO和VOC2007测试集上都取得了 有的结果。

 

目标检测进展

 

 

目标检测任务的目标是给定一张图像或是一个视频帧,让计算机找出其中所有目标的位置,并给出每个目标的具体类别,它结合了目标分类和定位两个任务,通俗的说就是要机器告诉图片中有什幺同时告诉在哪里。 检测是很多计算机视觉应用的基础,比如实例分割、人体关键点提取、人脸识别等。 现代大多数目标检测器的框架是Two-Stage,其中目标检测被定义为一个多任务学习问题:

 

(1)区分前景物体框与背景并为它们分配适当的类别标签;

 

(2)回归一组系数使得大化检测框和目标框之间的交并比(IoU)或其它指标。后,通过一个 NMS 过程移除冗余的边界框(对同一目标的重复检测)。

 

> > > >

 

Anchor-Based方法

 

传统Anchor-Based方法,都是用策略提出一些候选框(prior box or anchor box),然后对这些候选框做分类和位置的归回。方法是对这些框所对应的 featuremap向量作分类(softmax)或者回归(线性回归),得到box的位置和类别。

 

OneStage算法是直接在网络中提取特征来预测物体分类和位置,Two Stage算法是指首先生成proposal,然后进行细粒度的物体检测。

 

现代大多数目标检测器的框架是两步进行:

 

(1)RPN:区分前景物体框与背景并为它们分配适当的类别标签;

 

(2)回归一组系数使得大化检测框和目标框之间的交并比(IoU)或其它指标 后,通过一个 NMS 过程移除冗余的边界框(对同一目标的重复检测)。

 

目标检测的重要技术路线图如下图描述的很清晰:

 

 

图中的里程碑检测器: VJ Det, HOG Det,DPM, RCNN, SPPNet, Fast RCNN, Faster RCNN, YOLO, SSD, PyramidNetworks, RetinaNet。

 

如下是各个检测模型在VOC07、VOC12和MS-COCO数据集上的检测结果图:

 

 

篇幅所限,以后有机会再对每个具体的检测器做具体的展开讲解。

 

> > > >

 

Anchor-Free方法

 

自从去年8月CornerNet开始,Anchor-Free的目标检测模型层出不穷,近开始热门起来。所谓Anchor-Free是指检测时不用现预设一些参考的Anchor-

 

Box,而是直接通过模型预测目标的位置和类别,比如通过关键点的方式。

 

其实 Anchor-Free并不是一个新概念了, 早可以追溯的百度的DenseBox模型(此模型2015年提出,比Fast-RCNN还要早),大火的YOLO也算是目标检测领域的Anchor-Free模型,而 近的Anchor-Free模型如FASF、FCOS、FoveaBox都能看到DenseBox的影子。比较有代表性的Anchor-Free模型有:DenseBox、YOLO、CornerNet、ExtremeNet、FSAF、FCOS、FoveaBox。

 

虽然目前Anchor-Free的方法还没有完全胜过传统的Anchor-Based方法,但是确实提供一种可行新的检测流程,主要的是对于BoundingBox是否是检测的 合理的表达,提出了挑战,后面随着Anchor-Free模型的演进,可能会产生出搞好的目标表达方式。

 

图像分割进展

 

 

图像分割就是把图像分成若干个特定的、具有独特性质的区域并提出感兴趣目标的技术和过程, 可以被看作是一个逐像素的图像分类问题。 分割任务主要分为语义分割(semantic segmentation)、实例分割(instancesegmentation)以及今年刚兴起的新领域全景分割(panoptic segmentation),上图展示了不同分割的区别。

 

稍微展开说明一下不同分割任务:

 

语义分割: 语义分割更注重「类别之间的区分」,语义分割会重点将前景里的人群和背景里树木、天空和草地分割开,但是它不区分人群的单独个体,如图中的人全部标记为红色,导致右边黄色框中的人无法辨别是一个人还是不同的人。主要模型有U-Net、SegNet、DeepLab系列、FCN、ENet、ICNet、ShelfNet、BiseNet、DFN和CCNet等网络。

 

实例分割: 更注重「个体之间的区分」,实例分割这个问题近几年的发展在很大程度上是由 COCO 数据集和比赛推动的。从 MNC,FCIS 到PANet,都是在 COCO instance segmentation track 上拿第一名的方法。主要模型有FCIS、DeepMask、MaskR-CNN 、Hybrid Task Cascade(HTC)、PANet 等网络。

 

全景分割: 新的子任务, 先由FAIR与德国海德堡大学联合提出,可以说是语义分割和实例分割的结合,全景分割任务下,图像内的每个像素点都有其对应的语义标签和实例标签,从而能够大程度上地理解整幅图像。主要模型有JSIS-Net、TASCNet等。

 

> > > >

 

图像分割模型

 

图像分割大体框架或者说流程如下:

 

下采样+上采样:Convlution + Deconvlution/Resize。

 

多尺度特征融合:特征逐点相加/特征channel维度拼接。

 

获得像素级别的segement map:对每一个像素点进行判断类别。

 

下图展示了图像分割进展的技术图谱:

 

 

1、FullyConvolutional Networks (FCN): 这是神经网络做语义分割的开山之作,提出了全卷积网络。 将全连接网络替换成了卷积网络,使得网络可以接受任意大小的图片,并输出和原图一样大小的分割图。 只有这样,才能为每个像素做分类。 使用了反卷积层(Deconvolution),特征图进行上采样。

 

2、SegNet在FCN的基础上增加了解码器,形成目前分割任务中 流行的编解码结构,并给出了不同解码器对效果的影响和原因。

 

3、DeepLabv1/v2/v3: 引入了带洞卷积(Dilated Convolution or Atrous Convolution),使得视野更大了。

 

4、 PSPNet: 核心贡献是全局金字塔池化(Global Pyramid Pooling),将特征图缩放到几个不同的尺寸,使得特征具有更好地全局和多尺度信息。

 

5、MaskR-CNN:将Object Detection与SemanticSegmentation合在了一起做,提出了RoiAlign用来替换RoiPooling,消除了取整导致的偏移问题,提高了检测精度。

 

6、U-Net: 采用了编解码结构,编码部分,每经过一个池化层就构造一个新的尺度,包括原图尺度一共有5个尺度。 解码部分,每上采样一次,就和特征提取部分对应的通道数相同尺度融合。 这样就获得了更丰富的上下文信息,在Decode的过程中通过多尺度的融合丰富了细节信息,提高分割的精度。

 

> > > >

 

抠图(Image Matting)

 

Matting也是一类前背景分割问题,但是matting不是硬分割,而是软分割(Soft Segmentation),像玻璃、头发这类前景,对应像素点的颜色不只是由前景本身的颜色决定,而是前背景颜色融合的结果,matting问题的目标就是,找出前背景颜色,以及它们之间的融合程度。

 

抠图(ImageMatting)只将图片分成前景和背景两块,目的是拿到前景,好的抠图算法会对于头发等细节的处理效果比较精确。抠图和分割的重要区别是分割是返回像素分类结果,分类结果是整型;而抠图返回的是属于前景或背景的概率p,在前景与背景交互区域会产生渐变的效果,使得抠图更加自然。

 

抠图技术的核心问题是解公式:I = αF + (1-α)B,其中I是图像当前可观察的像素,为已知量;α是透明度,F是前景像素,B是背景像素,这三个变量为未知量。对于这个公式的理解,可以把原始图像看做是前景和背景按照一定权重(α透明度)叠加组成的。对于完全确定是前景的像素,α = 1;对于完全确定是背景的像素,α = 0;对于不确定是前景还是背景的像素,α是介于0到1之间的浮点数。

 

优秀的抠图算法是有能力将前景中非常细小的毛发细节都能提取出的好算法,这点是传统图像分割技术做不到的。

 

现在深度学习也慢慢引入了Image Matting,基本上用的方法也是Encoder-Decoder框架,只是训练数据的GroundTruth变成了trimap。比较有代表性的是adobe搞的end to end的方案DeepImage Matting。

 

由于应用场景没有其他分割广泛,再加上数据集和benchmark的欠缺,导致Matting技术没有其他的分割技术热度高。

 

Following-up

 

后续

 

当然计算机视觉不止这些任务,、检测和分割只是计算机视觉的最基础的任务,而这些任务因为其基础性和通用性,在其他任务中都会用的到。比如人脸领域,也会用到检测和分类,在做特效的时候也会用到分割。而文中介绍的基础的网络结构,比如ResNet、GoogleNet等,在其他任务中也会用到。

 

深度视觉领域,除了这些还有很多没有涉及到,比如关键点检测、视频分类、视频检测和追踪、生成对抗网络(GAN)、自动学习(AutoML),垂直领域的人脸识别、光学字符识别(OCR)、行人再识别,包括常用的深度学习框架tensorflow、pytorch等,还有一直在研究的无/弱监督学习、自监督学习,增强学习等,每个子领域展开讲都需要很大的篇幅,后面会再介绍这些方向的进展。

 

参考资料:
1、https://blog.csdn.net/xys430381_1/article/details/89640699
2、https://medium.com/atlas-ml/state-of-deep-learning-h2-2018-review-cc3e490f1679
3、https://zhuanlan.zhihu.com/p/57643009
4、https://zhuanlan.zhihu.com/p/62212910
5、https://cloud.tencent.com/developer/article/1428956

Be First to Comment

发表评论

邮箱地址不会被公开。 必填项已用*标注