• 华为云校园分享会学生免费体验微认证使用指引
    各位同学们好!为感谢各位同学对华为云校园分享会的支持,华为云学院为报名的各位同学赠送了《基于卷积神经网络实现景区精准识别场景》华为云微认证的免费体验机会,包含一站式在线学习、实验、考试、认证,为了方便大家学习,给大家提供了以下学习指引(详见附件),请查收哈!如在学习过程中有任何问题,都可以随时咨询华为云学院小助手(QQ:2353698645/微信:HWcloudedu)活动已于5月初截止一、华为云微认证是什么?华为云微认证提供在线MOOC视频学习+场景化在线实验+自主在线考试+官方认证证书领取一站式学习和认证方式,快速获得场景化的技能提升。目前已上线微认证分为云计算、大数据、人工智能、软件开发、云安全共14门。用户可根据个人需求自由选择。通过考试可以获得华为云官方的权威微认证证书,通过华为云微认证,可获得华为云面试优先推荐机会。       二、微认证流程指南            详细操作指引请下载附件查看,小助手精心准备的,有问题可以联系小助手哦!      三、相关学习网页       各位同学们可直接通过下方链接进行学习:      1. 《基于卷积神经网络实现景区精准识别场景》微认证      2. 华为云微认证      3. 华为云学院       同学们赶紧努力学习,考取属于你的华为云微认证证书吧!
  • [技术干货] 【ModelArts-Lab AI实战营】基于Vgg16的猫狗识别扩展案例(卷积神经网络)
    作者:yiakwy内容本案例包含了部署在ModelArts上所必须的项目文件,代码入口,以及部署工具。本案例提供了一个针对猫狗识别可达到95%以上精度的案例模型Vgg16,并且易于扩展其他模型到训练作业上准备工作将获得的cat_and_dog_XX.tar.gz 文件放到本目录下的data。我已经在data里面存放了,在部分数据预训练得到的预训练模型参数。在本地训练执行:cd codes && sh train.sh会自动解压数据包, 训练模型,并创建output文件夹,用于序列化的存放模型架构(proto文件)和参数。代码在ModelArts作业训练执行时,会将输出文件同步到OBS对应的作业版本号下models文件夹。此位置比较重要,线上部署时,会根据这个位置读取由keras转换的tensorflow模型开始进行部署。部署首先参考脚本,安装ModelArts SDK。修改cloud/deploy/deploy.py中对象存储,桶名称和目标路径(和训练作业输出路径下model目录一致)。cd codes && sh deploy.sh即可将本地依赖代码文件拷贝到OBS推理入口文件所在文件夹。
  • [教程] 【ModelArts-Lab AI实战营】基于ModelArts通过Keras来增广猫狗数据集(卷积神经网络)
    在【华为云 ModelArts-Lab AI实战营】第二期中的想提高猫狗识别率可以考虑增加训练数据来提高准确率。我们可以通过Keras来增广猫狗数据集。我们先把案例提供的25000张图片进行分类及分文件夹。因为,在华为云上的Notebook上增广图片的数量在500张比较好,一次增广量可达到4000,时间在3分钟左右。首先,我们先按500一份分装到50个文件夹内,再压缩成zip格式文件上传到notbook上。如图:我们再进入输入解压命令: unzip catdogdata.zip到文件目录界面可以看到解压出文件进行数据增广from keras.preprocessing.image import ImageDataGeneratorimport osimport numpy as npimport tensorflow as tfdef creat_x_database(rootdir, resize_row, resize_col):    list = os.listdir(rootdir)    database = np.arange(len(list) * resize_row * resize_col * 3).reshape(len(list), resize_row, resize_col, 3)    for i in range(0, len(list)):        path = os.path.join(rootdir, list)  # 把目录和文件名合成一个路径        if os.path.isfile(path):  ##判断路径是否为文件            image_raw_data = tf.gfile.FastGFile(path, 'rb').read()            with tf.Session() as sess:                img_data = tf.image.decode_jpeg(image_raw_data)                resized = tf.image.resize_images(img_data, [resize_row, resize_col], method=0)                database = resized.eval()    return database'''用以生成一个batch的图像数据,支持实时数据提升。训练时该函数会无限生成数据,直到达到规定的epoch次数为止。'''datagen = ImageDataGenerator(    featurewise_center=True,  # 去中心化    featurewise_std_normalization=True,  # 标准化    rotation_range=10,  # 旋转范围, 随机旋转(0-180)度    width_shift_range=0.2,  # 随机沿着水平或者垂直方向,以图像的长宽小部分百分比为变化范围进行平移;    height_shift_range=0.2,    shear_range=0.2,  # 水平或垂直投影变换    zoom_range=0.2,  # 按比例随机缩放图像尺寸    horizontal_flip=True,  # 水平翻转图像    fill_mode='nearest')  # 填充像素, 出现在旋转或平移之后x = creat_x_database('.xxx/xxx/训练文件路径', 256, 256)datagen.fit(x)i = 0for batch in datagen.flow(        x,        batch_size=300,        save_to_dir='./训练完毕的路径',        save_prefix='1',        save_format='jpg'):    i += 1    if i > 15:        break最后得到的效果:不过这里还有个数据标注还没完成,下期再补上,因为,我也没搞出来!!!难受!!!
  • [教程] 【ModelArts-Lab AI实战营】Mask R-CNN模型解析(深度学习)
    Mask R-CNN是由华人学者何凯明教授主导的一个多任务深度学习模型,能够在一个模型中完成图片中实例的分类和定位,并绘制出像素级的遮罩(Mask)来完成分割任务。Mask R-CNN是一个较为复杂的模型,使用了若干不同的网络模型,包括ResNet,FPN,RPN以及分类和回归模型。下面,我们对Mask R-CNN进行逐步的剖析。Mask R-CNN的三个主要网络Mask R-CNN包括三个主要的子网络:backbone网络RPN网络head网络整体结构如下图所示:下面,我们逐步分析这三个主要的网络。backbone网络Mask R-CNN的backbone网络,也称为骨干网,主要用于图像的特征提取。在Mask R-CNN之前,Faster R-CNN使用一个共享的卷积神经网络作为骨干网,Mask-RCNN的一个改进点在于,使用ResNet+FPN作为backbone网络,对于输入图片,生成多种尺寸的特征图,形成不同level的特征图金字塔,进一步强化了backbone网络的特征提取能力。ResNet网络我们在图像分类的任务中介绍过了VGG网络,在2014年,VGG的作者通过实验发现,增加卷积神经网络的深度可以提高模型精度,当时人们认为十几层的网络已经是非常深的网络了,VGG的作者推断,在VGG的基础上继续增加网络深度,模型的精度还可以继续提高。然而,人们通过实验发现,简单的叠加卷积层,会导致梯度弥散和梯度爆炸现象,通过合理的初始化和对中间层的正则化,使得我们可以训练深度达到几十层的网络。然而,随着深度的进一步增加,模型又出现了退化现象,即深度增加反而导致模型精度下降,这说明,深层神经网络不能通过简单的 增加深度进行优化。当时还在微软研究院的何凯明教授和他的同事们通过对深层网络的研究,提出了ResNet模型。既然简单粗暴的叠加神经层会导致精度下降,那么,通过加入一个残差模块,通过模型的训练,在适当的情况下让深度网络退化成一个浅层的网络,这样就能避免过深的网络带来的退化问题。通过在正常的深层网络中加入一个恒等映射,就可以实现残差模块,如图下所示:ResNet提出后,网络训练的深度从VGG时代的十几层,一举跃升至ResNet Xt的152层,ResNet也在VGG之后的2015年夺得ILSVRC图像识别的冠军,top5的错误率降低到5.37%,首次在ILSVRC竞赛中超过了人眼的识别精度5.1%。FPNMask R-CNN的backbone网络还包括了FPN(Feature Pyramid Network,图像特征金字塔)。FPN是Facebook的AI实验室FAIR在2017年提出的。2017年,何凯明教授已经从微软离开,加入FAIR,也参与了FPN的研究和论文发表,从ResNet到FPN再到Mask R-CNN,都有何教授的参与或主导,不得不令人佩服。直观的理解,图像在卷积神经网路的处理过程中,其尺寸逐步减小,而深度逐步增加,随着深度的增加,图像的细节特征逐步退化,而呈现出更抽象的语义特征。常规的卷积神经网络往往采用最后一个卷积的结果对图像进行分类,对于图片中一些较小的物体,则无法达到较好的效果。FPN的思想是,保留卷积过程中不同阶段的输出结果,同时进行训练,这样,既能在较为抽象的特征中识别较大物体,也能够在细节较多的特征中对小物体进行有效的识别,对不同层次的语义特征都能够进行有效的利用。ResNet在卷积处理的过程中,定义了不同的stage,每个stage输出不同尺寸的特征图,而这种结构恰好可以用来生成FPN,与FPN结合的天衣无缝,这两种模型的组合如下图所示:通过ResNet与FPN,我们得到了P2到P6这5中规格的特征图,用作后续两个模型的输入,下面是经过backbone处理的P2到P6的一个示例结果:RPN网络RPN网络主要用于生成Proposal,即带有前景、背景、包围框信息的区域。通过backbone网络,我们已经生成了不同尺寸的特征图。在RPN中,我们先对特征图上的每个像素都生成3个Anchor(像素区域的锚框),Anchor的长宽比为1:2, 1:1, 2:-1,即[0.5, 1, 2]。假设输入图片我们统一处理成1024x1024,则P2到P6特征图的边长分别为[256, 128, 64, 32, 16],特征图单个像素对应原图区域的边长则分别为[4, 8, 16, 32, 64],以P2为例,我们对每个像素生成的3个anchor尺寸为:比例长宽0.54 / (2^0.5)4 * (2^0.5)14424 * (2^0.5)4 / (2^0.5)需要注意的是,为了保证anchor面积不变,长宽的大小在变化时,要乘以或者除以根号2(表中用2^0.5表示)。对于P2,我们要生成anchor数量为256x256x3,P3的数量为128x128x3,以此类推。生成的全部anchor数量为3x(256^2+128^2+64^2+32^2+16^2)=261888。Anchor的训练Anchor生成之后,我们需要对Anchor进行处理,生成可以训练的数据,包括两个部分:Anchor是前景还是背景Anchor的包围框修正信息我们通过IoU(Intersection over Union)来判断一个Anchor是前景还是背景。我们对比一个Anchor和Ground Truth的包围框,计算两个框的交集与并集的商,即两个框重合的比例有多大,IoU如下图的示意:显然IoU的范围为[0, 1],当Anchor与Ground Truth box完全不相交时,IoU为0,当两者完全重合时,IoU为1,IoU越大,表示Anchor框住的物体面积越大。我们把IoU大于0.7的Anchor标记为前景(正样本),小于0.3的Anchor标记为背景(负样本),而IoU在0.3和0.7之间的Anchor认为是不明确的Anchor,我们在训练时丢弃不用。通过IoU我们标记出Anchor的正负样本,针对正样本,我们需要对其进行包围框的回归。假设Ground Truth box的中心点和宽高分别为x, y, w, h,Anchor的中心点和宽高分别为x', y', w', h',然后,我们计算下面4个量:dx = (x-x') / w'dy = (y-y') / h'dw = log((w-w') / w')dh = log((h-h') / h')然后对这4个量进行回归训练,得到Anchor的修正信息。在训练阶段,我们将输入的特征图进行一个3x3的卷积,得到F,对F进行一个(1x1,6)的卷积(代表卷积核大小为1x1,深度为6,即Anchor数量3乘以二分类数量2),再输入到一个softmax层得到二分类;对于包围框回归,则是对F进行一个(1x1, 12)的卷积,12即Anchor数量3乘以修正信息的个数4,再将卷积结果输入到一个线性回归层。这个过程如下图所示:其中分类问题使用交叉熵损失函数训练,回归问题使用SmoothL1损失函数进行训练。这样,通过对Anchor的训练,我们就得到了初步的Anchor分类和回归模型。RoIRoI,即Region of Interest,字面的意思就是"感兴趣区域",也就是我们认为有可能是框住物体的区域(我们对这样的区域是感兴趣的)。Anchor经过前面的训练,得到了前景背景分数,我们使用softmax做分类,因此,前景背景分数即anchor为前景或背景的概率。我们筛选出前景分数较高的Anchor,然后通过修正信息得到修正后的包围框,再对修正的包围框进行NMS(Non-Max Supression,非极大值抑制)处理,去掉重复的修正狂,最终得到与Ground Truth box最匹配的若干个修正框,即RoI。得到RoI后,我们生成head网络所需的数据。首先计算RoI与Ground Truth box的IoU并设置阈值0.5,IoU大于0.5的样本标记为正样本,小于0.5的标记为负样本,对于正样本,我们要给出head网络训练所需的三个值:正样本RoI所框住物体的分类id正样本RoI与Ground Truth box的偏移量(RoI是Anchor训练得到的,与Ground Truth box还会存在偏移差)正样本RoI的Mask信息RoI可能与多个Ground Truth的IoU大于0.5,我们取IoU最大的Ground Truth,将其分类id和Mask信息赋给RoI;RoI边框修正信息的计算方式与Anchor一致。这样,RoI的正样本中,就包含了某个具体物体的分类、Mask信息和边框修正信息,我们将带有这些信息的RoI称为Proposal,将其输入到RoI Align层后,再进入head网络进行进一步的训练。RoI AlignRoI Align是Mask R-CNN针对Faster R-CNN的一个重要改进。在Faster R-CNN模型中,需要将Proposal和特征图池化为固定的尺寸,以便于后续head网络的训练。Faster R-CNN中的backbone网络使用的是VGG16,生成的特征图stride为32,即尺寸为原图的1/32,因此原图的包围框向特征图映射时,除以32,会出现浮点数,Faster R-CNN中对浮点数直接进行了取整的操作,这一步损失了一部分精度。在RoI Pooling层中,要对包围框进一步进行池化操作,将大小固定为7x7,缩放后又会出现浮点数,RoI Pooling层会对浮点数再进行一次取整操作,因此又损失一部分精度。以下图为例,原图大小为800x800,物体大小为665x665,第一次映射后,边长变为655/32=20.78,取整后为20,原图映射为20x20的特征图。第二次映射后后,20x20的特征图被固定为7x7尺寸,20/7=2.86,则源特征图中的2个像素映射为1个像素,将7x7的特征图进行上采样映射会源特征图,发现对应的面积仅为14x14,误差非常大。这会导致head网络中的回归产生较大的偏差。Mask R-CNN的RoI Align层做法有所不同。作为对比,我们假设仍然使用VGG作为backbone网络,则原图向特征图映射时,655x655的物体特征图尺寸为20.78x20.78,这一步并不进行取整操作,而是保留浮点数。经过RoI Align池化为7x7的区域时,首先将20.78x20.78的区域分为7x7网格,则每个网格单元大小为20.78/7=2.97,也即池化后单位像素在特征图中对应的长度。接下来设置一个采样点的数量,一般为4,即把特征图中2.97x2.97的区域平均划分为2x2,共4个更小的区域,每个区域按照双线性差值算法计算中心点的像素值作为该区域的值,将得到的2x2采样区域的4个采样点的值计算出来,再进行一次池化,这样,最终也能生成7x7的区域,但是并没有丢失精度。RoI Align采样点的计算过程如下图所示:除了精度操作,由于Mask R-CNN使用ResNet+FPN作为backbone网络,输出的特征图尺寸有所不同,在原图向特征图进行映射时,需要先计算出特征图在FPN中的level,按照公式level=[k0 + log2(sqrt(w*h) / 244)],其中k0是w,h=244,244时对应的level,一般取4,得到FPN的level后,得到特征图对于原图的缩放比例,就可以进行映射了。由于Mask R-CNN中在head网络增加了mask分之,因此RoI Align除了将包围框固定为7x7,还会将mask则固定为14x14,计算的方式与上述过程是一致的。Head网络经过RoI Align的池化操作,就得到了head网络的训练数据。即:7x7的包围框,14x14的mask信息以及分类信息。分类与回归分支head的输入数据首先经过两层卷积网络,然后输入到两个全连接层,在分别输入到softmax和线性回归激活层。其中softmax层使用交叉熵损失函数训练,线性回归使用SmoothL1损失函数训练。这与RPN中Anchor的训练是一致的。Mask分支RoI Align池化固定的14x14 mask信息经过几层conv, BatchNorm, ReLU后,再进行2x2的反卷积操作,得到28x28的图像区域。然后经过大小1x1、深度为分类个数的卷积操作,输出每一个分类的28x28 mask信息,再经过一个sigmoid激活函数,这样28x28的像素区域,每个区域的值为0或1,代表是否为物体的遮罩。mask分支采用二元交叉熵损失函数进行训练,来预测每个像素位置为0还是1。至此,我们浏览了整个Mask R-CNN模型的结构,Mask R-CNN模型的损失函数一共有5个:Anchor二分类,交叉熵损失函数Anchor包围框回归,SmoothL1损失函数head网络的分类,交叉熵损失函数head网络的回归分支,SmoothL1损失函数head网络的mask分支,二元交叉熵损失函数
  • [教程] 【ModelArts-Lab AI实战营】ResNet模型解析(卷积神经网络)
    从2012年开始,卷积神经网络(Convolutional Neural Networks, CNN)极速发展,不断涌现出诸如AlexNet、VGGNet等优秀的神经网络。到了2015年,一个新型的网络更是颠覆了计算机视觉领域和深度学习领域,这就是ResNet。ResNet(Residual Neural Network)由微软研究院的何凯明等四名华人提出,其论文《Deep Residual Learning for Image Recognition》一举摘得CVPR2016最佳论文,下图就是它在 ILSVRC 和 COCO 2015 上的战绩。残差学习人们在探索深度学习网络的过程中,发现了“网络越深,效果越好”这一规律,从Alexnet的7层发展到了VGG的16乃至19层。然而在继续加深网络的时候遇到了问题:网络越深,模型训练难度越大,收敛速度变得很慢;当网络深度达到一定深度的时候,模型的效果很难再提升;甚至在继续增加深度时出现错误率提高的情况。出现这样类似“退化”的问题,主要是由于网络深度的增加,带来的在网络训练的时候,梯度无法有效的传递到浅层网络,导致出现梯度弥散(vanishing)。何凯明等人提出的残差结构就很好地解决了这个问题。残差的基本结构如下图所示:这有点类似与电路中的“短路”,所以是一种短路连接(shortcut connection),该残差块也被称为shortcut。它的原理是:对于一个堆积层结构(几层堆积而成)当输入为 x 时,其学习到的特征记为 H(x) ,现在我们希望其可以学习到残差 F(x)=H(x)-x ,这样其实原始的学习特征是 F(x)+x 。之所以这样是因为残差学习相比原始特征直接学习更容易。当残差为 0 时,此时堆积层仅仅做了恒等映射,至少网络性能不会下降,实际上残差不会为 0,这也会使得堆积层在输入特征基础上学习到新的特征,从而拥有更好的性能。总的来看,该层的神经网络可以不用学习整个的输出,而是学习上一个网络输出的残差,因此ResNet又叫做残差网络。ResNet网络结构作者为了表明残差网络的有效性,使用如下三种网络进行对比。其一为 VGG-19 网络(这是 VGG paper 中最深的亦是最有效的一种网络结构),另外则是顺着VGG网络思路继续简单地加深层次而形成的一种 VGG 朴素网络,它共有34个含参层。最后则是与上述34层朴素网络相对应的 Resnet 网络,由前面介绍的残差单元来构成。在论文中可以看到详细的实验对比结果,ResNet 的结构可以极快的加速神经网络的训练,收敛性能好;模型的准确率有比较大的提升,分类性能好。在 ResNet 中的网络结构单元被称为模块——block,其中会用到两种残差模块:一种是以两个 3x3 的卷积网络串接在一起作为一个残差模块,用于34-layer;另外一种,考虑到实际计算的时间和效率问题,作者提出了命名为 bottleneck 的结构块来代替常规的 Resedual block,将 1x1 、3x3、1x1 的3个卷积网络串接在一起作为一个残差模块,常用于层数更多的网络中。如下图所示。除上面展示的34-layer的ResNet,还可以构建更深的网络,如下表所示。上面一共提出了5种深度的ResNet,分别是18,34,50,101和152。比较常用的是50-layer,101-layer,152-layer。他们都是由上述的残差模块堆叠在一起实现的。在此以ResNet50为例,拆解其结构,使读者有更直观的了解。在Keras中,ResNet50的网络的整体结构示例为:data  1,3,224,224conv  filter=64, kernel_size=7, pad=3,stride=2 1,64,112,112bnactivation('relu')maxpool kernel_size=3,stride=2  1,64,56,56# block 1  (64,64,256)conv_block() in:1,64,56,56 filter=(64,64,256),out=1,256,56,56identity_block  in=1,256,56,56, filter=(64,64,256),out=1,256,56,56identity_block  in=1,256,56,56, filter=(64,64,256),out=1,256,56,56# block 2  (128,128,512)conv_block  in=1,256,56,56 filter=(128,128,512),out=1,512,28,28identity_block  in=1,256,56,56 filter=(128,128,512),out=1,512,28,28identity_block  in=1,256,56,56 filter=(128,128,512),out=1,512,28,28identity_block  in=1,256,56,56 filter=(128,128,512),out=1,512,28,28# block 3 (256,256,1024)conv_block  in=1,512,28,28 filter=(256,256,1024),out=1,1024,14,14identity_block  in=1,512,28,28 filter=(256,256,1024),out=1,1024,14,14identity_block  in=1,512,28,28 filter=(256,256,1024),out=1,1024,14,14identity_block  in=1,512,28,28 filter=(256,256,1024),out=1,1024,14,14identity_block  in=1,512,28,28 filter=(256,256,1024),out=1,1024,14,14identity_block  in=1,512,28,28 filter=(256,256,1024),out=1,1024,14,14# block 4 (512,512,2048)conv_block  in=1,1024,14,14 filter=(512,512,2048),out=1,2048,7,7identity_block  in=1,1024,14,14 filter=(512,512,2048),out=1,2048,7,7identity_block  in=1,1024,14,14 filter=(512,512,2048),out=1,2048,7,7maxpool kernel_size=7, stride=1 out=1,2048,1,1flattendence(1,1000)acivation('softmax')probbility(1,1000)在Keras代码中定义该网络模型,如下:def resnet_model(out_class, input_shape):    inputs = Input(shape=input_shape) #1,3,224,224    #    x = Conv2D(64, (7, 7), strides=2, padding='same')(inputs) #conv1  1,64,112,112    x = BatchNormalization(axis=-1)(x) #bn_conv1    x = Activation('relu')(x) #conv1_relu    x = MaxPool2D(pool_size=(3,3),strides=2)(x) # 1,64,56,56    # block1  (64,64,256) 1,2 in:1,64,56,56    x = conv_block(x, [64, 64, 256]) #out=1,256,56,56    x = identity_block(x, [64, 64, 256]) #out=1,256,56,56    x = identity_block(x, [64, 64, 256]) #out=1,256,56,56    # block2  (128,128,512) 1,3 in:1,256,56,56    x = conv_block(x, [128,128,512]) #out=1,512,28,28    x = identity_block(x, [128,128,512]) #out=1,512,28,28    x = identity_block(x, [128,128,512]) #out=1,512,28,28    x = identity_block(x, [128, 128, 512])  # out=1,512,28,28    # block 3 (256,256,1024) 1,5 in:1,512,28,28    x = conv_block(x, [256,256,1024])  # out=1,1024,14,14    x = identity_block(x, [256, 256, 1024])  # out=1,1024,14,14    x = identity_block(x, [256, 256, 1024])  # out=1,1024,14,14    x = identity_block(x, [256, 256, 1024])  # out=1,1024,14,14    x = identity_block(x, [256, 256, 1024])  # out=1,1024,14,14    x = identity_block(x, [256, 256, 1024])  # out=1,1024,14,14    # block 4 (512,512,2048) 1,2 in:1,1024,14,14    x = conv_block(x, [512,512,2048])  # out=1,2048,7,7    x = identity_block(x, [512, 512, 2048])  # out=1,2048,7,7    x = identity_block(x, [512, 512, 2048])  # out=1,2048,7,7    # maxpool kernel_size=7, stride=1 out=1,2048,1,1    x = MaxPool2D(pool_size=(7, 7), strides=1)(x)    # flatten    x = Flatten()(x)    # Dense    x = Dense(classes, activation='softmax')(x) # out=1,1000    model = Model(inputs=inputs, outputs=out)    return model下面是一些ResNets的其他特征:网络较深,控制了参数数量。存在明显层级,特征图个数层层递进,保证输出特征的表达能力。使用较少池化层,大量采用下采样,提高传播效率。没有使用 dropout,利用 Batch Normalization 和全局平均池化进行正则化,加快训练速度。层数较高时减少了3x3卷积核的个数,用1x1卷积核控制3x3卷积的输入输出特征 map 的数量。深度残差网络的提出是CNN图像史上的一件里程碑事件,随着对其的不断深入研究,有很多 ResNet 的变体已经出现,如:ResNeXt、DenseNet、WideResNet等,有待读者继续深入关注和了解。
  • [教程] 【ModelArts-Lab AI实战营】VGG模型解析(卷积神经网络)
    VGG是牛津大学的Karen Simonyan和Andrew Zisserman在挑战2014年的ILSVRC时提出的系列模型。基于模型研究和比赛结果,两人发表了论文《Very Deep Convolutional Networks For Large-Scale Image Recognition》。VGG的重要意义在于,其研究结果表明增加深度能够提高卷积神经网络的性能。在VGG之后,人们沿着更深层的网络这个方向,取得了一系列新的进展。本文结合原作者的论文,解析VGG模型的结构和基本原理。过程中会简单介绍卷积神经网络的一些基本要点。卷积神经网络卷积和池化是卷及神经网络(以下简称CNN)中的核心。我们使用CNN处理图像时,通过设置卷积核的尺寸和深度,以及池化层的大小,完成图像的特征提取。一般而言,计算机中的图像按照RGB颜色模式存储,本质上是一个(width, height, channels)的三维数组,其中channels为3,代表RGB三个颜色通道,每个通道是一个(width, height)的二维数组,我们通过一个n*n的参数矩阵,对二维数组进行矩阵点乘(每个元素对应相乘),然后将结果矩阵的值相加,计为输出矩阵中的一个单位值。这个过程如下图所示:卷积核还有一个参数深度,表示输出多少个新的矩阵,因此,直观的理解,通过卷积操作之后,图像的尺寸下降而深度增加,我们得到的是更为抽象的信息,例如颜色、轮廓等。卷积之后的矩阵中,相邻元素表示的是相似的信息,我们通过池化将所有信息进行合并。池化也是一个类似卷积的过程,我们通过一个矩阵对二维数组进行扫描,只是该矩阵不带参数,扫描的区域的值简单的进行取最大值或者平均值的操作,将相似信息进行提取。池化的过程如下图所示:VGG模型基本结构通过前面的描述,我们知道卷积核的大小是非常重要的,VGG模型的研究表明,较深的层+较小的卷积核,在特征提取上可以取得更好的效果。VGG是一系列模型,有不同的配置,编号从A到E,深度不断增加,如下表所示: 由于VGG最初用于ImageNet数据集的分类任务,所以输入图片统一尺寸为(224, 224)。整个网络中都用了3x3大小的卷积核,并配合1x1的卷积核进行简单的线型转变(不改变图片大小)。卷积核名字中-之后的数值表示卷积核输出的深度,随着网络深度的增加,卷积核输出深度从64逐步增加到256,而网络深度也从11层增加到19层,这其中包括了最后的3个全连接层。这就是VGG模型的基本结构,非常简单,但取得了非常好的效果,同时也非常易于扩展。VGG模型的研究向我们揭示了什么VGG模型本身非常简单,很容易理解,在VGG模型的实践中,作者通过实验和对比,发现了很多有趣的规律。例如上面提到的"较深的网络+较小的卷积核"可以取得更好的特征提取性能。下面,我们一一介绍作者的发现。"深网络+小卷积核"首先我们了解一下"感受野"的概念。简单的说,感受野就是通过卷积网络之后,输出矩阵的单位对应原矩阵区域的大小。例如,一个5x5的图像,经过3x3的卷积之后,尺寸变为3x3,新的矩阵中一个元素对应原始矩阵中的3x3区域。作者提到,2个3x3的卷基层和1个5x5的卷基层,感受野(receptive field)是一致的,都是4x 4,但是最终实验的结果却表明,前者的效果要优于后者。作者还对比了3x3卷积层和1个7x7卷积层,得到了相同的对比结果。同时,使用深网络+小卷积核还有一个好处,那就是参数较少。假设一个卷积核的深度为C,那么3个3x3卷积核需要的参数为3^2 * C^2 * 3,即27 * C^2(C^2表示C的平方),而1个7x7的卷积核的参数个数为7^2 * C^2,即49 * C^2,后者多出了81%的参数。pretrain与fine tune作者在训练模型时,基本延续了2012年ILSVRC冠军模型AlexNet的训练参数配置,包括对AlexNet的LRN进行了对比(最后发现加入LRN并不会对VGG模型有明显的提升)。最终的训练结果显示,学习率下降了3倍,而且在370K个迭代(74 epochs)就结束了训练。作者认为有2个原因:1,"深度网络+小卷积核"隐含的实现了数据的正态化;2,作者使用了预训练与微调的训练方式。前面我们提到,VGG系列模型从A到E,深度不断增加。作者在训练时,先使用随机初始化对模型A进行训练,然后将训练得到的权重来初始化模型B,模型B只比A多了两层卷积,这两层卷积依然采用随机初始化。这样,有效的降低了模型B的训练时间。不过,作者在提交比赛结果之后发现,使用论文《Understanding the difficulty of training deep feedforward neural networks》的方法,也可以直接使用随机初始化进行训练,不需要预训练参数。图像多尺寸缩放作者在训练模型时,对图像的尺寸进行了调整。ImageNet比赛中的图片尺寸都是224x224,因此,作者将输入图片进行了缩放,设缩放后的图片最小边长为S,然后使用224x224的尺寸对图片进行裁剪,缩放时保证S>=224。当:S=224时,裁剪时可以覆盖全部图片S>>224时,即S远大于224,这时裁剪的结果只能覆盖部分图片,覆盖的范围是图片中的一个物体或物体的一部分。那么,如何缩放图片呢?作者提出了两种方法,一种是S取固定值,先将S固定为256(参考了AlexNet的训练参数)进行训练,然后再基于训练结果将S设置为384,继续训练。第二种方法则是多缩放值训练,在一个范围[S_min, S_max]内随机取值并赋给S(实践中取S_min=256, S_max=512),然后进行训练。因为现实中输入图片的尺寸可能各不相同,这种训练方式可以获得更好的泛化性。同时,作者仍然使用了预训练的思想,以S=384的固定值训练为基础,进行多缩放值的训练。在验证阶段,作者也提出了图片缩放的思想。假设验证时,图片缩放后的最小值为Q,也使用了2种取值方法。第一种为Q取固定值,针对S不同的取值情况:S取固定值时,Q=SS在[S_min, S_max]范围时,Q=0.5(S_min + S_max)第二种为Q取多种值:S取固定值时,Q 从 集合{S-32, S, S+32}中取值S在[S_min, S_max]范围时,Q从集合{ S_min, 0.5(S_min+S_max), S_max }中取值在训练和验证阶段,作者发现对图片进行多值缩放,都可以取得更好的效果。后记以上对VGG模型进行了简单的介绍。人工智能领域的发展是非常迅猛的,作为一个2014年提出的经典模型,VGG虽然被后来的模型超越,但是它给我们带来了很多重要的启示。如卷积网络深度增加可以获得更好的效果,沿着这个方向,人们发现简单的堆叠层并不能获得更好的精度,反而出现了精度的下降,继而诞生了ResNet,将训练深度增加到最多152层;预训练权重对后续模型的初始化,在一定程度上解决了增加深度后,梯度无法收敛的问题;以及图像多值缩放取得更好的泛化效果,指出对数据进行补益可以提高模型效果。在后面的系列文章中,我们还会沿着VGG支出的方向,以及它带给我们的启示,介绍更多的模型和视觉领域的新成果。
  • [热门活动] Tensorflow 2.0实现卷积神经网络CNN对MNIST数字分类
    Tensorflow 2.0实现卷积神经网络CNN对MNIST数字分类本教程演示了如何训练简单的卷积神经网络(CNN)来对MNIST数字进行分类。这个简单的网络将在MNIST测试集上实现99%以上的准确率。因为本教程使用Keras Sequential API,所以创建和训练我们的模型只需几行代码。注意:CNN使用GPU训练更快。1.    导入TensorFlowfrom __future__ import absolute_import, division, print_function, unicode_literals   import tensorflow as tf   try:     import tensorflow.keras as keras   except:     import tensorflow.python.keras as keras2.    下载预处理MNIST数据集#下载预处理MNIST数据集   (train_images, train_labels), (test_images, test_labels) = keras.datasets.mnist.load_data() train_images = train_images.reshape((60000, 28, 28, 1)) test_images = test_images.reshape((10000, 28, 28, 1))   # 特征缩放[0, 1]区间   train_images, test_images = train_images / 255.0, test_images / 255.03.    创建卷积基数下面6行代码使用常见模式定义卷积基数: Conv2D 和MaxPooling2D层的堆栈。作为输入,CNN采用形状的张量(image_height, image_width, color_channels),忽略批量大小。MNIST有一个颜色通道(因为图像是灰度的),而彩**像有三个颜色通道(R,G,B)。在此示例中,我们将配置CNN以处理形状(28,28,1)的输入,这是MNIST图像的格式,我们通过将参数input_shape传递给第一层来完成此操作。#创建卷积基数   model = keras.models.Sequential() model.add(keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1))) model.add(keras.layers.MaxPooling2D((2, 2))) model.add(keras.layers.Conv2D(64, (3, 3), activation='relu')) model.add(keras.layers.MaxPooling2D((2, 2))) model.add(keras.layers.Conv2D(64, (3, 3), activation='relu'))   print(model.summary()) Model: "sequential"_________________________________________________________________Layer (type)                 Output Shape              Param #=================================================================conv2d (Conv2D)              (None, 26, 26, 32)        320_________________________________________________________________max_pooling2d (MaxPooling2D) (None, 13, 13, 32)        0_________________________________________________________________conv2d_1 (Conv2D)            (None, 11, 11, 64)        18496_________________________________________________________________max_pooling2d_1 (MaxPooling2 (None, 5, 5, 64)          0_________________________________________________________________conv2d_2 (Conv2D)            (None, 3, 3, 64)          36928=================================================================...在上面,你可以看到每个Conv2D和MaxPooling2D层的输出都是3D张量的形状(高度,宽度,通道),随着我们在网络中更深入,宽度和高度大小趋于缩小,每个Conv2D层的输出通道的数由第一个参数(例如,32或64)控制。通常,随着宽度和高度的缩小,我们可以(计算地)在每个Conv2D层中添加更多输出通道4.    在顶部添加密集层为了完成我们的模型,我们将最后的输出张量从卷积基(形状(3,3,64))馈送到一个或多个密集层中以执行分类。密集层将矢量作为输入(1D),而当前输出是3D张量。首先,我们将3D输出展平(或展开)为1D,然后在顶部添加一个或多个Dense层。MINST有10个输出类,因此我们使用具有10输出和softmax激活的最终Dense层。model.add(keras.layers.Flatten()) model.add(keras.layers.Dense(64, activation='relu')) model.add(keras.layers.Dense(10, activation='softmax'))   print(model.summary()) # 显示模型的架构 Model: "sequential"_________________________________________________________________Layer (type)                 Output Shape              Param #=================================================================conv2d (Conv2D)              (None, 26, 26, 32)        320_________________________________________________________________max_pooling2d (MaxPooling2D) (None, 13, 13, 32)        0_________________________________________________________________conv2d_1 (Conv2D)            (None, 11, 11, 64)        18496_________________________________________________________________max_pooling2d_1 (MaxPooling2 (None, 5, 5, 64)          0_________________________________________________________________conv2d_2 (Conv2D)            (None, 3, 3, 64)          36928_________________________________________________________________flatten (Flatten)            (None, 576)               0_________________________________________________________________dense (Dense)                (None, 64)                36928_________________________________________________________________dense_1 (Dense)              (None, 10)                650=================================================================...从上面可以看出,在通过两个密集层之前,我们的(3,3,64)输出被展平为矢量(576)。5.    编译和训练模型model.compile(optimizer='adam',               loss='sparse_categorical_crossentropy',               metrics=['accuracy']) model.fit(train_images, train_labels, epochs=5)...Epoch 5/560000/60000 [==============================] - 15s 258us/sample - loss: 0.0190 - accuracy: 0.99416.    评估模型#评估模型   test_loss, test_acc = model.evaluate(test_images, test_labels)   print(test_acc) 10000/10000 [==============================] - 1s 92us/sample - loss: 0.0272 - accuracy: 0.99210.9921 如你所见,我们简单的CNN已经达到了超过99%的测试精度,这几行代码还不错。另一种编写CNN的方式here(使用Keras Subclassing API和GradientTape)。 本实验利用网上已有的北京房价数据集预测了北京的房价,实现了TensorFlow的线性回归应用。更多的技术内容,请访问腾科公司网站 www.togogo.net
  • [技术干货] 使用两层卷积神经网络训练手写数字识别模型
    在手写数字识别实践 中,我使用训练好的模型对自制的数字图像进行了识别,识别的成功率只有不到4成。为了提高识别的精度,我尝试采用两层卷积神经网络来进行手写数字图像的识别。具体代码如附件所示其中,mnist_train_cnn.py是在本机训练两层卷积神经网络模型的程序代码;mnist_test_cnn.py是使用训练好的模型来识别自制手写数字图像的程序代码;经过测试,使用两层卷积神经网络模型后,对自制手写数字图像的识别精度成功提升到了9成左右。
  • [问题求助] 使用Modelarts的moxing模块来训练卷积神经网络时遇到的问题
    在手写数字图像识别实践中,由于使用实践中推荐的模型对自制的数字图像进行识别的成功率只有不到4成,为了提高模型的精度,我采用双层卷积神经网络来进行模型的训练。在本机进行试验时,训练好的模型在对自制的数字图像进行识别时取得了很好的效果,识别成功率超过了9层。但当通过modelarts来训练两层卷积神经网络模型时,我遇到了问题,就是对于moxing这个模块的使用还是不是很了解,我尝试修改了train_mnist.py程序,把其中的模型换成了两层卷积神经网络,在训练时没有发现问题,能够成功生成模型,但在测试模型时,模型的识别精度却只有1成,基本上是无论输入是什么,模型的输出都固定一个数字......这应该是我代码中存在问题,还希望大神们能指点一下......在附件中,是我修改后的训练代码:train_mnist_cnn.py,以及是在modelarts上训练模型的日志文件:job-train-mnistV0002-0-0-ddjgp_default-stdout.log从日志文件来看,训练的精度应该是很高的才对...
  • [问题求助] 模型转换出错Deconvolution层
    caffe模型测试正常,所有的算子都采用的caffe原生算子,转换成离线模型时Deconvolution层报错:[ERROR] FMK:2019-08-05-15:06:06.951.667 CheckShapeMatch:framework/domi/omg/../omg/model/op_builder/deconv_op_builder.cpp:190:"num_output is not 0 and num_output is not equal to (filter_channel * group), " "num_output:512, filter_channel:512, group:512"[ERROR] FMK:2019-08-05-15:06:06.951.694 Init:framework/domi/omg/../omg/model/op_builder/conv_base_op_builder.cpp:83:"Shape of op deconvolution4 does not match"[ERROR] FMK:2019-08-05-15:06:06.951.705 Build:framework/domi/omg/../omg/model/op_builder/op_builder.cpp:31:""Init" failed. Node: deconvolution4."[ERROR] FMK:2019-08-05-15:06:06.951.714 SetInputOutputDesc:framework/domi/omg/../omg/model/model_builder.cpp:314:"Op build failed. Node: deconvolution4."[ERROR] FMK:2019-08-05-15:06:06.951.725 Build:framework/domi/omg/../omg/model/model_builder.cpp:2322:"SetInputOutputDesc Failed!"[ERROR] FMK:2019-08-05-15:06:06.951.734 Generate:framework/domi/omg/omg.cpp:647:"OMG builder ret fail"[ERROR] FMK:2019-08-05-15:06:06.968.149 main:framework/domi/omg_main/main.cpp:652:"OMG Generate execute failed!!"OMG generate offline model failed. Please see the log or pre-checking report for more details.这是原始的caffe层定义(用双线性插值初始化的反卷积进行上采用):layer {  name: "deconvolution1"  type: "Deconvolution"  bottom: "relu_blob52"  top: "upsample_blob1"  param {  lr_mult: 0   decay_mult: 0   }  convolution_param {    kernel_size: 120     stride: 60     num_output: 512     group: 512    pad: 30    weight_filler: {    type: "bilinear"     }     bias_term: false  }问题应该出在mind studio对Deconvolution层组卷积(group convolution)的定义上:num_output is not equal to (filter_channel * group), " "num_output:512, filter_channel:512, group:512"希望能够给解决一下
  • [技术干货] 八分音符算子-北京颜水成教授办公室【神经网络基石-组网-算子篇】
    八分音符(频率)卷积算子 Octave Convolution==== 我是分割线(略过分割线,即是正文) ==== === 标签 ===卷积神经网络,算子分析,认知科学,频谱分析,快速傅里叶变换  === 前奏 ===为什么读此系列文章?优化数学和计算理论帮助机器学习完成了问题分类:1)按照领域划分,比如计算机视觉,自然语言处理,推荐,统计分析预测策略; 2)按照算法复杂划分,比如是否是NP-Hard问题,是否需要精确解;3)按照方法分类,监督性学习问题,非监督性学习问题,半监督性学习模型,和有先验信息的交互学习模型;4)按照研模型分类,比如基于代数线性表出理论、基理论的线性模型,基于决策树的树状非线性模型,基于Kernel理论的非线性模型,基于编码解码器的神经网络;逐渐形成以数据为主轴,离线训练算法,在线推理的机器学习模型离开刀耕火种,进入春秋百家争鸣时代。这一时期,监督性学习理论高速增长,以逻辑回归,SVM,Convolution Neural Network,RNN迅速在子领域占领重要的一席之地。这是一个幸福的时代,实际上每个子领域,都已经形成成熟的方法论,像从Tensorflow开始,我意识的这已经从春秋,进入战国时代。针对大量数据的存储、ETL、和分布式计算的平台,针对机器学习的软件架构实现比如PaddlePaddle、Tensorflow,针对业务场景的端设备优化比如针对于GPU设备TensorRT,针对CPU设备的Intel® OpenVino™,针对计算资源虚拟化、计算能力服务化的云平台,会扮演着越来越重要的作用。很有可能未来,在算法领域算法工程师和软件工程师,很有可能是从不同方向,成长起来的同一批人。所以我们需要了解,研究工业框架底层模型,到底是如何实现,实现从输入到输出的价值提取。本系列文章包含哪些内容?本系列文章,旨在通过扎实的实现的纵向优化,工业级代码框架的横向比较,透视、分析神经网络架构撰写技巧,方法和思路,正确使用神经网络工具,解决实际生成问题:数据篇:数据集编写,训练、测试数据预处理技术,图像数据正则化技巧,ZCA白化技术;带标注的训练数据增强,其中标注包含以下可能的数据类型:BBounding Box, Mask, Key Points, Feature Descriptor。还包括Anchor size等相关超参数估计技巧。无数据无监督性学习算法。网络结构篇:组网手段,各个网络的优势,和loss函数的书写技巧:比如CNN网络如何根据业务实时性选择特征提取层,不同尺度大小目标的特征提取,ROI编码等;再比如将回归问题转化为分类问题,给定一个预估值,动态计算上确界,和下确界,并极大化预估值落入区间的概率,极小化双向溢出率,通过分位数回归来计算loss实现任意非标准分布的强拟合;我们将重点关注,全连接网络,卷积网络,网络搜索(NAS),图网络的实现方法,和撰写技巧。算子篇:具体的算子的实现。比如IoU, GIoU, 我实现的UIoU;再比如卷积块实现,金字塔特征FP实现,残差块实现;在比如卷积核反向传播算法,空洞卷积反向传播算法求解器篇:求解器实现策略, 和相关数学原理。实际上神经网络的求解器涉及的技术和理论还是比较局限的,主要通过heuristic以梯度贪心,参数可行域无限制,参数间无约束关系(比如图连接)因此较为简单;比如Wolf-Powell定理及其实现,用于判定搜索是否可收敛;在拟牛顿法理论二次加速原理,及其局限性和相关近似算法;在比如理论上任网络可以使用另外一个非线性模型代替全连接层FC用来学习,比如SVM,GBDT等;BOOSTING技巧,有趣的AdaBoost;整数优化拓展,实际上离散优化和非离散优化的数学技术有很大的不同,是否可以神经网络架构搜索映射到0-1整数规划,一个值得思考的问题!更复杂的优化求解器技术,参数可行域受限,以参数间以图连接为约束,包含时间窗口约束,则需要更为完善的数学理论。这里我推荐Google OR tools来学习LP, MLP, VRPT(C)进行相关问题求解。计算图:计算图将上述类容串接,形成一个完成的计算骨架。从2015年Dean Jeff等人的文章《Large Scale Deep Learning with Tensorflow》, 计算图不仅仅包含自动微分,还包含分布式思想中的算子算力划分,数据并行,和模型并行的加速思想在里面。自动微分已经被人们完全掌握,比如基于Numpy的AutoGrad, 实现一个自动微分已经不难。但是实现一个能够进行上述在异构设备上进行算力划分, 执行不同并发策略是十分困难的。计算图不仅仅是针对于深度学习设计的计算骨架,而是针对于一般科学计算的计算骨架。比如可以利用Tensorflow实现经典的非监督学习KMeans++的Lloyd过程。当然计算图并不代表全部,科学计算骨架内容,又比如KMeans++的随即发生器,则更多涉及随机过程,概率分布的计算骨架。为什我想写?2019年通过姜老师的推荐,和华为ModelArts团队有接触,认识了陈亮老师等人。陈老师希望我来提高社区氛围,随后我就写了Vgg16, YoloV4(YoloV3)变种的实现,以及对ImageNet预训练网络的参数的利用方法。期间大家努力拼搏的精神,让我大受感动。我和清华大学出版社的编辑讨论,也觉得围绕机器学习的架构是个很重要的点。以往的书目,如华章教育从剑桥出版社引入的以色列科学家著的《深入理解机器学习,从算法到原理》(Understanding Machine Learning from Theory to Algorithms)作为研究生教程,有非常浓厚的数学理论的描述,过于艰涩:首先定义了机器学习的理论框架,以及所有理论服务于将模型编码到计算机上的根本目标;然后样本和总体的关系,定义一些评价由采样样本通过经验误差获得机器学习模型好坏的指标(Valiant提出PAC范式理论,于2010年获得图灵奖,诞生批处理算法并广泛运用于生产算法中,供业模型框架),进而通过找出尽量避免出现坏指标的规则,来设计可充分学习机器学习模型,并将机器学习的学习过程描述为一致收敛过程。接着该书分析了具体线性模型技术算法和一些高级技术。整个过程都是以伪代码和数学表达式来描述,没有明确的研究目标。在现在这种算法越来越专业,研究对象高度相关,算法质量要求越来越高的情况下,这种数学很难帮助学习者掌握1到2两个专业领域的核心技术,跟别说研究目标泛化机器学习体系了。随后2015-2017年博视(BroadView),电子工业出版社围绕着Tensorflow,Caffe, Scipy推出了一大批《XX实践》图书。它们具有以下特点:1)紧密围绕工具,讲解如何通过工具实现一个数据分析手段,从其行文可以看出主要面向非计算机专业方向的学生,从业人员。这导致他们容易受制于工具成为被一些高水平,尤其有计算机专业背景戏称为“调参侠”;2)有代码的实现和讲解,但是仅限于实现比较简单的,大约1000行以内的模型;或者借助框架提供的优化器,算子建模求解,相对上面的著作缺乏批判性分析和相关实验过程及实验结论;或者过于简化问题,和Github已经开源实现、或者二次开源复现所提供的完整的问题框架相差太远;把一个完整的问题的不同步骤,分散到不同章节的不同问题里面,这是不利于学习和掌握的;3)绝大多数图书包括《XX实践》,中关于神经网络,尤其是卷积网络都是浅尝辄止,和目前的高水平模型相差甚远,没有实用性:比如没有对预训练模型的利用,缺乏对数据源的分析,没有区分特征器提取问了包括VGG, ResNet, Inception, DarkNet,MobileNet速度,精确度,大小,架构的区别,没有对多目标检测诸多模块的分析,没有带标注数据数据增强相关的分析和思考。2018年以问题为导向,面向面试的机器学习图书《百面机器学习》在京东售卖。这本书的书写作非常有趣,是先抛出一个问题,然后再寻求解决,类似美国大学课程Warm Up环节,其实和我的一些思考、过去的备课的内容不谋而合:2018年我想改善机器学习面试体验。当时我通过我自己的渠道,已经收到了几十封简历,其中一些已经有相当资深的经验。受限HeadCount要求,我只能挑选一些刚毕业的学生,包括哥伦比亚大学毕业的,美国东北大学毕业,浙大毕业的,厦门大学毕业,华科大毕业的,北京邮电大大学毕业的朋友等。我结合自己的经验,我决定以问题为导向:我利用下班时间对简历进行coach后,面试中我给候选人准备了8道精心选择题目供他(她)3分钟内的选择,同时我又准备了20到题目根据前一步的选择,动态决定第二道题目选择,并和她沟通是否感兴趣。如果答得不是十分好,我会给一份课后作业,如果感兴趣,可以3天内完成的一个小Project。我同时我想HR,面试候选人做了些回访,无论结果如何,满意度还是非常高的。在我之前面试要么是纯Code,主要考察计算机基础理论和算法,要么就是现场做数学推理并回答一些比较经典的问题,而我自己恰又是一个平时只有兴趣做最基本的训练,大块时间放在专业领域上,临场全靠即兴发挥的人,觉得这个面试流程还有很大的改进空间。事实上例如2009年MSRA出版的《编程之美》和上述《百面机器学习》都一个不足,就是看似十分机智的问题,其实都有专门的研究领域。在这个研究领域,只能算是浅尝辄止的问题和实践。比如最基本的Qick-Sort,若没有读过专门的学术著作,了解其不断改进的过程,一个新问题放在面前,是很难立即优化的(比如对不均匀分布数据块,甚至数据链表,加速Quick-Sort;比如通过随机化,剪枝技术,实现O(log(n))速度完成topK排序--传统方法利用小/大顶堆heap完成O(nlogk)速度排序;笔者在Github有相关解答),因为面试者缺乏研究积累。所以我希望面试应该在应试者的专业范围内循序渐进,这对于涵盖,统计学、运筹学、控制学、计算机工程的、计算图形学的交叉学科尤为重要,因为很难有人全部掌握,而且我们的职业发展也要求你精专一个或两个领域。我仔细阅读了诸葛越女士做得序,发现这本书起于公众号的“Hulu机器学习问答”。因此我发现诸葛越女士似乎对“通用人工智能更感兴趣”,比如此书仍然更关注方法论,有非常强的数学属性在里面;书目同时涵盖了优化论,图模型,采样理论,全连接神经网络,深度卷积网络,深度残差网络,循环神经网络,树模型,强化学习,生成模型GAN。我们已经知道,Hulu是一个自制作剧目,并且售卖限时流媒体广告的公司,如果这本书能够从Hulu广告业务所对应的计算广告问题,视频网站相关的运营策略出发,比如推荐,曝光,排序问题,你会发现数据(有业务意义的埋点数据)所对应的处理方法(特征工程,采样,非均衡数据处理,离散特征编码),以及所选用的模型(可解释性)立刻有了明确的指向,方便我们清晰地理解整本书的组织架构。我希望本系列文章以问题为导向,同时问题是一脉相承的,主线明确。系列文章的每一部分,是为了主线问题,进一步细化每一个步骤的处理方法,和相关研究,在力所能及的范围内完整的解决一个目标,掌握一两个技术,产生实际价值。==== 我是分割线 ==== === 正文 ===Warmup原始的卷积核及其BP算法,在2019年4月30公开的这篇名为"Drop an Octave: Reducing Spatial Redundancy in Convolutional Neural Networks with Octave Convolution"[1]的文章里,原始卷积成为“平凡的实现”(Vanilla implementation)。在考虑新提出的八分音符(频率)[5]卷积前,我们需要回顾下上一篇文章提到的卷积网络的卷积核理论,以及JPEG算法。1. 卷积核理论回顾,如[文章](https://mp.weixin.qq.com/s/GKZeTrfTgRXmj29c_XouOQ)介绍:filters x k x k卷积,作用在输入特征B x H x W x C,涉及: B*(k^2*C*h_nm_out*w_nm_out + (k^2-1)*C*h_nm_out*w_nm_out-1)次浮点计算。我们已经说明,卷积对应多项式乘法的系数表达式。由于n维多项式,根据代数基本定理,由n采样点唯一确定,得知多项式,由范德蒙矩阵决定。因此将多项式乘法,改由采样的点值乘积(O(n))表示后,就可以通过范德蒙矩阵的逆推算,多项式乘积的系数,即傅里叶变换的取值。利用复根采样“重数折半”性质,根据主定理,FFT可以nlog(n)完成n阶多项式到采样值表示法:1) img2col可用于加速dot算子,但FFT不能使用img2col,因为理论上k*k的卷积核,最多只需要k维傅里叶基就可以表示,利用傅里叶变换的可分离性(Separable)可以用两个一维傅里叶变换计算二维傅里叶变换。2) 应用FFT到卷积核:H*W* (log(H) + log(W)) 3) 应用FFT到输入:H*W* (log(H) + log(W))4) 上面两个结果执行点乘计算: H*W5) 应用逆FFT到上一步计算结果:H*W*(log(H) + log(W))因此总浮点计算量(Flopts)为:B*(log(H) + log(W))*C*H*W对于256*256的图像log(H) + log(W) ~ 16,当卷积核为5, 8时分别节省1.5, 4倍算力。2. JPEG算法在JPEG理论,图像的像素在空间域(Spatial Domain)是有关联性的。因此先算出每个channel的图像的均值,并平移该通道的图像,然后启用二维离散傅里叶变换将图像从空间域(Spatial Domain)转换到 频域 (Frequency Domain) -- 每个像素点,由不同频率的余弦波值叠加而成,得到的逆变换。我们将得到下图,此时图像像素间毫无相关性:即任意丢弃高频波信息,逆变换后不改变原图像纹理。这是以二维傅里叶变换作为基础的JPEG技术专利的核心概念之一。这里的傅里叶变换,就是我们通过卷积核(8x8)点乘输入特征。 图1:空间频率 Spatial Frequency (SF)[https://sites.uclouvain.be/goffauxlab/project_sf.html]空间频谱图是对应频域低频傅里叶波函数。具体做法如下:1) 将图像通过img2col展成一维图像2) 用快速傅里叶变换,求得频域值3) 将低频移到中心方便矩形滤波器,过滤# /bin/pythonimport cv2import numpy as npimport utils# Read images with shape = (H,W)...# Perform 2-dimension fft (which implemented by two 1-dimension fft)Freq2 = np.fft.fft2(img)# Shift high frequency from bottom-right to centerFreq2_shift = np.fft.fftshift(Freq2)# Perform frequencies crop and extraction...可以通过下面代码进行查看频谱图:magnitude_spectrum = A * np.log(np.abs(fshift)) 通过,剪裁,我们可以提取不同尺度的频谱特征。下面我提供了实验代码和结果(Colab: https://colab.research.google.com/drive/1Qy5hRRXUz_czN_PXofhZ60ivA9PnA_T7#scrollTo=fLmYabj7XbQP):图2:频谱空间低频特征提取图3:频谱空间高频特征提取图4:频谱空间带特征提取3. 频谱和方向作为不变特征根据认知科学实验,视觉特征被分为,空间频谱(Spatial Frequency)和 朝向(Orientiation)[2]。大脑视觉皮层小的感受野被空间频谱和朝向分解激活,大的感受野被复杂的图形激活[2][3][4].实验发现[空间频谱和朝向激活量可以被朝向特征和频谱特征的线性加权逼近[2], 且不同的皮质位置响应不同的频谱频率[2]。其中局部8梯度方向直方图检测,已经成为了SIFT特征用于图像处理多年。高斯差分金字塔(DoG Pyramid)方法因此无论在仿生学上,还是实际计算中首先应用了多尺度特征提取的思想,已经接近日后的卷积块塔思想方法。尺度不变特征方法(SIFT)又进一步从朝向角度来寻找关键特征点,从而去定义图像特征。我们已经知道SIFT[6]的算法原理是有意义的,但是通过特征点来定义图像特征,已经不是我们现在的做法了。我们现在是通过神经网络编码器来输出图像的特征向量,精确度在包括ImageNet, Coco, VOC等数据集的比赛上已经超过了以往的所有方法。本偏文章介绍的算子,从频谱角度出发,我猜想还可以从朝向进一步发掘,而这有历史过往图像特征提取方法,电子信号学数学物理方法,认知科学实验的坚实支撑。Question & Answer卷积网络由卷积块组成。每个卷积包含若干组卷积算子。卷积算子是可训练的,由卷积核,bias组成的待训练参数。怎么设计实验证明参数是有,或者没有冗余?需要哪些指标验证你的实验?OctConv八分音符卷积,将训练过程中已经接近卷积核算子的参数,分为高频,和低频部分存储,并沿Channle(通道)方向丢弃高频特征参数。由于傅里叶变换的线性特征,(H+L)conlv W ~ Output = H conlv W + L conlv W。记输出Output的高频部分为Output_H, 低频部分为Output_L执行Butter-Fly计算:Output_H = Conlv(Inp_H, W_H) + Upsamle(Conlv(Inp_L, W_LH)) # Inp_H: HxW*(1-alpha)*ChannelOutput_L = Conlv(inp_H, W_L) + Conlv(AveragePooling(X_H, 2), W_HL) # Inp_L: 0.5Hx0.5W*alpha*Channel feature size这里沿通道方向丢弃参数十分有趣,如果我们观察以往的训练结果,不同的卷积核,可以对应不同的方向。本文主要是在不影响视觉特征的情况下,抑制高频特征。我期待从Channel角度,进一步分析方向特征的作用。图5:图像频谱分解[1]准确说,Output_H如前定义只和Output位置有关,例如靠近Output中心就是低频分解,靠近Output边缘就是高频分解。不考虑沿通道(Channel)方向按alpha比例分解,因此H 和 L是正交的因此H只对Output_H有贡献,L只对Output_L有贡献。但如果考虑了沿Channel方向分解,两者就不正交了,数值上也有体现。图6:Octave Convolution计算过程[1]对于Representation的研究,论文支出还见于Squeeze and Excitation Network(https://zpascal.net/cvpr2018/Hu_Squeeze-and-Excitation_Networks_CVPR_2018_paper.pdf)中的SE-Block模块。该论认为可以对卷积中的输出特征,用Embedding沿Channel方向压缩:# # Keras Implemenationdef SEBlock(inp, ratio=16, name=''):        channel = K.int_shape(inp)[config.channel_axis] # Channel last       avpooling = GlobalAveragePooling2D(name='{}_seblock_avgpooling'.format(name))(inp)        # FC with channel / ratio as output channel    fc1 = Dense(channel // ratio, activation='relu', name='{}_seblock_fc1'.format(name))(avpooling)        # FC with channel as output channel with sigmoid as activation    fc2 = Dense(channel, activation='sigmoid', name='{}_seblock_fc2'.format(name))(y)    # scale      output = Multiply(name='{}_seblock_mul'.format(name))()        return output但是SE-Block其显著增加了参数体积,和运算(FC层),应用并不广泛。OctConv从Channel方向来丢弃高频有异曲同工的作用,很明显但就方法上,OctConv更具优势。    图7:卷积核分解[1]OctConv基于上述隐含假设,有了如下参数划分:其中低频由0.5Hx0.5Wxalpha*Channel输入特征大小存贮卷积参数,高频由HxW*(1-alpha)*Channel输入特征大小存贮卷积参数。alpha为沿通道(Channel)方向的比例划分。因此我们根据这个,可以在进行计算量复杂度估计,约为1-float(3)/4*alpha*(2-alpha) # 不考虑upsampling, 和 average pooling算子复杂度。图8:输入特征频谱分解图[1]这样划分,导致卷积核参数接触了更大范围的输入特征,从而间接增加了感受野大小。相反地,这将导致对小目标检测精度下降。    表1:alhpa取0.5,通过Central Crop和Resize操作调整输入图片尺度对以ResNet-50架构模型的性能影响[1]理论计算没有考虑到Upsampling和Downsampling的计算量。实际计算效率和相关算子实现效率和参与程度有关。Facebook通过TVM给出了官方实现,其中1) https://github.com/facebookresearch/OctConv/blob/master/utils/symbol/symbol_resnetv2.py定义了实验Resnet组网;2) https://github.com/facebookresearch/OctConv/blob/master/utils/symbol/symbol_resblock.py定义了ResnetBlock组件,通过OctaveConvolution实现的ResnetBlock被记做BottleNeckV{1,2};实现方法是将标准残差连接块中的每个卷积块,由OctaveConvolution实现的卷积块代替;3)https://github.com/facebookresearch/OctConv/blob/master/utils/gluon/train_imagenet.py定义了训练入口,其中get_data_loader定义了数据预处理,和增强模块。inference测试平台为Intel Skylake CPU 2.0 GHz (single thread)。TVM编译结果用来做对照实验(尚不清楚,TVM编译后的算子对实测量性能影响程度)。论文实验分析解读笔者认为思想上,如前面铺垫,这是非常有价值的思考方向和方法。我们发现源代码中,OctConv是作用在整个训练周期,因此在初始迭代策略上,卷积分解的分析可能不凑效。OctConv实验结论是图9:实验结果图OctConv对感受野比较小的模型,精度有比较大的提升,同时减少了模型参数;对于常用模型,通过调整alpha,也能在减少模型参数的同时,提高精度。说明我们的卷积核确实包含冗余特征。实验分析如Warmup, 我们希望先设计下小的卷积块实验,根据OctConv中推理表达式,来观察训练过程Spatial Frequency分解能否满足正交。OctConv实验表明沿Channel方向丢掉一些高频特征参数,在某个channel比例因子下,有可能在减少参数的情况下,提升训练效果效果。沿用OctConv沿Channel通道丢弃高频参数框架,我们还希望了解,对于beta不同取值下得到的不同尺度的低频块和高频块对于“压缩能力-模型精度”的影响。[Experiment Access Adress](#)[1] Retrieve on 10th Aug 2019, "Drop an Octave: Reducing Spatial Redundancy in Convolutional Neural Networks with Octave Convolution", https://arxiv.org/pdf/1904.05049.pdf, Yunpeng Chen, Haoqi Fan, Bing Xu, Zhicheng Yan, Yannis Kalantidis, Marcus Rohrbach, Shuicheng Yan, Jiashi Feng[2] Everson RM, Prashanth AK, Gabbay M, Knight BW, Sirovich L, Kaplan E. Representation of spatial frequency and orientation in the visual cortex. Proc Natl Acad Sci U S A. 1998;95(14):8334–8338. doi:10.1073/pnas.95.14.8334[3] [4][5] Retrived on 15th Aug 2019, https://zh.wikipedia.org/wiki/Octave_(%E9%9B%BB%E5%AD%90%E5%AD%B8)[6] Distinctive Images Features from Scale-Invariant Keypoints, David G. Lowe, https://www.cs.ubc.ca/~lowe/papers/ijcv04.pdf, January 5, 2004[7] https://zpascal.net/cvpr2018/Hu_Squeeze-and-Excitation_Networks_CVPR_2018_paper.pdf === 标签 ===卷积神经网络,算子分析,认知科学,频谱分析,快速傅里叶变换
  • [技术干货] 深度学习中的目标检测原理概述
    一、 R-CNN的原理传统的目标检测方法大多以图像识别为基础。一般可以在图片上使用穷举法选出所有物体可能出现的区域框,对这些区域框提取特征并使用图像识别方法分类,在得到所有分类成功的区域后,通过非极大值抑制(Non-maximum suppression)输出结果。R-CNN的全称是Region-CNN,可以说是第一个成功将深度学习用到目标检测上的算法。R-CNN同样遵循传统目标检测的思路,同样采用提取框、对每个提取框提取特征、图像分类、非极大值抑制四个步骤进行目标检测。只不过在提取特征这一步,将传统的特征换成了深度卷积网络(CNN)提取的特征。使用R-CNN进行目标检测的基本步骤如下:(1)对于原始图像,首先使用Selective Search搜寻可能存在物体的区域。Selective Search可以从图像中启发式地搜索出可能包含物体的区域,相比穷举法可以节省一部分计算量。(2)将取出的可能含有物体的区域送入CNN中提取特征。CNN通常是接受一个固定大小的图像,而 Selective Search所取出的区域大小却各有不同,对此,R-CNN的做法是将区域缩放到统一大小,再使用CNN提取特征。(3)提取出特征后使用支持向量机SVM进行分类,最后通过非极大值抑制输出结果。R-CNN的训练可以分成下面四步:(1)在训练集上训练CNN,R-CNN论文中使用的CNN网络是AlexNet,数据集是ImageNet。(2)在目标检测的数据集上,对训练好的CNN进行微调(3)用Selective Search搜索候选区域,统一使用微调后的CNN对这些区域提取特征,并将提取的特征存储起来。(4)使用提取的特征,训练SVM分类器。R-CNN的缺点在于计算量太大,因此,后续研究者又提出了Fast R-CNN和Faster R-CNN,这两者在一定程度上改进了R-CNN计算量大的缺点,不仅速度变快不少,识别准确率也得到了提高。在介绍Fast R-CNN和Faster R-CNN之前,需要先引入SPPNet,并介绍SPPNet的原理。_二、SPPNet的原理SPPNet也称为空间金字塔池化卷积网络,它可以将CNN的输入从固定尺寸图片改进为任意尺寸的图片。SPPNet在普通的CNN结构中加入了ROI池化层,使得网络的输入可以是任意尺寸的。ROI池化层一般跟在卷积层后面,它的输入是任意大小的卷积,输出是固定维数的向量。其原理如下:(1)设卷积层输出的宽度为w,高为h,通道为c。不管输入图像尺寸是多少,卷积层的通道数是不会变,也就是说c是一个常数。而w,h会随着输入图像的尺寸的变化而变化,可以看做是两个变量。(2)ROI池化层首先将卷积层划分为44的网格,每个网格的宽为w/4,高为h/4,通道数为c。当不能整除时,取整数。(3)对于网格中的每个通道,都取出最大值(即对每个网格内的特征做最大值池化),这个44的网格最终就形成了16c维的特征。(4)然后,再将网络划分成22的网格,用同样的方法提取特征,提取的特征的长度是4c。再把网络划分为11的网格,提取出的特征的长度就是c(也就是取出卷积中每个通道的最大值)。(5)最后,将得到的特征拼接起来,得到的特征是16c+4c+c=21c维的特征。很显然,这个输出特征的长度与w,h无关,因此ROI池化层可以把任意宽度、高度的卷积特征转换为固定长度的向量。将ROI应用到目标检测中,可以这样考虑:网络的输入是一张图像,中间经过若干卷积形成了卷积特征,这个卷及特征实际上和原始图像在位置上是有一定对应关系的。因此,原始图像中的候选框,实际上也可以对应到卷积特征中相同位置的框,而利用ROI可以将卷积特征中不同形状的区域对应到同样长度的向量特征。综合上述步骤,就可以将原始图像中的不同长宽的区域都对应到一个固定长度的向量特征,这就完成了各个区域的特征提取工作。采用ROI后,就可以先对图像进行一遍卷积计算,得到整个图像的卷积特征;接着,对于原始图像中的各种候选框,只需要在卷积特征中找到对应的位置框,再使用ROI池化层对位置框中的卷积提取特征,就可以完成特征提取工作R-CNN与SPPNet的不同在于,R-CNN要对每个区域计算卷积,而SPPNet只需要计算一次,所以SPPNet的效率要高得多。三、Fast R-CNN的原理在SPPNet中,特征提取和区域分类两个步骤还是分离的,特征提取通过ROI,而在区域分类时,还是使用传统的SVM作为分类器。Fast R-CNN相比SPPNet更进了一步,使用神经网络(全连接层)进行分类,这样就可以同时训练特征提取网络和分类网络,从而取得比SPPNet更高的准确度。Fast R-CNN的全连接层有两个输出,一个输出负责分类,另一个输出负责框回归。(1)分类:假设要在图像中检测K类物体,那么最终的输出应该是K+1个,因为还需要一个背景类,即针对该区域无目标物体的情况(2)框回归:对原始的检测框进行某种程度的“校准”,即学习到与尺寸无关的平移量和缩放量。四、Faster R-CNN的原理Fast R-CNN中还存在一个有点尴尬的问题,它需要使用Selective Search提取框,这个方法比较慢。在Faster R-CNN中,用RPN(Region Proposal Network)网络取代了Selective Search,速度和准确度均得到了很大提高。RPN还是需要先使用一个CNN网络对原始图片提取特征,对这个卷积特征再进行一次卷积计算,保持宽、高、通道不变。下面定义一个“位置”的概念:对于一个5139256的卷积特征,称它一共有5139个位置。让新的卷积特征的每一个位置都负责原图中对应位置9种尺寸的框的检测,检测的目标是判断框中是否存在一个物体,因此,一共有51399个框,这些框统一称为“anchor”。anchor的面积分别为128128,256256,512512,每种面积又分为三种长宽比:2:1,1:1,1:2anchor的尺寸实际是属于可调的参数,不同的任务可以选择不同的尺寸。对于这5139个位置和51399个anchor,接下来展示每个位置的计算步骤:设k为单个位置对应的anchor的个数,此时k=9,首先使用一个33的滑动窗口,将每个位置转换为一个统一的256维的特征。 这个特征对应了两部分的输出:一部分表示该位置的anchor为物体的概率,这部分的总输出长度为2k(一个anchor对应两个概率,一个是是物体的概率,一个是不是物体的概率);另一部分为框回归(同Fast R-CNN),一个anchor对应四个框回归参数(w和h的平移量、缩放量),因此框回归部分的总输出的长度为4kFaster R-CNN使用RPN生成候选框后,剩下的网络结构与Fast R-CNN一样在训练过程中,需要训练两个网络:RPN和分类网络。通常的做法是交替训练,即在一个batch中,先训练RPN一次,再训练分类网络一次。注:以上内容均摘抄至《21个项目玩转深度学习-基于TensorFlow的实践详解》(河之源编著)
  • [技术干货] 定义超分辨问题——降级模型
    要训练监督式超分辨模型的第一个问题是:如何获得“低清-高清”样本对?事实上,我们只能通过将任意一张图片当做高清图像然后将其缩小成低清图像的方式制作训练样本对,而反过来就无法做到,因为任意一张图片对应的“真实”高清图像是未知的(比如手机拍照得到的“普清”图片不存在“真实”的高清图像)。为此,我们必须先通过某种方式生成低清图像,生成低清图像的过程在超分辨的研究文献中被称为降级(Degradation),可用如下公式表示:I_x = \mathcal{D}(I_y;\delta)Ix=D(Iy;δ)其中\mathcal DD表示降级映射,\deltaδ为模型中的参数。将上式代入超分辨模型,可得:\hat{I}_y = \mathcal{F}(\mathcal{D}(I_y;\delta);\theta)I^y=F(D(Iy;δ);θ)可以发现,其实超分就是是降级的反过程,当超分图像\hat{I}_yI^y越来越接近高清图像I_yIy时,超分模型就会越来越接近降级模型的反函数。所以说,有什么样的降级模型假设,就会习得什么样的超分模型,降级模型的假设越贴近真实场景,习得的超分模型的效果就越好。然而实际问题中的降级过程是非常复杂的,它会受散焦、压缩失真、传感器噪声、噪点等诸多因素的影响。现有降级模型假设有两种,第一种模型将降级过程简单的描述成下采样:I_x = (I_y)\downarrow_sIx=(Iy)↓s式中的\downarrow↓表示下采样操作,ss表示下采样的倍数,为了简化问题,大多数超分模型都采用了这样的假设。而另一种模型更加复杂,它将模糊与噪声纳入考虑:I_x = (I_y \otimes k)\downarrow_s + nIx=(Iy⊗k)↓s+n其中\otimes⊗表示卷积,kk为卷积核,nn为加性噪声,该模型假设低清图像由高清图像经过加模糊(用卷积来建模表示)、下采样和加噪(假设为加性噪声)操作后得出,这种假设更具广泛性,也更贴近实际情况。考虑模糊与噪声的降级模型
  • [技术干货] 超分辨网络结构设计——上采样方法
    上采样是超分辨网络设计中的关键一环,主要分为基于插值的方法和基于学习的方法。常用的插值法有以下三种:最近邻插值 (Nearest Neibor): 使用中心像素块填充满插值空隙双线性插值 (Bilinear): 在横竖两个方向上进行线性插值双三次插值 (Bicubic): 在横竖两个方向上进行三次插值其中双向插值的过程如下图所示,:双向插值的过程图中的蓝点表示原始像素,黄点由横向插值生成,绿点由纵向插值生成。插值时先进行横向插值再进行纵向插值,双线性插值和双三次插值的过程均如此,只是使用的插值函数不同。基于插值的上采样方法是一个固定运算,而基于学习的上采样方法将使用带权重的网络层来学习上采样过程。当今应用最广泛的两种上采样层为反卷积层(Deconvolution Layer)和亚像素层(Sub-Pixel Layer),它们的运算过程如下图所示:两种上采样层的区别反卷积层与普通卷积相比只是多了像素扩展的步骤,在原始像素周围填充足够数量的0可以保证卷积得到的特征图的尺寸符合放大倍数要求。反卷积层由于其余原始卷积的兼容性而被广泛应用,但反卷积层具有“非均匀重叠效应”,这会导致生成图像带有典型的棋盘纹理,使生成效果变差。亚像素层使用多个卷积核直接在原始图像上(带padding)做卷积,然后将得到的多个特征图进行重排列合成出一张更大的图像,这要求特征图的数量必须是放大倍数的平方。可以发现,亚像素层输出特征图的最大有效感受野为9,信息利用率比反卷积层更高(最大感受野为4)。但一个重构块(灰色虚线标识的块)内的所有像素共享相同的感受域,这可能会导致各块的边界处产生不自然的纹理。
  • [技术干货] 超分辨经典模型:单链路浅层网络——SRCNN
    SRCNN是深度学习超分辨的开山之作,发表于2014年,此时AlexNet问世才2年,Tensorflow也还没有发布,深度学习的发展远不如现在这么繁荣。作者将超分过程抽象为1) 图像块抽取与表征 2) 非线性映射 3) 重构 三个步骤,每个步骤都可以用卷积来表示,从而组成了简洁的三层卷积结构。网络使用插值后的低清图像作为输入,第一个卷积层密集地抽取9x9的低清图像块(patch)并将每一个图像块表示成64维的特征向量,即低清表征;第二个卷积层利用一组(5x5个)低清特征向量生成一个高清像素的特征向量(32维),即完成低清表征到高清表征的非线性映射;第三个卷积层使用一组(5x5个)高清特征向量重构出一个高清像素,即利用特征重构图像。值得注意的是,为了避免边际效应,SRCNN中的卷积没有使用Padding,导致最后生成的图像尺寸变小, 所以在评估性能时只使用了高清图像的中心部分。SRCNN结构图SRCNN的设计初衷并不是简单的套用CNN,而是归纳整合先前的超分辨研究成果。作者在原文中揭示了基于稀疏表示的超分辨方法与SRCNN的内在联系,并表示前者可以被解释为一种特定的卷积网络,这充分印证了CNN应用于超分辨任务的合理性与灵活性。
总条数:400 到第
上滑加载中