#2022.02.15补充
- dialate convolution 空洞卷积 空洞卷积(Atrous Convolution)的优缺点 - 赵代码 - 博客园
- 优点:
- 特征图相同情况下,空洞卷积可以得到更大的感受野,从而获得更加密集的数据;更大的感受野可以提高在目标检测和语义分割的任务中的小物体识别分割的的效果。
- 使用空洞卷积代替下采样/上采样可以很好的保留图像的空间特征,也不会损失图像信息。当网络层需要更大的感受野,但是由于计算资源有限无法提高卷积核数量或大小时,可以考虑使用空洞卷积。
- 缺点:
- 网格效应并不是所有的pixel都用来计算了,这样的方式会损失信息的连续性,这对于像素级的任务来说是致命的。
- 远距离信息可能不相关。如果光采用大的扩张率的卷积可能只对一些大物体分割有效果。设计好空洞卷积层的关键在于如何同时处理不同大小物体的关系。
- 如何使用:一个称为HDC(混合空洞卷积)的结构被设计出来解决卷积核不连续的问题。
- 叠加卷积的扩张率不能有大于1的公约数
- 将扩张率设计成锯齿状结构,如[1,2,3,1,2,3] 从一开始就保留了完整连续的3*3区域,之后的几个rate设计又保证了感受野的连贯性,即使有重叠也密不透风;设计成锯齿状结构。这是为了同时满足小物体、大物体的分割要求
- 最后一层的空洞卷积的
dilation rate
最大,且dilation rate
小于等于卷积核的大小。这也是为了对抗网格效应。
- 优点:
- deformable convolution 扭曲卷积 Deformable Convolution 关于可变形卷积 - 知乎
- 可变形卷积是指卷积核在每一个元素上额外增加了一个参数方向参数,这样卷积核就能在训练过程中扩展到很大的范围。
(a)是传统的标准卷积核,尺寸为3x3(图中绿色的点);
(b)就是我们今天要谈论的可变形卷积,通过在图(a)的基础上给每个卷积核的参数添加一个方向向量(图b中的浅绿色箭头),使的我们的卷积核可以变为任意形状;
(c)和(d)是可变形卷积的特殊形式。 - 传统卷积的问题:未知的变化适应性差,泛化能力不强。卷积单元对输入的特征图在固定的位置进行采样;池化层不断减小着特征图的尺寸;RoI池化层产生空间位置受限的RoI。同一CNN层的激活单元的感受野尺寸都相同,这对于编码位置信息的浅层神经网络并不可取,因为不同的位置可能对应有不同尺度或者不同形变的物体,这些层需要能够自动调整尺度或者感受野的方法。
- 卷积核可以根据实际情况调整本身的形状,更好的提取输入的特征。
具体过程: - 理解误差:很多人可能以为deformable conv学习的是可变形的kernel,其实不是不是不是!本文并不是对kernel学习offset而是对feature的每个位置学习一个offset。
- defomable ROI pooing
首先,通过普通的ROI Pooling得到一个feature map,如下图中的绿色块,通过得到的这个feature map,加上一个全连接层,生成每一个位置的offset,然后按照上面的公式得到△Pij,为了让offset的数据和ROI 的尺寸匹配,需要对offset进行微调。
- 可变形卷积是指卷积核在每一个元素上额外增加了一个参数方向参数,这样卷积核就能在训练过程中扩展到很大的范围。
- Non-Local网络设计 我们都爱Non-local 神经网络 - 知乎
- 捕捉长距离依赖关系是深度神经网络的核心问题。以图像数据为例,要想捕捉长距离依赖,通常的做法是堆积卷积层,随着层数的加深,感受野越来越大,就能把原先非相邻的像素点纳入到一个整体考虑,获取的信息分布广度也越来越高。缺点:计算效率很低,层的加深意味着更多的参数,更复杂的关系;优化困难,需要谨慎设计优化过程;建模困难,尤其是对于那些多级依赖项,需要在不同距离位置传递信息
- 非局部操作是将所有位置对一个位置的特征加权和作为该位置的响应值。
non-local operations通过计算任意两个位置之间的交互直接捕捉远程依赖,而不用局限于相邻点,摒弃了距离的概念。non-local可以作为一个组件,和其它网络结构结合。
适用范围:在视频中,长距离的相互作用发生在空间和时间中有距离的像素之间,一个单独的non-local块,可以用前向传播的方式直接捕获这些时空依赖关系。【比较适用于视频时刻序列】 - non-local operations的通用表示
- 通用模块non-local block举例子
#2022.02.14补充
- 神经网络常用的注意力机制有哪些?有什么特点与区别?神经网络中的注意力机制总结及PyTorch实战_CurryCoder的个人博客-CSDN博客_pytorch注意力机制神经网络中的注意力机制 - 知乎神经网络中的注意力机制总结及PyTorch实战_CurryCoder的个人博客-CSDN博客_pytorch注意力机制
- 注意力机制的计算可以分为两步:在所有输入信息上计算注意力分布;根据注意力分布来计算输入信息的加权平均
- 注意力模型通过允许解码器访问所有编码器产生的输出,来克服传统结构的上述两大缺点。其核心思想是对编码器的所有输出进行加权组合后输入到当前位置的解码器中来影响解码器的输出。通过对编码器的输出进行加权,在实现输入与输出的对齐的同时还能够利用更多的原始数据的上下文信息。
- 传统结构 vs 加入注意力机制的结构
- 注意力模型的分类:单注意力模型,协同注意力模型(多模态),自注意力模型(候选状态和查询状态为同一个序列)
- 常见的注意力打分函数
- 普通模式和键值模式
- 多头注意力模式
- 优化器中weight decay 与 L2 、L1正则化的关系?深度学习中的常见正则化方法(Regularization)以及优化器中的WeightDecay参数详解_张亲亲亲亲钦的博客-CSDN博客_adam优化器weight_decay
- Regularization 中文是正则化,可以理解为一种减少方差的策略。
- 泛化误差可以理解为:偏差的平方+方差+噪声
- 偏差度量了学习算法的期望预测与真实结果的偏离程度,即刻画了学习算法本身的拟合能力。
- 方差度量了同样大小的训练集的变动所导致的学习性能的变化,即刻画了数据扰动所造成的影响。
- 噪声则表达了在当前任务上学习任何算法所能达到的期望泛化误差的下界。
- 优化器的weight decay 即为L2正在化前面的朗玛达参数
- L2 正则化的作用,约束权值尽量靠近 0。
- Regularization 中文是正则化,可以理解为一种减少方差的策略。
- BN、GN、IN、LN使用区别,什么时候使用?深度学习中的五种归一化(BN、LN、IN、GN和SN)方法简介_修行之路-CSDN博客_gn是什么意思
- 为什么需要归一化:
- 神经网络学习过程的本质就是为了学习数据分布,如果我们没有做归一化处理,那么每一批次训练数据的分布不一样,从大的方向上看,神经网络则需要在这多个分布中找到平衡点,从小的方向上看,由于每层网络输入数据分布在不断变化,这也会导致每层网络在找平衡点,显然,神经网络就很难收敛了。当然,如果我们只是对输入的数据进行归一化处理(比如将输入的图像除以255,将其归到0到1之间),只能保证输入层数据分布是一样的,并不能保证每层网络输入数据分布是一样的,所以也需要在神经网络的中间层加入归一化处理。
- 训练的时候,是根据输入的每一批数据来计算均值和方差,那么测试的时候,平均值和方差是怎么来的? 对于均值来说直接计算所有训练时batch 均值的平均值;然后对于标准偏差采用每个batch 方差的无偏估计
- 示意图
- BN
- BN的计算就是把每个通道的NHW单独拿出来归一化处理
- 针对每个channel我们都有一组γ,β,所以可学习的参数为2*C
- 当batch size越小,BN的表现效果也越不好,因为计算过程中所得到的均值和方差不能代表全局
- LN
- LN的计算就是把每个CHW单独拿出来归一化处理,不受batchsize 的影响
- 常用在RNN网络,但如果输入的特征区别很大,那么就不建议使用它做归一化处理
- IN
- IN的计算就是把每个HW单独拿出来归一化处理,不受通道和batchsize 的影响
- 常用在风格化迁移,但如果特征图可以用到通道之间的相关性,那么就不建议使用它做归一化处理
- GN
- GN的计算就是把先把通道C分成G组,然后把每个gHW单独拿出来归一化处理,最后把G组归一化之后的数据合并成CHW
- GN介于LN和IN之间,当然可以说LN和IN就是GN的特列,比如G的大小为1或者为C
- Batch size 过小的时候使用GN
- Switchable Normalization
- 将 BN、LN、IN 结合,赋予权重,让网络自己去学习归一化层应该使用什么方法
- .集万千宠爱于一身,但训练复杂
- 为什么需要归一化:
- 计算密集型与访存密集型的运算有哪些?深度学习模型大小与模型推理速度的探讨_人工智能与算法学习的博客-CSDN博客
- 计算量是模型所需的计算次数,反映了模型对硬件计算单元的需求(OPs)。由于最常用的数据格式为 float32,因此也常常被写作 FLOPs (Floating Point Operations),即浮点计算次数。
- 参数量是模型中的参数的总和,跟模型在磁盘中所需的空间大小直接相关;参数量往往是被算作访存量的一部分,参数量不直接影响模型推理性能。但是参数量一方面会影响内存占用,另一方面也会影响程序初始化的时间。
- 访存量:是指模型计算时所需访问存储单元的字节大小, 反映了模型对存储单元带宽的需求,访存量一般用 Bytes(或者 KB/MB/GB)来表示,即模型计算到底需要存/取多少 Bytes 的数据。访存量对模型的推理速度至关重要,设计模型时需要予以关注。
- 内存占用是指模型运行时,所占用的内存/显存大小。一般有工程意义的是最大内存占用,当然有的场景下会使用平均内存占用。这里要注意的是,内存占用 ≠ 访存量。内存占用在论文里不常用,主要原因是其大小除了受模型本身影响外,还受软件实现的影响。有的框架为了保证推理速度,会将模型中每一个 Tensor 所需的内存都提前分配好,因此内存占用为网络所有 Tensor 大小的总和
- 计算量越小,模型推理不一定越快:模型在特定硬件上的推理速度,除了受计算量影响外,还会受访存量、硬件特性、软件实现、系统环境等诸多因素影响,呈现出复杂的特性。因此,在手头有硬件且测试方便的情况下,实测是最准确的性能评估方式。在设计网络结构时,如果有实测的条件,建议在模型迭代早期对性能也进行测试;
- 计算密度是指一个程序在单位访存量下所需的计算量,单位是 FLOPs/Byte。其计算公式很简单,很多教材、资料里也称之为计算访存比,用于反映一个程序相对于访存来说计算的密集程度。
- 根据算子的计算密度划分计算密集型与访存密集型:Conv、FC、Deconv 算子属于计算密集型算子;ReLU、EltWise Add、Concat 等属于访存密集型算子;算子的计算密度越大,越有可能提升硬件的计算效率,充分发挥硬件性能。
- 网络设计建议:
-
对于低算力平台(CPU、低端 GPU 等),模型很容易受限于硬件计算能力,因此可以采用计算量低的网络来降低推理时间。
-
对于高算力平台(GPU、DSP 等),一味降低计算量来降低推理时间就并不可取了,往往更需要关注访存量。单纯降低计算量,很容易导致网络落到硬件的访存密集区,导致推理时间与计算量不成线性关系,反而跟访存量呈强相关(而这类硬件往往内存弱于计算)。相对于低计算密度网络而言,高计算密度网络有可能因为硬件效率更高,耗时不变乃至于更短。
-
面向推理性能设计网络结构时,尽量采用经典结构,大部分框架会对这类结构进行图优化,能够有效减少计算量与访存量。例如 Conv->BN->ReLU 就会融合成一个算子,但 Conv->ReLU->BN 就无法直接融合 BN 层。
-
算子的参数尽量使用常用配置,如 Conv 尽量使用 3x3_s1/s2、1x1_s1/s2 等,软件会对这些特殊参数做特殊优化。
-
CNN 网络 channel 数尽量选择 4/8/16/32 的幂次,很多框架的很多算子实现在这样的 channel 数下效果更好(具体用多少不同平台不同框架不太一样)
-
框架除了计算耗时外,也处理网络拓扑、内存池、线程池等开销,这些开销跟网络层数成正比。因此相比于“大而浅”的网络,“小而深”的网络这部分开销更大。一般情况下这部分开销占比不大。但在网络算子非常碎、层数非常多的时候,这部分开销有可能会影响多线程的扩展性,乃至于成为不可忽视的耗时因素。
-
除了优化网络结构、推理框架性能外,还可以考虑通过一些其他工程技巧来提升系统整体的性能。例如:对推理服务流水化,并行数据读取与计算的过程,掩盖 IO 延时。
-
#2022.01.22 补充
- 卷积计算与感受野的计算
- 感受野:高层的特征图中的像素点受原图多大区域的影响,卷积神经网络中每层的特征图(Feature Map)上的像素点在原始图像中映射的区域大小。
- 在目标检测任务中,我们一般在高层的feature map上检测大物体,在底层的feature map上检测小物体。
- 卷积计算公式:
- 不带空洞卷积
- 带有空洞卷积
- 不带空洞卷积
- 感受野的计算
- 普通卷积感受野的计算:与每个layer的stride和kernelsize有关,与padding没有关系,感受野只是表示两者的映射关系,与原始图的大小无关
上层是在低语义feature map特征,下层是指高语义feature map特征 - 带有空洞的卷积的感受野计算:所以空洞卷积可以增加增加感受野
- 普通卷积感受野的计算:与每个layer的stride和kernelsize有关,与padding没有关系,感受野只是表示两者的映射关系,与原始图的大小无关
- LRN/BN/LN/IN/GN的区别与作用,手写BN公式,并推到梯度反传【10】深度学习中的五种归一化(BN、LN、IN、GN和SN)_sdw8855的博客-CSDN博客
- 神经网络学习过程的本质就是为了学习数据分布,一旦训练数据与测试数据的分布不同,那么网络的泛化能力也大大降低;另外一方面,一旦每批训练数据的分布各不相同(batch 梯度下降),那么网络就要在每次迭代都去学习适应不同的分布,这样将会大大降低网络的训练速度。
如果我们没有做归一化处理,那么每一批次训练数据的分布不一样,从大的方向看,神经网络则需要在这多个分布中找到平衡点,从小的方向上看,由于每层网络输入数据分布在不断变化,这也会导致每层网络在找平衡点,显然,神经网络就很难收敛了。当然,如果我们只是对输入的数据进行归一化处理(比如将输入的图像除以255,将其归到0到1之间),只能保证输入层数据分布是一样的,并不能保证每层网络输入数据分布是一样的,所以也需要在神经网络的中间层加入归一化处理。
归一化作用:- 加速网络收敛速度,可以使用较大的学习率来训练网络
- 改善梯度弥散
- 提高网络的泛化能力
- BN层一般用在线性层和卷积层后面,而不是放在非线性单元后
- LRN:不存在学习的参数,所以不需要反向传播的参数迭代。LRN的创意来源于神经生物学的侧抑制,被激活的神经元会抑制相邻的神经元。用一句话来形容LRN:让响应值大的feature map变得更大,让响应值小的变得更小;主要思想在于让不同卷积核产生feature map之间的相关性更小,以实现不同通道上的feature map专注于不同的特征的作用,例如A特征在一通道上更显著,B特征在另一通道上更显著。
BN/LN/IN/GN有学习参数,来增强模型的非线性能力,因为通过单纯的normalization后,模型的值会集中在0~1之间,而通过可以提升模型的表示能力、 - 训练计算每个batch size的均值方差,而测试的时候使用训练时记录的无偏估计来代替
- BN/LN/IN/GN 关系图:归一化处理到均值为0,方差为1
BN受batch size影响较大
LN:常用在RNN网络,但如果输入的特征区别很大,那么就不建议使用它做归一化处理
IN:常用于风格迁移,但如果特征图可以用到通道之间的相关性,那么就不建议使用它做归一化处理 - SN(Switchable Normalization):将 BN、LN、IN 结合,赋予权重,让网络自己去学习归一化层应该使用什么方法,自动为神经网络的每个归一化层确定一个合适的归一化操作,但训练复杂。
- 神经网络学习过程的本质就是为了学习数据分布,一旦训练数据与测试数据的分布不同,那么网络的泛化能力也大大降低;另外一方面,一旦每批训练数据的分布各不相同(batch 梯度下降),那么网络就要在每次迭代都去学习适应不同的分布,这样将会大大降低网络的训练速度。
- 不同激活函数的特点【14】
- 不同池化操作的区别一文看尽深度学习中的各种池化方法! - 知乎
- 执行降采样:从H,W降低特征维度,避免计算量过大与或者参数过多带来过拟合。
- 保持平移不变性,即使图像有了几个像素的位移情况下,依然可以获得稳定的特征组合,平移不变形对于识别十分重要。
- 提高feature map的感受野
- 优点:
- 增大网络感受野
- 抑制噪声,降低信息冗余
- 降低模型计算量,降低网络优化难度,防止网络过拟合
- 使模型对输入图像中的特征位置变化更加鲁棒;【平移不变】
- 可以在保留更多空间细节信息的同时提取到更具有判别力的抽象特征;
- 池化种类
- 最大池化:方式摒弃了网络中大量的冗余信息,使得网络更容易被优化。同时这种操作方式也常常丢失了一些特征图中的细节信息,所以最大池化更多保留些图像的纹理信息
- 平均池化:可以提取特征图中所有特征的信息进入下一层,可以保留图像【feature map】的背景信息
- 全局平均池化:取代最后的全连接层,用很小的计算代价实现了降维,更重要的是GAP极大减少了网络参数(CNN网络中全连接层占据了很大的参数);GAP【全局平均池化】对整个网络在结构上做正则化防止过拟合;使用GAP代替全连接层,可以实现任意图像大小的输入,而GAP对整个特征图求平均值,也可以用来提取全局上下文信息,全局信息作为指导进一步增强网络性能
- 混合池化(mix pooling):在模型训练期间随机采用了最大池化和平均池化方法,并在一定程度上有助于防止网络过拟合现象。
混合池化优于传统的最大池化和平均池化方法,并可以解决过拟合问题来提高分类精度。此外该方法所需要的计算开销可忽略不计,而无需任何超参数进行调整,可被广泛运用于CNN - 随机池化(Stochastic Pooling):随机池化只需对特征图中的元素按照其概率值大小随机选择,即元素值大的被选中的概率也大,而不像max-pooling那样,永远只取那个最大值元素,这使得随机池化具有更强的泛化能力
- 先将方格中的元素同时除以它们的和sum,得到概率矩阵。
- 按照概率随机选中方格。
- pooling得到的值就是方格位置的值。
- 推理过程也很简单,对矩阵区域求加权平均即可
-
Power Average Pooling(幂平均池化)
-
Detail-Preserving Pooling(DPP池化):由于池化本质上是一个有损的过程,所以每个这样的层都必须保留对网络可判别性最重要的部分进行激活 ;DPP一种自适应池化方法,该池化可以放大空间变化并保留重要的图像结构细节,且其内部的参数可通过反向传播加以学习
DPP池化允许缩减规模以专注于重要的结构细节,可学习的参数控制着细节的保存量,此外,由于细节保存和规范化相互补充,DPP可以与随机合并方法结合使用,以进一步提高准确率 -
Local Importance Pooling(局部重要性池化)
从局部重要性的角度提出了局部重要性池化Local Importance Pooling
首先在原特征图上学习一个类似于注意力的特征图,然后再和原特征图进行加权求均值
Local Importance Pooling可以学习自适应和可判别性的特征图以汇总下采样特征,同时丢弃无信息特征。这种池化机制能极大保留物体大部分细节,对于一些细节信息异常丰富的任务至关重要。 -
Soft Pooling(软池化)
现有的一些池化方法大都基于最大池化和平均池化的不同组合,而软池化Soft Pooling[9]是基于softmax加权的方法来保留输入的基本属性,同时放大更大强度的特征激活。与maxpooling不同,softpool是可微的,所以网络在反向传播过程中为每个输入获得一个梯度,这有利于提高训练效果。
SoftPool的计算流程如下:
a. 特征图透过滑动视窗来框选局部数值
b. 框选的局部数值会先经过指数计算,计算出的值为对应的特征数值的权重
c. 将各自的特征数值与其相对应的权重相乘
d. 最后进行加总
这样的方式让整体的局部数值都有所贡献,重要的特征占有较高的权重。比Max pooling(直接选择最大值)、Average pooling (求平均,降低整个局部的特征强度) 能够保留更多讯息。
SoftPool可以在保持池化层功能的同时尽可能减少池化过程中带来的信息损失,更好地保留信息特征并因此改善CNN中的分类性能
- 常用损失函数,softmax 交错熵损失函数的梯度反向传导
概述:损失函数分为经验风险损失函数和结构风险损失函数;结构风险损失函数是指经验风险损失函数加上正则项- 0-1损失函数【分类损失】
- 绝对损失函数:L1损失函数【回归任务】
smooth-L1函数:第5条 Huber Loss 函数的特例,分界值为1 - 对数损失函数
- 平方损失函数:对异常点不够鲁棒,会施加较大惩罚;如果异常点交错可以考虑绝对损失,但是绝对损失不可导,不容易优化。【回归任务】
- Huber 损失是对两者的综合:当损失较大时使用绝对损失函数;当损失较小时使用平方损失函数。【回归问题】
平方损失、绝对损失、huber损失 - 逻辑损失函数【logistic Loss为Logistic Regression中使用的损失函数,下面做一下简单证明:
逻辑损失函数与交叉熵【二分类】损失函数是等价的,只是对标签y的定义不同,前者是-1/1,后者是0, 1; - hingle loss 为svm中使用的损失函数
- 指数损失函数
- modified huber loss
- 分类损失函数对比
- 交叉熵函数与最大似然函数的区别
区别:交叉熵函数使用来描述模型预测值和真实值的差距大小,越大代表越不相近;似然函数的本质就是衡量在某个参数下,整体的估计和真实的情况一样的概率,越大代表越相近。
联系:交叉熵函数可以由最大似然函数在伯努利分布的条件下推导出来,或者说最小化交叉熵函数的本质就是对数似然函数的最大化。
推到过程:常见的损失函数(loss function)总结 - 知乎
- rank loss 排序损失函数:在很多不同的领域任务和神经网络结构(比如siamese net或者Triplet net)中被广泛地应用;其广泛应用但缺乏对其命名标准化导致了其拥有很多其他别名,比如对比损失Contrastive loss,边缘损失Margin loss,铰链损失hinge loss和我们常见的三元组损失Triplet loss等。一文理解Ranking Loss/Contrastive Loss/Margin Loss/Triplet Loss/Hinge Loss_机器学习杂货铺1号店-CSDN博客
ranking loss的目的是去预测输入样本之间的相对距离。这个任务经常也被称之为度量学习(metric learning)- 成对样本的rank loss
CNN的权重值是共享的,称之为Siamese Net;
对于正样本对来说,这个loss随着样本对输入到网络生成的表征之间的距离的减小而减少,增大而增大,直至变成0为止。
对于负样本来说,这个loss只有在所有负样本对的元素之间的表征的距离都大于阈值m mm的时候才能变成0。当实际负样本对的距离小于阈值的时候,这个loss就是个正值,因此网络的参数能够继续更新优化,以便产生更适合的表征。这个项的loss最大值不会超过m mm,在d ( r a , r n ) = 0 \mathrm{d}(r_a,r_n)=0d(ra,rn)=0的时候取得。这里设置阈值的目的是,当某个负样本对中的表征足够好,体现在其距离足够远的时候,就没有必要在该负样本对中浪费时间去增大这个距离了,因此进一步的训练将会关注在其他更加难分别的样本对中。 - 三元组的rank loss Triplet loss
负样本的挑选:- 一个明显的策略就是:简单的三元组应该尽可能被避免采样到,因为其loss为0,对优化并没有任何帮助
- 第一个可供选择的策略是离线三元组采集(offline triplet mining),这意味着在训练的一开始或者是在每个世代(epoch)之前,就得对每个三元组进行定义(也即是采样)。第二种策略是在线三元组采集(online triplet mining),这种方案意味着在训练中的每个批次(batch)中,都得对三元组进行动态地采样,这种方法经常具有更高的效率和更好的表现。
- 成对样本的rank loss
- emd[Earth Mover's Distance] loss 地球移动距离;EMD:提出的一种直方图相似度量图像检索中的相似度度量:EMD距离(Earth Mover's Distance)_不眠旅行-CSDN博客_emd距离
class EMDLoss(torch.nn.Module): def __init__(self): super(EMDLoss, self).__init__() def forward(self, p_estimate: torch.Tensor, p_target: torch.Tensor): assert p_target.shape == p_estimate.shape # cdf for values [1, 2, ..., 10] cdf_target = torch.cumsum(p_target, dim=1) # cdf for values [1, 2, ..., 10] cdf_estimate = torch.cumsum(p_estimate, dim=1) cdf_diff = cdf_estimate - cdf_target # samplewise_emd = torch.sqrt(torch.mean(torch.pow(torch.abs(cdf_diff), 2))) samplewise_emd = torch.sqrt(torch.mean(torch.pow(torch.abs(cdf_diff), 2), -1)) # print(samplewise_emd) return samplewise_emd.mean()
- norm-in-norm loss(mos质量分)
- GAN Loss
- 超分损失函数:超分损失函数小结 - 江南烟雨尘 - 博客园
- 0-1损失函数【分类损失】
- 网络常见初始化方法 权重/参数初始化 - 知乎
参数初始化:深度学习模型训练过程的本质是对weight(即参数 W)进行更新,神经网络其实就是对权重参数w不停地迭代更新,以达到较好的性能。好的初始化参数能够加速收敛,并且更可能找到较优解。权重初始化的目的是防止在深度神经网络的正向(前向)传播过程中层激活函数的输出损失梯度出现爆炸或消失- 全零初始化:网络对称性没法打破
- 随机初始化:输出数据分布的方差随着输入神经元的个数以及参数初始化方法的改变而改变,是的网络输入与输出不是同分布,出现学习的振荡不容易收敛;此外,以单纯感感知机为例,如果初始化参数的方差大于1,后续层网络输出的方差将激增出现梯度爆炸现象;如果较小优化出现梯度消息现象;所以权重初始值太大或者太小,网络都将无法很好地进行学习。
- Xavier初始化:可以帮助减少梯度消失的问题,使得信号在神经网络中可以传递得更深,在经过多层神经元后保持在合理的范围(不至于太小或太大)
- 基本思想:保持输入和输出的方差一致(服从相同的分布),这样就避免了所有输出值都趋向于0
- 初始化方法:
- Xavier初始化主要用于tanh,不适用于ReLU
- He initialization(MSRA)
- Batch Normalization Layer + 随机初始化:在广泛采用 Batch Normalization 的情况下,使用普通的小方差的高斯分布即可。
- pre-training (“锅甩给别人,机智地一匹” ):先使用greedy layerwise auto-encoder做unsupervised pre-training,然后再做fine-tuning
- pre-training阶段:将神经网络中的每一层取出,构造一个auto-encoder做训练,使得输入层和输出层保持一致。在这一过程中,参数得以更新,形成初始值。
- fine-tuning阶段:将pre-train过的每一层放回神经网络,利用pre-train阶段得到的参数初始值和训练数据对模型进行整体调整。在这一过程中,参数进一步被更新,形成最终模型。
- 随着数据量的增加以及activation function 的发展,pre-training的概念已经渐渐发生变化。目前,从零开始训练神经网络时我们也很少采用auto-encoder进行pre-training,而是直奔主题做模型训练。如果不想从零开始训练神经网络时,我们往往选择一个已经在任务A上训练好的模型(称为pre-trained model),将其放在任务B上做模型调整(称为fine-tuning)。
- 常见优化器的区别【18】
1.反卷积(deconv)与转置卷积(transposed conv)是同一种卷积形式,对图像的上采样,卷积的逆过程
输入输出可以通过正常卷积输入输出关系反推:
规范表达:
DL中的deconv,是一种上采样过程;卷积的输入input 通过卷积得到输出output, 而从output到input就是反卷积。反卷积等于将卷积的卷积核水平翻转再垂直翻转得到的卷积核作用于卷积的操作的ouput上,得到卷积操作的input。
2.L1 与L2 损失,以及其正则化
L0损失定义为:向量中非零元素的个数,常常用于压缩感知,压缩传感计划试图找到欠定线性系统(under-determinedlinear system)最稀疏的解(sparsest solution)。最稀疏的解意味着解有最少的非零元素。
L1 损失:
L2损失(欧几里得范数):
作为损失函数: 用 L2 一定只有一条最好的预测线,L1 则因为其性质可能存在多个最优解;L1鲁棒性 (Robust) 更强,对异常值更不敏感。
作为正则项:
L1 最重要的一个特点,输出稀疏,会把不重要的特征直接置零,而 L2 则不会;L1一个天然的特征选择器;L2 有唯一解,而 L1 不是
为什么输出稀疏特征??
3.常用模型压缩方法
模型压缩的方法:对模型预测精度无明显影响,压缩模型的参数数量,深度来降低模型空间的复杂度,不显著提高训练时间复杂度,降低预测时间的复杂度。
(1)更精细的模型设计
- 将3x3卷积核替换为1x1卷积核(1个1x1卷积核的参数是3x3卷积核参数的1/9,这一改动理论上可以将模型尺寸压缩9倍)。
- 减小输入到3x3卷积核的输入通道数
- 尽可能的将降采样放在网络后面的层中
- 借鉴ResNet思想,对原始网络结构做了修改,增加了旁路分支,将分类精度提升了约3%。
- 借鉴mobileNet的思想(借鉴factorized convolution的思想),将普通卷积操作分成两部分:深度卷积(每个卷积核滤波器只针对特定的输入通道进行卷积操作)和逐点卷积(采用1x1大小的卷积核将depthwise convolution层的多通道输出进行结合)
- shuffleNet :基于MobileNet的group思想,将卷积操作限制到特定的输入通道。而与之不同的是,ShuffleNet将输入的group进行打散,从而保证每个卷积核的感受野能够分散到不同group的输入中,增加了模型的学习能力。
(2)模型的裁剪(剪枝)
挑选出模型中不重要的参数,将其剔除而不会对模型的效果造成太大的影响。在剔除不重要的参数之后,通过一个retrain的过程来恢复模型的性能。如何找到一个有效的对参数重要性的评价手段;基于模型裁剪的方法是最为简单有效的模型压缩方式
a)单个权重剪枝(非结构化):定义:任意权重被看作是单个参数并进行随机非结构化剪枝。
b)核内权重剪枝(核稀疏化)(结构化):对权重的更新加以正则项进行限制,使其更加稀疏,使大部分的权值都为0。
c)卷积核/特征图/通道剪枝(结构化):减去第i层的filter,进而减去第i层产生的部分特征图和第i+1层的部分kernel。
d)中间隐层剪枝:删除一些层,即改变网络结构
(3)网络分解(zhang laing)(张量分解)
方法:a)将三维张量铺展成二维张量,使用标准SVD;b)使用多个一维张量外积求和逼近
通常基于张量的低秩近似理论和方法,将原始的权重张量分解为两个或者多个张量,并对分解张量进行优化调整;
优缺点:
低秩方法很适合模型压缩和加速。
低秩方法的实现并不容易,因为它涉及计算成本高昂的分解操作。
目前的方法逐层执行低秩近似,无法执行非常重要的全局参数压缩,因为不同的层具备不同的信息。
分解需要大量的重新训练来达到收敛。
(4)权值共享
1)结构化矩阵:如果一个 m x n 阶矩阵只需要少于 m×n 个参数来描述,就是一个结构化矩阵。通常这样的结构不仅能减少内存消耗,还能通过快速的矩阵-向量乘法和梯度计算显著加快推理和训练的速度。
2)哈希:将参数映射到相应的哈希桶内,在同一个哈希桶内的参数则共享同一值。
(5)权重量化
思想:通过减少表示每个权重所需的比特数来压缩原始网络。
(6)迁移学习/网络精馏
迁移学习:将一个模型的性能迁移到另一个模型上
网络精馏:在同一个域上迁移学习的一种特例
核心思想是通过迁移知识,从而通过训练好的大模型得到更加适合推理的小模型。大模型学习到的函数压缩进更小更快的模型,而获得可以匹敌大模型结果的方法
(7)计算加速
(8)对数据进行转换
4.softmax 的公式以及反向传递
自己手推
5.mobileNet :深度可分离卷积,shuffleNet
MobileNets:
为移动和嵌入式设备提出的高效模型,MobileNets基于流线型架构(streamlined),使用深度可分离卷积(depthwise separable convolutions,即Xception变体结构)来构建轻量级深度神经网络。
MobileNet描述了一个高效的网络架构,允许通过两个超参数直接构建非常小、低延迟、易满足嵌入式设备要求的模型。
现阶段在建立小型高效的神经网络工作:
(1)压缩预训练模型。获得小型网络的一个办法是减小、分解或压缩预训练网络,例如量化压缩(product quantization)、哈希(hashing )、剪枝(pruning)、矢量编码( vector quantization)和霍夫曼编码(Huffman coding)等;此外还有各种分解因子(various factorizations )用来加速预训练网络;一种训练小型网络的方法叫蒸馏(distillation ),使用大型网络指导小型网络;
(2)直接训练小模型:Flattened networks利用完全的因式分解的卷积网络构建模型,显示出完全分解网络的潜力;Factorized Networks引入了类似的分解卷积以及拓扑连接的使用。
Depthwise Separable Convolution
MobileNet是基于深度可分离卷积的, 深度可分离卷积干的活是:把标准卷积分解成深度卷积(depthwise convolution)和逐点卷积(pointwise convolution)。这么做的好处是可以大幅度降低参数量和计算量;这么做的好处是可以大幅度降低参数量和计算量;
轻量级网络--MobileNet论文解读_DFan的NoteBook-CSDN博客_mobilenet论文:深度卷积和逐点卷积的推导;深度卷积负责滤波作用, 逐点卷积负责转换通道;如果是需要下采样,则在第一个深度卷积上取步长为2.;MobileNet模型几乎将所有的密集运算放到1×1 卷积上,这可以使用general matrix multiply (GEMM) functions优化。在MobileNet中有95%的时间花费在1×1 1×11×1卷积上,这部分也占了75%的参数:剩余的其他参数几乎都在FC层上了。
论文提出了一种基于深度可分离卷积的新模型MobileNet,同时提出了两个超参数用于快速调节模型适配到特定环境。实验部分将MobileNet与许多先进模型做对比,展现出MobileNet的在尺寸、计算量、速度上的优越性。宽度因子α \alphaα(Width multiplier )
分辨率因子ρ \rhoρ(resolution multiplier ).
shuffleNet:ShuffleNet算法详解_AI之路-CSDN博客_shufflenet
轻量级网络--ShuffleNet论文解读_DFan的NoteBook-CSDN博客_shufflenet论文
一个效率极高的CNN架构ShuffleNet,专门应用于计算力受限的移动设备。新的架构利用两个操作:逐点群卷积(pointwise group convolution)和通道混洗(channel shuffle);该文章主要采用channel shuffle、pointwise group convolutions和depthwise separable convolution来修改原来的ResNet单元,接下来依次讲解。
ShuffleNet的核心就是用pointwise group convolution,channel shuffle和depthwise separable convolution代替ResNet block的相应层构成了ShuffleNet uint,达到了减少计算量和提高准确率的目的。channel shuffle解决了多个group convolution叠加出现的边界效应,pointwise group convolution和depthwise separable convolution主要减少了计算量。
6.python 的多进程与多线程(进程和现成的区别)
进程:是系统进行资源分配和运行调用的独立单位。可以简单地理解为操作系统中正在执行的程序,每个应用程序都有一个自己的进程。
每一个进程启动时都会最先产生一个线程,即主线程。然后主线程会再创建其他的子线程。
线程:线程是一个基本的 CPU 执行单元。它必须依托于进程存活。一个线程是一个execution context(执行上下文),即一个 CPU 执行时所需要的一串指令;
进程和线程的区别:
- 线程必须在某个进行中执行。
- 一个进程可包含多个线程,其中有且只有一个主线程。
- 多线程共享同个地址空间、打开的文件以及其他资源。
- 多进程共享物理内存、磁盘、打印机以及其他资源。
线程主要可以划分为:主线程,子线程,后台线程(守护线程),前台线程
Python的多线程:其他语言,CPU 是多核时是支持多个线程同时执行。但在 Python 中,无论是单核还是多核,同时只能由一个线程在执行。其根源是 GIL 的存在。
GIL 的全称是 Global Interpreter Lock(全局解释器锁),来源是 Python 设计之初的考虑,为了数据安全所做的决定。某个线程想要执行,必须先拿到 GIL,我们可以把 GIL 看作是“通行证”,并且在一个 Python 进程中,GIL 只有一个。拿不到通行证的线程,就不允许进入 CPU 执行。
GIL 只在 CPython 中才有,而在 PyPy 和 Jython 中是没有 GIL 的。每次释放 GIL锁,线程进行锁竞争、切换线程,会消耗资源。这就导致打印线程执行时长,会发现耗时更长的原因。
Python提供两个模块进行多线程的操作,分别是thread
和threading
,前者是比较低级的模块,用于更底层的操作,一般应用级别的开发不常用。
Python 要进行多进程操作,需要用到muiltprocessing
库,其中的Process
类跟threading
模块的Thread
类很相似。所以直接看代码熟悉多进程。进程之间不共享数据的。如果进程之间需要进行通信,则要用到Queue模块
或者Pipi模块
来实现。
-
CPU 密集型:程序比较偏重于计算,需要经常使用 CPU 来运算。例如科学计算的程序,机器学习的程序等。
-
I/O 密集型:顾名思义就是程序需要频繁进行输入输出操作。爬虫程序就是典型的 I/O 密集型程序。
如果程序是属于 CPU 密集型,建议使用多进程。而多线程就更适合应用于 I/O 密集型程序。
7.手写Resnet的跳转连接(pytorch),以类的形式封装好,后续别的网络模块可直接调用
已手写
8.CNN梯度的反向传播
推荐:CNN中的梯度的求法和反向传播过程_haolexiao的专栏-CSDN博客_cnn 梯度
9.怎么选择卷积核的大小,以及怎么选择全连接层神经元的个数
怎么选择卷积核的大小:卷积神经网络的卷积核大小、卷积层数、每层map个数都是如何确定下来的呢? - 知乎
怎么选择全联接层神经元的个数:
10. BN的反向传递,BN为什么会加入缩放量和偏移量
手推反向传递:已经手推:笔记: Batch Normalization及其反向传播 - 知乎
python 代码实现:BN(多种角度),IN,LN,GN 的原理,公式,以及反向传播的推倒及代码_justsolow的博客-CSDN博客_bn层反向传播过程
###BN 的实现 python
def batchnorm_froward(x, gamma, beta, bn_param):
"""
Input:
- x: (N, D)维输入数据
- gamma: (D,)维尺度变化参数
- beta: (D,)维尺度变化参数
- bn_param: Dictionary with the following keys:
- mode: 'train' 或者 'test'
- eps: 一般取1e-8~1e-4
- momentum: 计算均值、方差的更新参数
- running_mean: (D,)动态变化array存储训练集的均值
- running_var:(D,)动态变化array存储训练集的方差
Returns a tuple of:
- out: 输出y_i(N,D)维
- cache: 存储反向传播所需数据
"""
mode = bn_param['mode']
eps = bn_param.get('eps', 1e-5)
momentum = bn_param.get('momentum', 0.9)
N,D = x.shape
running_mean = bn_param.get('running_mean', np.zeros(D, dtype=x.dtype))
running_var = bn_param.get('running_var', np.zeros(D, dtype=x.dtype))
out,cache = None, None
if mode == 'train':
samples_mean = np.mean(x, axis=0)
samples_var = np.var(x, axis=0)
x_hat = (x - samples_mean) / np.sqart((samples_var + eps))
out = gamma * x_hat + beta
cache = (x, gamma, beta, x_hat, samples_mean, samples_var, eps)
running_mean = momentum * running_mean + (1 - momentum) * samples_mean
running_var = momentum * running_var + (1 - momentum) * sample_var
elif mode == 'test':
x_hat = (x - running_mean) / np.sqart((running_var + eps))
out = gamma * x_hat + beta
else:
raise ValueError('Invalid forward batchnorm mode "%s"' % mode)
bn_param['running_mean'] = running_mean
bn_param['running_var'] = running_var
return out, cache
def batchnorm_backward(dout, cache):
"""
Inputs:
- dout: 上一层的梯度,维度(N, D),即 dL/dy
- cache: 所需的中间变量,来自于前向传播
Returns a tuple of:
- dx: (N, D)维的 dL/dx
- dgamma: (D,)维的dL/dgamma
- dbeta: (D,)维的dL/dbeta
"""
x, gamma, beta, x_hat, sample_mean, sample_var, eps = cache
N = x.shape[0]
dgamma = np.sum(dout * x_hat, axis = 0)
dbeta = np.sum(dout, axis = 0)
dx_hat = dout * gamma
dsigma = -0.5 * np.sum(dx_hat * (x - sample_mean), axis=0) * np.power(sample_var + eps, -1.5)
dmu = -np.sum(dx_hat / np.sqrt(sample_var + eps), axis=0) - 2 * dsigma*np.sum(x-sample_mean, axis=0)/ N
dx = dx_hat /np.sqrt(sample_var + eps) + 2.0 * dsigma * (x - sample_mean) / N + dmu / N
return dx, dgamma, dbeta
背景:
Internal Covariate Shift:统计学习中的一个很重要的假设就是输入的分布是相对稳定的;在深度神经网络中变得更加难以解决。在神经网络中,网络是分层的,可以把每一层视为一个单独的分类器,将一个网络看成分类器的串联。这就意味着,在训练过程中,随着某一层分类器的参数的改变,其输出的分布也会改变,这就导致下一层的输入的分布不稳定。分类器需要不断适应新的分布,这就使得模型难以收敛。
对数据的预处理可以解决第一层的输入分布问题,而对于隐藏层的问题无能为力,这个问题就是Internal Covariate Shift。 而Batch Normalization其实主要就是在解决这个问题。
一般的神经网络的梯度大小往往会与参数的大小相关(仿射变换),且随着训练的过程,会产生较大的波动,这就导致学习率不宜设置的太大。Batch Normalization使得梯度大小相对固定,一定程度上允许我们使用更高的学习率。
BN层的主要功能总结为两点:
1)归一化scale
没有BN层时,若LR设置较大,在配合ReLU激活函数时,容易出现Dead ReLU问题。
2)数据初始化集中,缓解overfitting(这里还理解得不是很透彻)
Overfitting主要发生在一些较远的便捷点【离群点】,BN操作可以使初始化数据在数据内部。
3)激活sigmoid和RELU激活函数
通常提到BN层,我们会想到,若使用sigmoid激活函数时,它可以将数据归一化到梯度较大的区域,便于梯度更新。在BN中的gamma对于ReLU的影响很小,因为数值的收缩,不会影响是否大于0。但是如果没有偏移量beta,就会出现数据分布在以0为中心的位置,强行将一半的神经元输出置零。因此偏移量beta是必不可少的。
引入gamma和beta两个参数是为了避免数据只用sigmoid的线性部分;如果不使用gamma和beta,激活值基本上会在[0.1 0.9]这个近似线性的区域中;这与深度神经网络所要求的“多层非线性函数逼近任意函数”的要求不符,所以引入gamma和beta还是有必要的,深度网络会自动决定使用哪一段函数。
BN的算法优势:
(1) 可以使用更高的学习率。如果每层的scale不一致,实际上每层需要的学习率是不一样的,同一层不同维度的scale往往也需要不同大小的学习率,通常需要使用最小的那个学习率才能保证损失函数有效下降,Batch Normalization将每层、每维的scale保持一致,那么我们就可以直接使用较高的学习率进行优化。
(2) 移除或使用较低的dropout。 dropout是常用的防止overfitting的方法,而导致overfit的位置往往在数据边界处,如果初始化权重就已经落在数据内部,overfit现象就可以得到一定的缓解。论文中最后的模型分别使用10%、5%和0%的dropout训练模型,与之前的40%-50%相比,可以大大提高训练速度。
(3) 降低L2权重衰减系数(减少对L1和L2正则化的依赖)。 还是一样的问题,边界处的局部最优往往有几维的权重(斜率)较大,使用L2衰减可以缓解这一问题,现在用了Batch Normalization,就可以把这个值降低了,论文中降低为原来的5倍。
(4) 取消Local Response Normalization层。 由于使用了一种Normalization,再使用LRN就显得没那么必要了。而且LRN实际上也没那么work。
(5) 减少图像扭曲【增强】的使用。 由于现在训练epoch数降低,所以要对输入数据少做一些扭曲,让神经网络多看看真实的数据。
还包括对BN的求导
推荐:深度学习通用策略:BN原理详解以及优势_BigCowPeking-CSDN博客_bn 深度学习
11. inception, squeezeNet网络结构
inception:https://blog.csdn.net/u010402786/article/details/52433324/
神经网络更深(层数),更宽(神经元个数)的缺点:
1.参数太多,容易过拟合,若训练数据集有限;
2.网络越大计算复杂度越大,难以应用;
3.网络越深,梯度越往后穿越容易消失(梯度弥散),难以优化模型
为了解决这样的问题当然是增加网络深度和宽度的同时,减少参数量
inception v1:
在3x3前,5x5前,max pooling后分别加上了1x1的卷积核起到了降低特征图厚度的作用,减少计算量。
inception V2:
加入了BN层,减少了Internal Covariate Shift(内部neuron的数据分布发生变化),使每一层的输出都规范化到一个N(0, 1)的高斯;
另外一方面学习VGG用2个3x3的conv替代inception模块中的5x5,既降低了参数数量,也加速计算 。
inception v3:
v3一个最重要的改进是分解(Factorization),将7x7分解成两个一维的卷积(1x7,7x1),3x3也是一样(1x3,3x1),这样的好处,既可以加速计算(多余的计算能力可以用来加深网络),又可以将1个conv拆成2个conv,使得网络深度进一步增加,增加了网络的非线性,还有值得注意的地方是网络输入从224x224变为了299x299,更加精细设计了35x35/17x17/8x8的模块。
使用3×3的已经很小了,那么更小的2×2呢?2×2虽然能使得参数进一步降低,但是不如另一种方式更加有效,那就是Asymmetric方式,即使用1×3和3×1两种来代替3×3的卷积核。这种结构在前几层效果不太好,但对特征图大小为12~20的中间层效果明显。
inception v4:
v4研究了Inception模块结合Residual Connection能不能有改进?发现ResNet的结构可以极大地加速训练,同时性能也有提升,得到一个Inception-ResNet v2网络,同时还设计了一个更深更优化的Inception v4模型,能达到与Inception-ResNet v2相媲美的性能。
Squeeze and Excitation Net(SENet):https://blog.csdn.net/wangkun1340378/article/details/79092001
Squeeze(挤压) 和 Excitation(激励) 是两个非常关键的操作;希望显式地建模特征通道之间的相互依赖关系;我们并不打算引入一个新的空间维度来进行特征通道间的融合,而是采用了一种全新的「特征重标定」策略。通过学习的方式来自动获取到每个特征通道的重要程度,然后依照这个重要程度去提升有用的特征并抑制对当前任务用处不大的特征;
首先是 Squeeze 操作,我们顺着空间维度来进行特征压缩,将每个二维的特征通道变成一个实数,这个实数某种程度上具有全局的感受野,并且输出的维度和输入的特征通道数相匹配。它表征着在特征通道上响应的全局分布,而且使得靠近输入的层也可以获得全局的感受野,这一点在很多任务中都是非常有用的。
其次是 Excitation 操作,它是一个类似于循环神经网络中门的机制。通过参数 w 来为每个特征通道生成权重,其中参数 w 被学习用来显式地建模特征通道间的相关性。
最后是一个 Reweight 的操作,我们将 Excitation 的输出的权重看做是进过特征选择后的每个特征通道的重要性,然后通过乘法逐通道加权到先前的特征上,完成在通道维度上的对原始特征的重标定。
12.可变形卷积网络--Deformable Convolutional Networks
参考博客:可变形卷积网络--Deformable Convolutional Networks_AI小作坊 的博客-CSDN博客
本文可以看做是对 Spatial Transformer Networks 工作的深入,通过 deformable convolution 和 deformable RoI pooling提升当前CNN网络的空间信息建模能力。Spatial Transformer Networks建立的是 global、sparse transformation ,本文的Deformable Convolutional Networks建立的是 local and dense transformation。
上图显示可变形卷积可以提高模型对 scale, aspect ratio and rotation 等映射的泛化能力。这个偏移量是可以通过学习得到,并不需要额外的监督。因为是对网络内部结构进行了改进。因此新的module可以应用在很多vision tasks上,本文拿segmentation和detection进行举例。
卷积该具体怎么deformable,这个可以通过一个卷积层来学习;对于输入的一张feature map,假设原来的卷积操作是3*3的,那么为了学习offset,我们定义另外一个3*3的卷积层,输出的offset field其实就是原来feature map大小,channel数等于2*3*3=18(分别表示后面feature map上某点对应前一张feature map上9个采样点的x,y方向的偏移)。这样的话,有了输入的feature map,有了和feature map一样大小的offset field,我们就可以进行deformable卷积运算。所有的参数都可以通过反向传播学习得到。
deformable RoI pooling这个 offsets 通过一个全链接层学习 ;offset通常不是整数,因此我们需要用双线性插值的方法确定偏移之后的采样点的值;假设对于一个ROI,需要pooling成spatial size为3*3大小。为了获得3*3个bin对应的offset,首先正常roi pooling一下,然后接上一个全连接层学习这9个offset,然后再reshape。所有的参数也是可以学习得到的。
比较同类方法:可以用几何变换增强数据集,或者设计一些transformation invariant的描述子。这些方法都是建立在我们已经知道数据集里面存在哪些几何变换的基础上,对于未知的变换无法适应。
为什么提出可变形卷积网络?
同一层的激活单元的感受野是一样大的,这对于目标检测来说就是不太合理的,因为不同位置对应的目标大小是不一样的。如果能够使得感受野在不同位置的大小进行自适应调整,那么对于目标检测语义分割等等任务的帮助必然很大。
13.常用的数据增强方法有哪些?
为什么要进行数据增强:
比较成功的神经网络需要大量的参数,许许多多的神经网路的参数都是数以百万计,而使得这些参数可以正确工作则需要大量的数据进行训练,而实际情况中数据并没有我们想象中的那么多
数据增强的作用:
- 增加训练的数据量,提高模型的泛化能力
- 增加噪声数据,提升模型的鲁棒性
数据增强的分类:
数据增强可以分为两类,一类是离线增强,一类是在线增强
离线增强 : 直接对数据集进行处理,数据的数目会变成增强因子 x 原数据集的数目 ,这种方法常常用于数据集很小的时候
在线增强 : 这种增强的方法用于,获得 batch 数据之后,然后对这个 batch 的数据进行增强,如旋转、平移、翻折等相应的变化,由于有些数据集不能接受线性级别的增长,这种方法长用于大的数据集,很多机器学习框架已经支持了这种数据增强方式,并且可以使用 GPU 优化计算。
常用的数据增强技术:
1)翻转 2)旋转 3)缩放 4)裁剪 5)平移
6)添加噪声:过拟合通常发生在神经网络学习高频特征的时候 (因为低频特征神经网络很容易就可以学到,而高频特征只有在最后的时候才可以学到) 而这些特征对于神经网络所做的任务可能没有帮助,而且会对低频特征产生影响,为了消除高频特征我们随机加入噪声数据来消除这些特征。
7)color jittering
7)gan生成图像进行数据增强
8)纹理贴图,自造假数据
推荐博客:深度学习中的数据增强_Glory 的 博客-CSDN博客_深度学习数据增强
14. 常见的激活函数有哪些,以及它们的特点,及相应的导数
温故知新——激活函数及其各自的优缺点 - 知乎
什么是激活函数:在人工神经网络的神经元上运行的函数,负责将神经元的输入映射到输出端。
为什么要使用激活函数:
如果不用激励函数,每一层输出都是上层输入的线性函数,无论神经网络有多少层,输出都是输入的线性组合(感知机就是这样的没有激活函数,只能模拟线性变化)。
如果使用的话,激活函数给神经元引入了非线性因素,使得神经网络可以任意逼近任何非线性函数,这样神经网络就可以应用到众多的非线性模型中。
常用的激活函数包括:sigmoid,Tanh,ReLU,Leaky ReLU,PReLU,ELU,Maxout,h-swich/swish,ReLU-6
(1)sigmoid[logistic]
特点:
它能够把输入的连续实值变换为0和1之间的输出,特别的,如果是非常大的负数,那么输出就是0;如果是非常大的正数,输出就是1.
优点:
- Sigmoid函数的输出在(0,1)之间,输出范围有限,优化稳定,可以用作输出层。
- 连续函数,便于求导。
缺点:
sigmoid函数曾经被使用的很多,不过近年来,用它的人越来越少了。主要是因为它固有的一些缺点。
缺点1:在深度神经网络中梯度反向传递时导致梯度爆炸和梯度消失,其中梯度爆炸发生的概率非常小,而梯度消失发生的概率比较大。首先来看Sigmoid函数的导数(由反向传播算法的数学推导可知,梯度从后向前传播时,每传递一层梯度值都会减小为原来的0.25倍,如果神经网络隐层特别多,那么梯度在穿过多层后将变得非常小接近于0,即出现梯度消失现象;当网络权值初始化为 (1,+∞) (1,+∞)(1,+∞) 区间内的值,则会出现梯度爆炸情况。)
缺点2:Sigmoid 的 output 不是0均值(即zero-centered)。这会导致后一层的神经元将得到上一层输出的非0均值的信号作为输入。产生的一个结果就是:
那么对w求局部梯度则都为正,这样在反向传播的过程中w要么都往正方向更新,要么都往负方向更新,导致有一种捆绑的效果,使得收敛缓慢。 如果按batch去训练,那么那个batch可能得到不同的信号,所以这个问题还是可以缓解一下的。因此,非0均值这个问题虽然会产生一些不好的影响,不过跟上面提到的梯度消失问题相比还是要好很多的。
缺点3:其解析式中含有幂运算,计算机求解时相对来讲比较耗时。对于规模比较大的深度网络,这会较大地增加训练时间。
(2)tanh 函数
它解决了Sigmoid函数的不是zero-centered输出问题,然而,梯度消失(gradient vanishing)的问题和幂运算的问题仍然存在。
(3)Relu函数
ReLU函数其实就是一个取最大值函数,注意这并不是全区间可导的,但是我们可以取sub-gradient;ReLU虽然简单,但却是近几年的重要成果,有以下几大优点:
1) 解决了gradient vanishing问题 (在正区间) 2)计算速度非常快,只需要判断输入是否大于0 3)使用SGD收敛速度远快于sigmoid和tanh
单侧抑制;相对广阔的兴奋边界;稀疏激活(只对部分信号进行响应,提高学习精度,更好地提取稀疏特性);x<0 硬饱和,大于0不饱和,保持梯度不变,从而缓解梯度消息问题;
ReLU也有几个需要特别注意的问题:
1)ReLU的输出不是zero-centered
2)Dead ReLU Problem,指的是某些神经元可能永远不会被激活,导致相应的参数永远不能被更新。有两个主要原因可能导致这种情况产生: (1) 非常不幸的参数初始化,这种情况比较少见 (2) learning rate太高导致在训练过程中参数更新太大,不幸使网络进入这种状态。解决方法是可以采用Xavier初始化方法,以及避免将learning rate设置太大或使用adagrad等自动调节learning rate的算法。
(4)Leaky Relu (PRelu)函数
人们为了解决Dead ReLU Problem,提出了将ReLU的前半段设为αx而非0,通常α=0.01 。另外一种直观的想法是基于参数的方法,
理论上来讲,Leaky ReLU有ReLU的所有优点,外加不会有Dead ReLU问题,但是在实际操作当中,并没有完全证明Leaky ReLU总是好于ReLU。
(5)ELU ((Exponential Linear Units))函数
它的一个小问题在于计算量稍大。类似于Leaky ReLU,理论上虽然好于ReLU,但在实际使用中目前并没有好的证据ELU总是优于ReLU。
(6)MaxOut函数
(7) Swish函数
特点:具备无上界有下界、平滑、非单调的特性,性能在总体上优于Relu。
关于正则效果:x轴越靠近左半轴,纵坐标的值越小,甚至接近于0,如果x值是-10,那么经过激活之后的值接近于0,那么就可以一定程度上过滤掉一部分信息,起到正则化的效果。
(7)mish函数【YOLOv4骨干网络的激活函数】
(8)relu-6
主要是为了在移动端float16的低精度的时候,也能有很好的数值分辨率,如果对ReLu的输出值不加限制,那么输出范围就是0到正无穷,而低精度的float16无法精确描述其数值,带来精度损失。
(9)hard-swish
如何选择神经元激活函数:
凭经验:
1)深度学习往往需要大量时间来处理大量数据,模型的收敛速度是尤为重要的。所以,总体上来讲,训练深度学习网络尽量使用zero-centered数据 (可以经过数据预处理实现) 和zero-centered输出。所以要尽量选择输出具有zero-centered特点的激活函数以加快模型的收敛速度。
2)如果使用 ReLU,那么一定要小心设置 learning rate,而且要注意不要让网络出现很多 “dead” 神经元,如果这个问题不好解决,那么可以试试 Leaky ReLU、PReLU 或者 Maxout.
3)最好不要用 sigmoid,你可以试试 tanh,不过可以预期它的效果会比不上 ReLU 和 Maxout.
推荐博客:常用激活函数比较_u011584941的专栏-CSDN博客
常用激活函数(激励函数)理解与总结_tyhj_sf的博客空间-CSDN博客_激活函数
15.mobielNetV2 与V1的对比, mobile NetV3 的原理
为什么MobileNetV2会先扩张在压缩呢?
因为MobileNet 网络结构的核心就是Depth-wise,此卷积方式可以减少计算量和参数量。而为了引入shortcut结构,若参照Resnet中先压缩特征图的方式,将使输入给Depth-wise的特征图大小太小,接下来可提取的特征信息少,所以在MobileNet V2中采用先扩张后压缩的策略。
为什么在1*1的压缩卷积后会连接线性激活函数?
因为在激活函数之前,已经使用1*1卷积对特征图进行了压缩,而ReLu激活函数对于负的输入值,输出为0,会进一步造成信息的损失,所以使用Linear激活函数。
mobile net V1:
把VGG中的标准卷积层换成深度可分离卷积就可以;可分离卷积主要有两种类型:空间可分离卷积和深度可分离卷积。空间可分离就是将一个大的卷积核变成两个小的卷积核,比如将一个3×3的核分成一个3×1和一个1×3的核(inception v3 就是在inception v2中加入空间可分离卷积);mobileNet 主要是应用了深度可分离卷积(用更少的参数,更少的运算,但是能达到与普通卷积差的不是很多的结果):
深度卷积:将卷积核拆分成为但单通道形式,在不改变输入特征图像的深度的情况下,对每一通道进行卷积操作,这样就得到了和输入特征图通道数一致的输出特征图,卷积核(不同)的个数和输入feature map的通道数相同。
逐点卷积:逐点卷积就是1×1卷积。主要作用就是对特征图进行升维和降维
N是卷积核(普通卷积核或者逐点卷积核)的个数,Dk是卷积核(普通卷积核)的宽(一般宽等于高)。
V1的卷积层,首先使用3×3的深度卷积提取特征,接着是一个BN层,随后是一个ReLU层,在之后就会逐点卷积(扩展feature的维度),最后就是BN和ReLU了。这也很符合深度可分离卷积,将左边的标准卷积拆分成右边的一个深度卷积和一个逐点卷积。其中的relu激活函数使用的是ReLU6(输入的值大于6的时候,返回6,relu6“具有一个边界”)作者认为ReLU6作为非线性激活函数,在低精度计算下具有更强的鲁棒性。
使用深度可分离卷积与标准卷积,参数和计算量能下降为后者的九分之一到八分之一左右。但是准确率只有下降极小的1%。
作者还在论文中分析整个了网络的参数和计算量分布,如下图所示。可以看到整个计算量基本集中在1x1卷积(95%的时间)上。对于参数也主要集中在1x1卷积,除此之外还有就是全连接层占了一部分参数
mobile net V2:
V1的问题:发现深度卷积部分的卷积核比较容易训废掉:训完之后发现深度卷积训出来的卷积核有不少是空的; 作者认为是ReLU这个浓眉大眼的激活函数的锅,对低维度做ReLU运算,很容易造成信息的丢失。而在高维度进行ReLU运算的话,信息的丢失则会很少。。
既然是ReLU导致的信息损耗,将ReLU替换成线性激活函数。
linear bottleneck:
在DW深度卷积之前使用PW卷积进行升维(升维倍数为t,t=6),再在一个更高维的空间中进行卷积操作来提取特征。
不管输入通道数是多少,经过第一个PW逐点卷积升维之后,深度卷积都是在相对的更高6倍维度上进行工作
ResNet 先降维 (0.25倍)、卷积、再升维。MobileNetV2 则是 先升维 (6倍)、卷积、再降维(inverted residuals)。
MobileNetV3:
(1)网络的架构基于NAS实现的MnasNet, MnasNet是一个比MobileNet精度和实时性更高的模型就行了。
(2)引入MobileNetV1的深度可分离卷积
(3)引入MobileNetV2的具有线性瓶颈的倒残差结构
(4)引入基于squeeze and excitation结构的轻量级注意力模型(SE)
(5)使用了一种新的激活函数h-swish(x)
h-swish是基于swish的改进
Swish具备无上界有下界、平滑、非单调的特性。并且Swish在深层模型上的效果优于ReLU。
在V3的架构中,只在模型的后半部分使用h-swish(HS)。
(6)网络结构搜索中,结合两种技术:资源受限的NAS(platform-aware NAS)与NetAdapt
资源受限的NAS,用于在计算和参数量受限的前提下搜索网络来优化各个块(block),所以称之为模块级搜索(Block-wise Search) ;NetAdapt,用于对各个模块确定之后网络层的微调每一层的卷积核数量,所以称之为层级搜索
(7)修改了MobileNetV2网络端部最后阶段
使用1×1卷积来构建最后层,这样可以便于拓展到更高维的特征空间。这样做的好处是,在预测时,有更多更丰富的特征来满足预测,但是同时也引入了额外的计算成本与延时。
是谷歌在2019年3月21日提出的网络架构。
问什么MobileNet系列能够如此的快:原因就在于它大量的使用了1*1卷积,1x1卷积不需要im2col的过程(其它卷积需要设计卷积运算的重组,所以时间慢),所以底层可以有更快的实现,拿起来就能直接算,大大节省了数据重排列的时间和空间。
推荐博客:MobileNet v1 和 v2 记录_gbyy42299的博客-CSDN博客
MobileNetV1和V2详解_attitude_yu-CSDN博客_mobilenetv1和v2的区别
https://cloud.tencent.com/developer/article/1459846
16.传统的hand-crafted特征(SIFT、ORB等)与基于学习的ConvNet特征的对比以及使用场景
???
传统的特征提取算法:特征不能根据图像及其标签进行调整,如果选择的特征缺乏代表性来区分各个类别,模型准确率就大打折扣(无论你是用什么样的分类策略【常用的SVM, LR,随机森林,决策树】)
CNN模型(卷积核):实现了权重共享和稀疏连接
17.了解RNN和LSTM的基本特点和网络结构,它们之间的区别?LSTM与GRU的原理与区别
已手写
18.各种优化器的特点
机器学习:各种优化器Optimizer的总结与比较_SanFancsgo的博客-CSDN博客_optimizer
梯度下降法是最基本的一类优化器,目前主要分为三种梯度下降法:标准梯度下降法(GD, Gradient Descent),随机梯度下降法(SGD, Stochastic Gradient Descent)及批量梯度下降法(BGD, Batch Gradient Descent)。
(1)标准SD(梯度下降的算法)
假设要学习训练的模型参数为W,代价函数为J(W),则代价函数关于模型参数的偏导数即相关梯度为ΔJ(W),学习率为ηt,则使用梯度下降法更新参数为:
其中,Wt表示t时刻的模型参数。
基本策略可以理解为”在有限视距内寻找最快路径下山“,因此每走一步,参考当前位置最陡的方向(即梯度)进而迈出下一步 。
标准梯度下降法主要有两个缺点:
训练速度慢:每走一步都要要计算调整下一步的方向,下山的速度变慢。在应用于大型数据集中,每输入一个样本都要更新一次参数,且每次迭代都要遍历所有的样本。会使得训练过程极其缓慢,需要花费很长时间才能得到收敛解。
容易陷入局部最优解:由于是在有限视距内寻找下山的反向。当陷入平坦的洼地,会误以为到达了山地的最低点,从而不会继续往下走。所谓的局部最优解就是鞍点。落入鞍点,梯度为0,使得模型参数不在继续更新。
(2)批量梯度下降(BGD)
(3)SGD 随机梯度下降
参考自己的笔记
优点:
虽然SGD需要走很多步的样子,但是对梯度的要求很低(计算梯度快)。而对于引入噪声,大量的理论和实践工作证明,只要噪声不是特别大,SGD都能很好地收敛。
应用大型数据集时,训练速度很快。比如每次从百万数据样本中,取几百个数据点,算一个SGD梯度,更新一下模型参数。相比于标准梯度下降法的遍历全部样本,每输入一个样本更新一次参数,要快得多。
缺点:
SGD在随机选择梯度的同时会引入噪声,使得权值更新的方向不一定正确。
此外,SGD也没能单独克服局部最优解的问题。
(4)动量梯度下降
动量优化方法是在梯度下降法的基础上进行的改变,具有加速梯度下降的作用。一般有标准动量优化方法Momentum、NAG(Nesterov accelerated gradient)动量优化方法。
Momentum
- 使用动量(Momentum)的随机梯度下降法(SGD),主要思想是引入一个积攒历史梯度信息动量来加速SGD。
-
动量主要解决SGD的两个问题:一是随机梯度的方法(引入的噪声);二是Hessian矩阵病态问题(可以理解为SGD在收敛过程中和正确梯度相比来回摆动比较大的问题)NN优化过程中存在的挑战 - 知乎。在深度学习中,条件数用于表示函数相对于输入的微小变化而产生变化的快慢程度,条件数越大则,输入的轻微扰动就会产生结果的剧烈变化,在NN中表现为:在神经网络的优化中,hesiian矩阵病态就表现在局部最小点和鞍点,因为在局部最小点和鞍点处四周的梯度变化率(梯度和二阶导都是相似的)都是相似的,但是往不同的梯度方向前进又会导致优化结果有较大的差异
理解策略为:由于当前权值的改变会受到上一次权值改变的影响,类似于小球向下滚动的时候带上了惯性。这样可以加快小球向下滚动的速度。
牛顿加速梯度(NAG, Nesterov accelerated gradient)算法,是Momentum动量算法的变种。
Nesterov动量梯度的计算在模型参数施加当前速度之后,因此可以理解为往标准动量中添加了一个校正因子。
理解策略:在Momentun中小球会盲目地跟从下坡的梯度,容易发生错误。所以需要一个更聪明的小球,能提前知道它要去哪里,还要知道走到坡底的时候速度慢下来而不是又冲上另一个坡。计算Wt−αvt−1Wt−αvt−1可以表示小球下一个位置大概在哪里。从而可以提前知道下一个位置的梯度,然后使用到当前位置来更新参数。
在凸批量梯度的情况下,Nesterov动量将额外误差收敛率从O(1/k)(k步后)改进到O(1/k平方)。然而,在随机梯度情况下,Nesterov动量对收敛率的作用却不是很大。
自适应学习率优化算法针对于机器学习模型的学习率,传统的优化算法要么将学习率设置为常数要么根据训练次数调节学习率。极大忽视了学习率其他变化的可能性。然而,学习率对模型的性能有着显著的影响,因此需要采取一些策略来想办法更新学习率,从而提高训练速度。
目前的自适应学习率优化算法主要有:AdaGrad算法,RMSProp算法,Adam算法以及AdaDelta算法。
推荐博客:机器学习:各种优化器Optimizer的总结与比较_SanFancsgo的博客-CSDN博客_optimizer
loss乘以s【*10】倍,SGD、Momentum、NAS相当于学习率乘以10,而自适应学习率RMSProp,Adadelta、ADAM相当于学习率不受影响,【Adagrad必成s倍影响】;而对学习率直接乘以s倍,如ADAM 将对参数发生较大影响,其它学习期亦然。
深度网络loss除以10和学习率除以10是不是等价的? - 知乎
20.resnet 的特点,为什么要这么设计?
残差网络单元其中可以分解成右图的形式,从图中可以看出,残差网络其实是由多种路径组合的一个网络,直白了说,残差网络其实是很多并行子网络的组合,整个残差网络其实相当于一个多人投票系统(Ensembling)。
如果把残差网络理解成一个Ensambling系统,那么网络的一部分就相当于少一些投票的人,如果只是删除一个基本的残差单元,对最后的分类结果应该影响很小;而最后的分类错误率应该适合删除的残差单元的个数成正比的,论文里的结论也印证了这个猜测。
其实ResNet是由大多数中度网络和一小部分浅度网络和深度网络组成的,说明虽然表面上ResNet网络很深,但是其实起实际作用的网络层数并没有很深;大多数的梯度其实都集中在中间的路径上,论文里称为effective path。 从这可以看出其实ResNet只是表面上看起来很深,事实上网络却很浅。 所示ResNet真的解决了深度网络的梯度消失的问题了吗?似乎没有,ResNet其实就是一个多人投票系统。
由于上下组的卷积层通道数不同(类似于VGG网络通道数的特点),使得短路连接不能直接相加,故需要在后四组连接上一组的第一个卷积层的短路连接通路添加投影卷积。
在每个残差模块内部主要使用的卷积大小为1*1卷积和3*3卷积,采用较小的卷积核既可以减小网络的参数量,又可以极大的提高网络的非线性(比如3*3 可以分解为3*1,1*3 )增加了网络的表达能力。
由于ResNet的结构有别于传统的卷积结构,使得信号的前向传播和梯度的反向传播变得更复杂。为了稳定训练时信号的前向传播和梯度的反向传播,从ResNet开始,网络普遍使用Batch Normalization。
resnetxt: 2017CVPR
它的核心思想是在不增加网络参数复杂度的情况下提高检测或者分类的准确率,同时还可以较少超参数的数量。
出自论文“Aggregated Residual Transformations for Deep Neural Networks”,主要是将残差块的中间的3x3卷积层变成group卷积,同时扩大了3x3卷积的输入输出通道数,使得在与对应的ResNet网络的计算量和参数个数相近的同时提高网络的性能。值得一提的是,ResNeXt与常用的ResNet对应的层数完全相同,都是50、101、152层。ResNeXt已经被很多网络用来当作backbone,例如Mask RCNN中除了使用ResNet,也尝试使用了ResNeXt-101和ResNeXt-152。
DenseNet:
2017年横空出世的密集连接网络(DenseNet),将跳跃连接用到了极致
对于一个具有n个卷积层的密集连接模块,其有n*(n+1)/ 2
推荐博客:ResNet 6大变体对比_darren2015zdc的博客-CSDN博客
21.过拟合的处理方法?BN为什么可以防止过拟合?
BN防止过拟合的原因:在训练中,BN的使用使得一个mini-batch中的所有样本都被关联在了一起,因此网络不会从某一个训练样本中生成确定的结果。意思就是同样一个样本的输出不再仅仅取决于样本本身,也取决于跟这个样本属于同一个mini-batch的其它样本。同一个样本跟不同的样本组成一个mini-batch,它们的输出是不同的(仅限于训练阶段,在inference阶段是没有这种情况的)。我把这个理解成一种数据增强:同样一个样本在超平面上被拉扯,每次拉扯的方向的大小均有不同。不同于数据增强的是,这种拉扯是贯穿数据流过神经网络的整个过程的,意味着神经网络每一层的输入都被数据增强处理了。
22. python hash 存储的内部实现原理; python map reduce函数的作用?
哈希表的定义:哈希存储的基本思想是以关键字Key为自变量,通过一定的函数关系(散列函数或哈希函数),计算出对应的函数值(哈希地址),以这个值作为数据元素的地址,并将数据元素存入到相应地址的存储单元中。
查找时再根据要查找的关键字采用同样的函数计算出哈希地址,然后直接到相应的存储单元中去取要找的数据元素即可。
哈希表(hash table)是实现字典操作的一种有效的数据结构。
尽管最坏的情况下,散列表中查找一个元素的时间与链表中查找的时间相同,达到了O(n)。在一些合理的假设下,在散列表中查找一个元素的平均时间是O(1)。
建立hash建立的过程
1) step1 取数据元素的关键字key,计算其哈希函数值(地址)。若该地址对应的存储空间还没有被占用,则将该元素存入;否则执行step2解决冲突。
2) step2 根据选择的冲突处理方法,计算关键字key的下一个存储地址。若下一个存储地址仍被占用,则继续执行step2,直到找到能用的存储地址为止。
构造哈希函数的方法有很多,总的原则是尽可能将关键字集合空间均匀的映射到地址集合空间中,同时尽可能降低冲突发生的概率。
常用的hash函数:
影响哈希查找效率的一个重要因素是哈希函数本身。当两个不同的数据元素的哈希值相同时,就会发生冲突。为减少发生冲突的可能性,哈希函数应该将数据尽可能分散地映射到哈希表的每一个表项中。
(1)开放地址法
如果两个数据元素的哈希值相同,则在哈希表中为后插入的数据元素另外选择一个表项。
当程序查找哈希表时,如果没有在第一个对应的哈希表项中找到符合查找要求的数据元素,程序就会继续往后查找,直到找到一个符合查找要求的数据元素,或者遇到一个空的表项。
python中的hash(dict)采用的是开放地址法的双哈希函数探测法
(2)链地址法
将哈希值相同的数据元素存放在一个链表中,在查找哈希表的过程中,当查找到这个链表时,必须采用线性查找方法。
推荐:【Python算法】哈希存储、哈希表、散列表原理 - 5_FireFly - 博客园
python filter map reduce函数的作用:
(1)filter:功能:filter主要作用是过滤掉序列中不符合函数条件的元素,当序列中要删、减元素时,可以使用filter函数。
格式:fliter(function,sequence)
function可以是匿名函数或者自定义函数,它可以对后面的sequence序列的每个元素判定是否符合条件,返回True或者False,从而留下True的元素;sequence可以是列表、元组或者字符串。
注意:迭代器需要进行列表转换
(2)map:功能:map主要作用是求一个序列或者多个序列进行函数映射之后的值。
格式:map(function,iterable1,iterable2)
function中参数值可以是一个,也可以是多个;后面的iterable代表function运算中的参数值,有几个参数值就传入几个iterable。
注意:1.迭代器需要进行列表转换 2.map中如果传入的序列长度不一,会依据最短的序列计算
(3)reduce:功能:reduce是对一个序列进行压缩运算,得到一个值。
格式:reduce(function,iterable)
function中必须传入两个参数,iterable可以是列表或者元组。
注意:reduce使用前需要导包 from functools import reduce,map和filter是内置函数,所以可以直接调用.
23.反卷积如何实现?
在信号处理上,反转180度称作卷积,直接滑动计算称作自相关,在大部分深度学习框架上都没有反转180度的操作,而是直接滑动计算卷积。
目前使用得最多的deconvolution有2种。
方法1:full卷积, 完整的卷积可以使得原来的定义域变大
方法2:记录pooling index,然后扩大空间,再用卷积填充
推荐博客:卷积神经网络CNN(1)——图像卷积与反卷积(后卷积,转置卷积)_Fate_fjh的博客-CSDN博客
24.DL数据不平衡怎么解决的?
处理不平衡的方法总的来说可以分为两大类:1. 数据增强,2.损失函数权值均衡
一、数据集方法:1.数据增强,2.过采样和欠采样, 3. 人工数据合成
二、损失函数的权值均衡:1.不同类别的loss 权值不一样,最佳参数需要手动调节 2.focal loss
推荐:处理深度学习中数据集不平衡问题方法汇总_一江明澈的水的专栏-CSDN博客_深度学习数据集不平衡
25.softmax 层有什么缺点?triplet loss的形式,特点原理?
softmax为什么要用指数作用与神经元的输出(指数函数是一种max的行为可以让大的输出更大)
softmax 主要用于多分类,而sigmoid主要用于二分类;softmax建模使用的分布是多项式分布,而logistic则基于伯努利分布
多个logistic回归通过叠加也同样可以实现多分类的效果,但是 softmax回归进行的多分类,类与类之间是互斥的,即一个输入只能被归为一类;多个logistic回归进行多分类,输出的类别并不是互斥的,即"苹果"这个词语既属于"水果"类也属于"3C"类别。
总结:
Softmax训练的深度特征,会把整个超空间或者超球,按照分类个数进行划分,保证类别是可分的,这一点对多分类任务如MNIST和ImageNet非常合适,因为测试类别必定在训练类别中。
但Softmax并不要求类内紧凑和类间分离,这一点非常不适合人脸识别任务,因为训练集的1W人数,相对测试集整个世界70亿人类来说,非常微不足道,而我们不可能拿到所有人的训练样本,更过分的是,一般我们还要求训练集和测试集不重叠。
所以需要改造Softmax,除了保证可分性外,还要做到特征向量类内尽可能紧凑,类间尽可能分离
推荐:
[深度概念]·Softmax优缺点解析_简明AI工作室-CSDN博客_softmax的缺点
triplet loss:
推荐:Triplet-Loss原理及其实现、应用_莫失莫忘的博客-CSDN博客_tripletloss
triplet loss 原理以及梯度推导_tangwei2014的专栏-CSDN博客_triplet-loss
26.CNN的原理?把feature map 映射为矩阵?
卷积和反卷积的作用:卷积与反卷积操作使得神经网络可以处理二维以上的数据。它最大的好处在于:1.保持了数据在空间上的位置信息;2.权重共享使得计算复杂度大大降低。
27.attention 机制的原理
从两个角度来分类Attention种类:空间注意力和时间注意力,即Spatial Attention 和Temporal Attention。这种分类更多的是从应用层面上,而从Attention的作用方法上,可以将其分为Soft Attention和Hard Attention,其实有Soft AM,对应也有一个Hard AM。既然Soft是给每个单词都赋予一个单词对齐概率,那么如果不这样做,直接从输入句子里面找到某个特定的单词,然后把目标句子单词和这个单词对齐,而其它输入句子中的单词硬性地认为对齐概率为0,这就是Hard Attention Model的思想,这既我们所说的,Attention输出的向量分布是一种one-hot的独热分布还是soft的软分布,这直接影响对于上下文信息的选择作用。
Attention的出现就是为了两个目的:1. 减小处理高维输入数据的计算负担,通过结构化的选取输入的子集,降低数据维度。2. “去伪存真”,让任务处理系统更专注于找到输入数据中显著的与当前输出相关的有用信息,从而提高输出的质量。Attention模型的最终目的是帮助类似编解码器这样的框架,更好的学到多种内容模态之间的相互关系,从而更好的表示这些信息,克服其无法解释从而很难设计的缺陷。从上述的研究问题可以发现,Attention机制非常适合于推理多种不同模态数据之间的相互映射关系,这种关系很难解释,很隐蔽也很复杂,这正是Attention的优势—不需要监督信号,对于上述这种认知先验极少的问题,显得极为有效。
深度学习里的Attention model其实模拟的是人脑的注意力模型,对自然语言处理,图像识别描述,语音识别任务有极大地作用;
Encoder-Decoder加Attention架构由于其卓越的实际效果,目前在深度学习领域里得到了广泛的使用,了解并熟练使用这一架构对于解决实际问题会有极大帮助。
深度学习笔记——Attention Model(注意力模型)学习总结_mpk_no1的博客-CSDN博客_additive attention
28.多机多卡和单机多卡是怎么训练的?
tensorflow版本:
构建好图后,使用拓扑算法来决定执行哪一个节点,即对每个节点使用一个计数,值表示所依赖的未完成的节点数目,当一个节点的运算完成时,将依赖该节点的所有节点的计数减一。如果节点的计数为0,将其放入准备队列等待执行。
单机多GPU的训练过程如下:
-
假设你的机器上有3个GPU
-
在单机单GPU的训练中,数据是一个batch一个batch的训练。 在单机多GPU中,数据一次处理3个batch(假设是3个GPU训练), 每个GPU处理一个batch的数据计算
-
变量或者说参数,保存在CPU节点上
-
刚开始的时候数据由CPU分发给3个GPU, 在GPU上完成计算,得到每个batch要更新的梯度
-
然后在CPU上收集完了3个GPU上的要更新的梯度, 计算一下平均梯度,然后更新参数。
-
继续循环这个过程。
处理的速度取决于最慢那个GPU的速度。如果3个GPU的处理速度差不多的话, 处理速度就相当于单机单GPU的速度的3倍减去数据在CPU和GPU之间传输的开销,实际的效率提升看CPU和GPU之间数据的速度和处理数据的大小。CPU要等到GPU中最慢的一个处理完数据之后,才将数据汇总并且惊醒下一次数据的分发。
多机多卡训练过程如下(分布式的深度学习训练方法):
参数服务器:当你的模型越来越大, 模型的参数越来越多,多到模型参数的更新,一台机器的性能都不够的时候, 很自然的我们就会想到把参数分开放到不同的机器去存储和更新。
In-graph模式(将模型的计算图的不同部分放在不同的主机上执行), 把计算已经从单机多GPU,已经扩展到了多机多GPU了, 不过数据分发还是在一个节点。 这样的好处是配置简单, 其他多机多GPU的计算节点,只要起个join操作, 暴露一个网络接口,等在那里接受任务就好了。 这些计算节点暴露出来的网络接口,使用起来就跟本机的一个GPU的使用一样, 只要在操作的时候指定tf.device(“/job:worker/task:n”), 就可以向指定GPU一样,把操作指定到一个计算节点上计算,使用起来和多GPU的类似。 但是这样的坏处是训练数据的分发依然在一个节点上, 要把训练数据分发到不同的机器上, 严重影响并发训练速度。在大数据训练的情况下, 不推荐使用这种模式。
Between-graph模式下(数据并行,每台主机使用完全相同的计算图。),训练的参数保存在参数服务器, 数据不用分发, 数据分片的保存在各个计算节点, 各个计算节点自己算自己的, 算完了之后, 把要更新的参数告诉参数服务器,参数服务器更新参数。这种模式的优点是不用训练数据的分发了, 尤其是在数据量在TB级的时候, 节省了大量的时间,所以大数据深度学习还是推荐使用Between-graph模式。
推荐:分布式TensorFlow多主机多GPU原理与实现_yjk13703623757的博客-CSDN博客_分布式gpu
29.Relu 和 sigmoid等激活函数的应用场景
手写特点
30. OCR
30.卷积核怎么初始化
就是神经网络神经元的初始化类似,根据输入输出的神经元的数量来进行初始化
31 L1和L2 损失函数的区别,L1L2正则化的作用
L1正则和L2正则的比较分析详解_Learning from the mistakes-CSDN博客_l1正则和l2正则的区别
32.模型搜索
33. shuffle Net V1 与 shuffle V2
旷视提出来的:
shuffle Net V1深度卷积,逐点组卷积,channel shuffle
channel shuffle:作者提出把每个组的特征图分为一定组在每一层都进行一定程度的乱序结合,以这样的方式增加特征图的连接融合次数
shuffle V2:ShuffleNet v2算法笔记_AI之路-CSDN博客_shufflenetv2
完全瞄准轻量化这个目标而设计。广泛使用的FLOPs真的可以很好的反应我们网络的复杂度吗?显然答案是否定的,作者举出的例子是MobileNetV2的FLOPs和NASNET-A是相当的,但是速度却快出了后者很多。一个忽略的因素就是MAC(memory access cost),另一个被忽略的因素就是网络设计的平行度(parallelism),作者研究说在相同的FLOPs下,平行度高的模型比平行度低的模型速度要快很多。
(1)相同维度的通道数将最小化MAC
(2)过多的分组卷积会加大MAC
(3)碎片操作将减小网络的平行度,这里的碎片操作指的是将一个大的卷积操作分为多个小的卷积操作进行。
(4)不要忽略元素级操作,这里元素级操作指的就是Relu,TensorAdd,BiasAdd等等的矩阵元素级操作,可以推测到这些操作其实基本没有被算到FLOPs中,但是对于MAC这个参数的影响确实比较大的。
(5)关于模型设计的分支数量对模型速度的影响。结论是模型中的分支数量越少,模型速度越快。
作者首先复盘了ShuffleNetV1,认为目前比较关键的问题是如何在全卷积或者分组卷积中维护大多数的卷积是平衡的。针对这个目标,作者提出了Channel Split的操作,同时构建了ShuffleNetV2。
34.推荐系统
正是为了解决信息过载(Information overload)的问题,人们提出了推荐系统(与搜索引擎对应,人们习惯叫推荐系统为推荐引擎)。
推荐引擎更倾向于人们没有明确的目的,或者说他们的目的是模糊的,通俗来讲,用户连自己都不知道他想要什么,这时候正是推荐引擎的用户之地,推荐系统通过用户的历史行为或者用户的兴趣偏好或者用户的人口统计学特征来送给推荐算法。
长尾理论(人们只关注曝光率高的项目,而忽略曝光率低的项目)可以很好的解释推荐系统的存在,试验表明位于长尾位置的曝光率低的项目产生的利润不低于只销售曝光率高的项目的利润。推荐系统正好可以给所有项目提供曝光的机会,以此来挖掘长尾项目的潜在利润。
如果说搜索引擎体现着马太效应(会造成越流行的东西随着搜索过程的迭代会越流行,使得那些越不流行的东西石沉大海)的话,那么长尾理论则阐述了推荐系统所发挥的价值。
1.基于内容的推荐
利用项目的内在品质或者固有属性来进行推荐,建立在项目的内容信息上作出推荐的,而不需要依据用户对项目的评价意见,更多地需要用机器学习的方法从关于内容的特征描述的事例中得到用户的兴趣资料。
基于项目的相似度来通过最近邻获取与目标项目最相似的项目列表,然后把用户没有行为记录并且评分高的项目推荐给特定用户。
2.基于协同过滤的推荐
通过集体智慧的力量来进行工作,过滤掉那些用户不感兴趣的项目;协同过滤是基于这样的假设:为特定用户找到他真正感兴趣的内容的好方法是首先找到与此用户有相似兴趣的其他用户,然后将他们感兴趣的内容推荐给此用户。
一般采用最近邻技术,利用用户的历史喜好信息计算用户之间的距离,然后利用目标用户的最近邻居用户对商品评价的加权评价值来预测目标用户对特定商品的喜好程度,系统从而根据这一喜好程度来对目标用户进行推荐,通常需要用到UI矩阵的信息。协同过滤推荐又可以根据是否运用机器学习的思想进一步划分为基于内存的协同过滤推荐(Memory-based CF)和基于模型的协同过滤推荐(Model-based CF)。
基于内存的推荐系统(Memory-based CF)主要是通过启发式的方法来进行推荐,主要步骤一个是相似性函数的选择,如何选择合适的相似性函数来更好的度量两个项目或者用户的相似性是关键;另一个主要步骤是如何进行推荐,最简单的推荐方法是基于大多数的推荐策略,即推荐那些大多数人产生过行为而目标用户未产生过行为的项目。
基于模型的协同过滤推荐
基于模型的推荐系统(Model-based CF)主要是运用机器学习的思想来进行推荐,说到机器学习思想那真是不胜枚举