赞
踩
dilation rate
最大,且dilation rate
小于等于卷积核的大小。这也是为了对抗网格效应。对于低算力平台(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 延时。
Detail-Preserving Pooling(DPP池化):由于池化本质上是一个有损的过程,所以每个这样的层都必须保留对网络可判别性最重要的部分进行激活 ;DPP一种自适应池化方法,该池化可以放大空间变化并保留重要的图像结构细节,且其内部的参数可通过反向传播加以学习
DPP池化允许缩减规模以专注于重要的结构细节,可学习的参数控制着细节的保存量,此外,由于细节保存和规范化相互补充,DPP可以与随机合并方法结合使用,以进一步提高准确率
Local Importance Pooling(局部重要性池化)
从局部重要性的角度提出了局部重要性池化Local Importance Pooling
首先在原特征图上学习一个类似于注意力的特征图,然后再和原特征图进行加权求均值
Local Importance Pooling可以学习自适应和可判别性的特征图以汇总下采样特征,同时丢弃无信息特征。这种池化机制能极大保留物体大部分细节,对于一些细节信息异常丰富的任务至关重要。
- 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()
输入输出可以通过正常卷积输入输出关系反推:
规范表达:
DL中的deconv,是一种上采样过程;卷积的输入input 通过卷积得到输出output, 而从output到input就是反卷积。反卷积等于将卷积的卷积核水平翻转再垂直翻转得到的卷积核作用于卷积的操作的ouput上,得到卷积操作的input。
L0损失定义为:向量中非零元素的个数,常常用于压缩感知,压缩传感计划试图找到欠定线性系统(under-determinedlinear system)最稀疏的解(sparsest solution)。最稀疏的解意味着解有最少的非零元素。
L1 损失:
L2损失(欧几里得范数):
作为损失函数: 用 L2 一定只有一条最好的预测线,L1 则因为其性质可能存在多个最优解;L1鲁棒性 (Robust) 更强,对异常值更不敏感。
作为正则项:
L1 最重要的一个特点,输出稀疏,会把不重要的特征直接置零,而 L2 则不会;L1一个天然的特征选择器;L2 有唯一解,而 L1 不是
为什么输出稀疏特征??
模型压缩的方法:对模型预测精度无明显影响,压缩模型的参数数量,深度来降低模型空间的复杂度,不显著提高训练时间复杂度,降低预测时间的复杂度。
挑选出模型中不重要的参数,将其剔除而不会对模型的效果造成太大的影响。在剔除不重要的参数之后,通过一个retrain的过程来恢复模型的性能。如何找到一个有效的对参数重要性的评价手段;基于模型裁剪的方法是最为简单有效的模型压缩方式
a)单个权重剪枝(非结构化):定义:任意权重被看作是单个参数并进行随机非结构化剪枝。
b)核内权重剪枝(核稀疏化)(结构化):对权重的更新加以正则项进行限制,使其更加稀疏,使大部分的权值都为0。
c)卷积核/特征图/通道剪枝(结构化):减去第i层的filter,进而减去第i层产生的部分特征图和第i+1层的部分kernel。
d)中间隐层剪枝:删除一些层,即改变网络结构
方法:a)将三维张量铺展成二维张量,使用标准SVD;b)使用多个一维张量外积求和逼近
通常基于张量的低秩近似理论和方法,将原始的权重张量分解为两个或者多个张量,并对分解张量进行优化调整;
优缺点:
低秩方法很适合模型压缩和加速。
低秩方法的实现并不容易,因为它涉及计算成本高昂的分解操作。
目前的方法逐层执行低秩近似,无法执行非常重要的全局参数压缩,因为不同的层具备不同的信息。
分解需要大量的重新训练来达到收敛。
1)结构化矩阵:如果一个 m x n 阶矩阵只需要少于 m×n 个参数来描述,就是一个结构化矩阵。通常这样的结构不仅能减少内存消耗,还能通过快速的矩阵-向量乘法和梯度计算显著加快推理和训练的速度。
2)哈希:将参数映射到相应的哈希桶内,在同一个哈希桶内的参数则共享同一值。
思想:通过减少表示每个权重所需的比特数来压缩原始网络。
迁移学习:将一个模型的性能迁移到另一个模型上
网络精馏:在同一个域上迁移学习的一种特例
核心思想是通过迁移知识,从而通过训练好的大模型得到更加适合推理的小模型。大模型学习到的函数压缩进更小更快的模型,而获得可以匹敌大模型结果的方法
自己手推
为移动和嵌入式设备提出的高效模型,MobileNets基于流线型架构(streamlined),使用深度可分离卷积(depthwise separable convolutions,即Xception变体结构)来构建轻量级深度神经网络。
MobileNet描述了一个高效的网络架构,允许通过两个超参数直接构建非常小、低延迟、易满足嵌入式设备要求的模型。
现阶段在建立小型高效的神经网络工作:
(1)压缩预训练模型。获得小型网络的一个办法是减小、分解或压缩预训练网络,例如量化压缩(product quantization)、哈希(hashing )、剪枝(pruning)、矢量编码( vector quantization)和霍夫曼编码(Huffman coding)等;此外还有各种分解因子(various factorizations )用来加速预训练网络;一种训练小型网络的方法叫蒸馏(distillation ),使用大型网络指导小型网络;
(2)直接训练小模型:Flattened networks利用完全的因式分解的卷积网络构建模型,显示出完全分解网络的潜力;Factorized Networks引入了类似的分解卷积以及拓扑连接的使用。
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论文解读_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主要减少了计算量。
进程:是系统进行资源分配和运行调用的独立单位。可以简单地理解为操作系统中正在执行的程序,每个应用程序都有一个自己的进程。
每一个进程启动时都会最先产生一个线程,即主线程。然后主线程会再创建其他的子线程。
线程:线程是一个基本的 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 密集型程序。
已手写
推荐:CNN中的梯度的求法和反向传播过程_haolexiao的专栏-CSDN博客_cnn 梯度
怎么选择卷积核的大小:卷积神经网络的卷积核大小、卷积层数、每层map个数都是如何确定下来的呢? - 知乎
怎么选择全联接层神经元的个数:
手推反向传递:已经手推:笔记: 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 深度学习
神经网络更深(层数),更宽(神经元个数)的缺点:
1.参数太多,容易过拟合,若训练数据集有限;
2.网络越大计算复杂度越大,难以应用;
3.网络越深,梯度越往后穿越容易消失(梯度弥散),难以优化模型
为了解决这样的问题当然是增加网络深度和宽度的同时,减少参数量
在3x3前,5x5前,max pooling后分别加上了1x1的卷积核起到了降低特征图厚度的作用,减少计算量。
加入了BN层,减少了Internal Covariate Shift(内部neuron的数据分布发生变化),使每一层的输出都规范化到一个N(0, 1)的高斯;
另外一方面学习VGG用2个3x3的conv替代inception模块中的5x5,既降低了参数数量,也加速计算 。
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的中间层效果明显。
v4研究了Inception模块结合Residual Connection能不能有改进?发现ResNet的结构可以极大地加速训练,同时性能也有提升,得到一个Inception-ResNet v2网络,同时还设计了一个更深更优化的Inception v4模型,能达到与Inception-ResNet v2相媲美的性能。
Squeeze(挤压) 和 Excitation(激励) 是两个非常关键的操作;希望显式地建模特征通道之间的相互依赖关系;我们并不打算引入一个新的空间维度来进行特征通道间的融合,而是采用了一种全新的「特征重标定」策略。通过学习的方式来自动获取到每个特征通道的重要程度,然后依照这个重要程度去提升有用的特征并抑制对当前任务用处不大的特征;
首先是 Squeeze 操作,我们顺着空间维度来进行特征压缩,将每个二维的特征通道变成一个实数,这个实数某种程度上具有全局的感受野,并且输出的维度和输入的特征通道数相匹配。它表征着在特征通道上响应的全局分布,而且使得靠近输入的层也可以获得全局的感受野,这一点在很多任务中都是非常有用的。
其次是 Excitation 操作,它是一个类似于循环神经网络中门的机制。通过参数 w 来为每个特征通道生成权重,其中参数 w 被学习用来显式地建模特征通道间的相关性。
最后是一个 Reweight 的操作,我们将 Excitation 的输出的权重看做是进过特征选择后的每个特征通道的重要性,然后通过乘法逐通道加权到先前的特征上,完成在通道维度上的对原始特征的重标定。
参考博客:可变形卷积网络--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的描述子。这些方法都是建立在我们已经知道数据集里面存在哪些几何变换的基础上,对于未知的变换无法适应。
为什么提出可变形卷积网络?
同一层的激活单元的感受野是一样大的,这对于目标检测来说就是不太合理的,因为不同位置对应的目标大小是不一样的。如果能够使得感受野在不同位置的大小进行自适应调整,那么对于目标检测语义分割等等任务的帮助必然很大。
比较成功的神经网络需要大量的参数,许许多多的神经网路的参数都是数以百万计,而使得这些参数可以正确工作则需要大量的数据进行训练,而实际情况中数据并没有我们想象中的那么多
数据增强可以分为两类,一类是离线增强,一类是在线增强
离线增强 : 直接对数据集进行处理,数据的数目会变成增强因子 x 原数据集的数目 ,这种方法常常用于数据集很小的时候
在线增强 : 这种增强的方法用于,获得 batch 数据之后,然后对这个 batch 的数据进行增强,如旋转、平移、翻折等相应的变化,由于有些数据集不能接受线性级别的增长,这种方法长用于大的数据集,很多机器学习框架已经支持了这种数据增强方式,并且可以使用 GPU 优化计算。
1)翻转 2)旋转 3)缩放 4)裁剪 5)平移
6)添加噪声:过拟合通常发生在神经网络学习高频特征的时候 (因为低频特征神经网络很容易就可以学到,而高频特征只有在最后的时候才可以学到) 而这些特征对于神经网络所做的任务可能没有帮助,而且会对低频特征产生影响,为了消除高频特征我们随机加入噪声数据来消除这些特征。
7)color jittering
7)gan生成图像进行数据增强
8)纹理贴图,自造假数据
推荐博客:深度学习中的数据增强_Glory 的 博客-CSDN博客_深度学习数据增强
如果不用激励函数,每一层输出都是上层输入的线性函数,无论神经网络有多少层,输出都是输入的线性组合(感知机就是这样的没有激活函数,只能模拟线性变化)。
如果使用的话,激活函数给神经元引入了非线性因素,使得神经网络可以任意逼近任何非线性函数,这样神经网络就可以应用到众多的非线性模型中。
常用的激活函数包括:sigmoid,Tanh,ReLU,Leaky ReLU,PReLU,ELU,Maxout,h-swich/swish,ReLU-6
特点:
它能够把输入的连续实值变换为0和1之间的输出,特别的,如果是非常大的负数,那么输出就是0;如果是非常大的正数,输出就是1.
优点:
缺点:
sigmoid函数曾经被使用的很多,不过近年来,用它的人越来越少了。主要是因为它固有的一些缺点。
缺点1:在深度神经网络中梯度反向传递时导致梯度爆炸和梯度消失,其中梯度爆炸发生的概率非常小,而梯度消失发生的概率比较大。首先来看Sigmoid函数的导数(由反向传播算法的数学推导可知,梯度从后向前传播时,每传递一层梯度值都会减小为原来的0.25倍,如果神经网络隐层特别多,那么梯度在穿过多层后将变得非常小接近于0,即出现梯度消失现象;当网络权值初始化为 (1,+∞) (1,+∞)(1,+∞) 区间内的值,则会出现梯度爆炸情况。)
缺点2:Sigmoid 的 output 不是0均值(即zero-centered)。这会导致后一层的神经元将得到上一层输出的非0均值的信号作为输入。产生的一个结果就是:
那么对w求局部梯度则都为正,这样在反向传播的过程中w要么都往正方向更新,要么都往负方向更新,导致有一种捆绑的效果,使得收敛缓慢。 如果按batch去训练,那么那个batch可能得到不同的信号,所以这个问题还是可以缓解一下的。因此,非0均值这个问题虽然会产生一些不好的影响,不过跟上面提到的梯度消失问题相比还是要好很多的。
缺点3:其解析式中含有幂运算,计算机求解时相对来讲比较耗时。对于规模比较大的深度网络,这会较大地增加训练时间。
它解决了Sigmoid函数的不是zero-centered输出问题,然而,梯度消失(gradient vanishing)的问题和幂运算的问题仍然存在。
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的算法。
人们为了解决Dead ReLU Problem,提出了将ReLU的前半段设为αx而非0,通常α=0.01 。另外一种直观的想法是基于参数的方法,
理论上来讲,Leaky ReLU有ReLU的所有优点,外加不会有Dead ReLU问题,但是在实际操作当中,并没有完全证明Leaky ReLU总是好于ReLU。
它的一个小问题在于计算量稍大。类似于Leaky ReLU,理论上虽然好于ReLU,但在实际使用中目前并没有好的证据ELU总是优于ReLU。
关于正则效果:x轴越靠近左半轴,纵坐标的值越小,甚至接近于0,如果x值是-10,那么经过激活之后的值接近于0,那么就可以一定程度上过滤掉一部分信息,起到正则化的效果。
(7)mish函数【YOLOv4骨干网络的激活函数】
主要是为了在移动端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博客_激活函数
因为MobileNet 网络结构的核心就是Depth-wise,此卷积方式可以减少计算量和参数量。而为了引入shortcut结构,若参照Resnet中先压缩特征图的方式,将使输入给Depth-wise的特征图大小太小,接下来可提取的特征信息少,所以在MobileNet V2中采用先扩张后压缩的策略。
因为在激活函数之前,已经使用1*1卷积对特征图进行了压缩,而ReLu激活函数对于负的输入值,输出为0,会进一步造成信息的损失,所以使用Linear激活函数。
把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卷积,除此之外还有就是全连接层占了一部分参数
V1的问题:发现深度卷积部分的卷积核比较容易训废掉:训完之后发现深度卷积训出来的卷积核有不少是空的; 作者认为是ReLU这个浓眉大眼的激活函数的锅,对低维度做ReLU运算,很容易造成信息的丢失。而在高维度进行ReLU运算的话,信息的丢失则会很少。。
既然是ReLU导致的信息损耗,将ReLU替换成线性激活函数。
在DW深度卷积之前使用PW卷积进行升维(升维倍数为t,t=6),再在一个更高维的空间中进行卷积操作来提取特征。
不管输入通道数是多少,经过第一个PW逐点卷积升维之后,深度卷积都是在相对的更高6倍维度上进行工作
ResNet 先降维 (0.25倍)、卷积、再升维。MobileNetV2 则是 先升维 (6倍)、卷积、再降维(inverted residuals)。
(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
???
传统的特征提取算法:特征不能根据图像及其标签进行调整,如果选择的特征缺乏代表性来区分各个类别,模型准确率就大打折扣(无论你是用什么样的分类策略【常用的SVM, LR,随机森林,决策树】)
CNN模型(卷积核):实现了权重共享和稀疏连接
已手写
机器学习:各种优化器Optimizer的总结与比较_SanFancsgo的博客-CSDN博客_optimizer
梯度下降法是最基本的一类优化器,目前主要分为三种梯度下降法:标准梯度下降法(GD, Gradient Descent),随机梯度下降法(SGD, Stochastic Gradient Descent)及批量梯度下降法(BGD, Batch Gradient Descent)。
假设要学习训练的模型参数为W,代价函数为J(W),则代价函数关于模型参数的偏导数即相关梯度为ΔJ(W),学习率为ηt,则使用梯度下降法更新参数为:
其中,Wt表示t时刻的模型参数。
基本策略可以理解为”在有限视距内寻找最快路径下山“,因此每走一步,参考当前位置最陡的方向(即梯度)进而迈出下一步 。
标准梯度下降法主要有两个缺点:
训练速度慢:每走一步都要要计算调整下一步的方向,下山的速度变慢。在应用于大型数据集中,每输入一个样本都要更新一次参数,且每次迭代都要遍历所有的样本。会使得训练过程极其缓慢,需要花费很长时间才能得到收敛解。
容易陷入局部最优解:由于是在有限视距内寻找下山的反向。当陷入平坦的洼地,会误以为到达了山地的最低点,从而不会继续往下走。所谓的局部最优解就是鞍点。落入鞍点,梯度为0,使得模型参数不在继续更新。
(2)批量梯度下降(BGD)
参考自己的笔记
优点:
虽然SGD需要走很多步的样子,但是对梯度的要求很低(计算梯度快)。而对于引入噪声,大量的理论和实践工作证明,只要噪声不是特别大,SGD都能很好地收敛。
应用大型数据集时,训练速度很快。比如每次从百万数据样本中,取几百个数据点,算一个SGD梯度,更新一下模型参数。相比于标准梯度下降法的遍历全部样本,每输入一个样本更新一次参数,要快得多。
缺点:
SGD在随机选择梯度的同时会引入噪声,使得权值更新的方向不一定正确。
此外,SGD也没能单独克服局部最优解的问题。
动量优化方法是在梯度下降法的基础上进行的改变,具有加速梯度下降的作用。一般有标准动量优化方法Momentum、NAG(Nesterov accelerated gradient)动量优化方法。
Momentum
动量主要解决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是不是等价的? - 知乎
残差网络单元其中可以分解成右图的形式,从图中可以看出,残差网络其实是由多种路径组合的一个网络,直白了说,残差网络其实是很多并行子网络的组合,整个残差网络其实相当于一个多人投票系统(Ensembling)。
如果把残差网络理解成一个Ensambling系统,那么网络的一部分就相当于少一些投票的人,如果只是删除一个基本的残差单元,对最后的分类结果应该影响很小;而最后的分类错误率应该适合删除的残差单元的个数成正比的,论文里的结论也印证了这个猜测。
其实ResNet是由大多数中度网络和一小部分浅度网络和深度网络组成的,说明虽然表面上ResNet网络很深,但是其实起实际作用的网络层数并没有很深;大多数的梯度其实都集中在中间的路径上,论文里称为effective path。 从这可以看出其实ResNet只是表面上看起来很深,事实上网络却很浅。 所示ResNet真的解决了深度网络的梯度消失的问题了吗?似乎没有,ResNet其实就是一个多人投票系统。
由于上下组的卷积层通道数不同(类似于VGG网络通道数的特点),使得短路连接不能直接相加,故需要在后四组连接上一组的第一个卷积层的短路连接通路添加投影卷积。
在每个残差模块内部主要使用的卷积大小为1*1卷积和3*3卷积,采用较小的卷积核既可以减小网络的参数量,又可以极大的提高网络的非线性(比如3*3 可以分解为3*1,1*3 )增加了网络的表达能力。
由于ResNet的结构有别于传统的卷积结构,使得信号的前向传播和梯度的反向传播变得更复杂。为了稳定训练时信号的前向传播和梯度的反向传播,从ResNet开始,网络普遍使用Batch Normalization。
它的核心思想是在不增加网络参数复杂度的情况下提高检测或者分类的准确率,同时还可以较少超参数的数量。
出自论文“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。
对于一个具有n个卷积层的密集连接模块,其有n*(n+1)/ 2
推荐博客:ResNet 6大变体对比_darren2015zdc的博客-CSDN博客
BN防止过拟合的原因:在训练中,BN的使用使得一个mini-batch中的所有样本都被关联在了一起,因此网络不会从某一个训练样本中生成确定的结果。意思就是同样一个样本的输出不再仅仅取决于样本本身,也取决于跟这个样本属于同一个mini-batch的其它样本。同一个样本跟不同的样本组成一个mini-batch,它们的输出是不同的(仅限于训练阶段,在inference阶段是没有这种情况的)。我把这个理解成一种数据增强:同样一个样本在超平面上被拉扯,每次拉扯的方向的大小均有不同。不同于数据增强的是,这种拉扯是贯穿数据流过神经网络的整个过程的,意味着神经网络每一层的输入都被数据增强处理了。
查找时再根据要查找的关键字采用同样的函数计算出哈希地址,然后直接到相应的存储单元中去取要找的数据元素即可。
哈希表(hash table)是实现字典操作的一种有效的数据结构。
尽管最坏的情况下,散列表中查找一个元素的时间与链表中查找的时间相同,达到了O(n)。在一些合理的假设下,在散列表中查找一个元素的平均时间是O(1)。
建立hash建立的过程
1) step1 取数据元素的关键字key,计算其哈希函数值(地址)。若该地址对应的存储空间还没有被占用,则将该元素存入;否则执行step2解决冲突。
2) step2 根据选择的冲突处理方法,计算关键字key的下一个存储地址。若下一个存储地址仍被占用,则继续执行step2,直到找到能用的存储地址为止。
构造哈希函数的方法有很多,总的原则是尽可能将关键字集合空间均匀的映射到地址集合空间中,同时尽可能降低冲突发生的概率。
常用的hash函数:
影响哈希查找效率的一个重要因素是哈希函数本身。当两个不同的数据元素的哈希值相同时,就会发生冲突。为减少发生冲突的可能性,哈希函数应该将数据尽可能分散地映射到哈希表的每一个表项中。
(1)开放地址法
如果两个数据元素的哈希值相同,则在哈希表中为后插入的数据元素另外选择一个表项。
当程序查找哈希表时,如果没有在第一个对应的哈希表项中找到符合查找要求的数据元素,程序就会继续往后查找,直到找到一个符合查找要求的数据元素,或者遇到一个空的表项。
python中的hash(dict)采用的是开放地址法的双哈希函数探测法
(2)链地址法
将哈希值相同的数据元素存放在一个链表中,在查找哈希表的过程中,当查找到这个链表时,必须采用线性查找方法。
推荐:【Python算法】哈希存储、哈希表、散列表原理 - 5_FireFly - 博客园
(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是内置函数,所以可以直接调用.
在信号处理上,反转180度称作卷积,直接滑动计算称作自相关,在大部分深度学习框架上都没有反转180度的操作,而是直接滑动计算卷积。
目前使用得最多的deconvolution有2种。
方法1:full卷积, 完整的卷积可以使得原来的定义域变大
方法2:记录pooling index,然后扩大空间,再用卷积填充
推荐博客:卷积神经网络CNN(1)——图像卷积与反卷积(后卷积,转置卷积)_Fate_fjh的博客-CSDN博客
处理不平衡的方法总的来说可以分为两大类:1. 数据增强,2.损失函数权值均衡
一、数据集方法:1.数据增强,2.过采样和欠采样, 3. 人工数据合成
二、损失函数的权值均衡:1.不同类别的loss 权值不一样,最佳参数需要手动调节 2.focal loss
推荐:处理深度学习中数据集不平衡问题方法汇总_一江明澈的水的专栏-CSDN博客_深度学习数据集不平衡
softmax为什么要用指数作用与神经元的输出(指数函数是一种max的行为可以让大的输出更大)
softmax 主要用于多分类,而sigmoid主要用于二分类;softmax建模使用的分布是多项式分布,而logistic则基于伯努利分布
多个logistic回归通过叠加也同样可以实现多分类的效果,但是 softmax回归进行的多分类,类与类之间是互斥的,即一个输入只能被归为一类;多个logistic回归进行多分类,输出的类别并不是互斥的,即"苹果"这个词语既属于"水果"类也属于"3C"类别。
Softmax训练的深度特征,会把整个超空间或者超球,按照分类个数进行划分,保证类别是可分的,这一点对多分类任务如MNIST和ImageNet非常合适,因为测试类别必定在训练类别中。
但Softmax并不要求类内紧凑和类间分离,这一点非常不适合人脸识别任务,因为训练集的1W人数,相对测试集整个世界70亿人类来说,非常微不足道,而我们不可能拿到所有人的训练样本,更过分的是,一般我们还要求训练集和测试集不重叠。
所以需要改造Softmax,除了保证可分性外,还要做到特征向量类内尽可能紧凑,类间尽可能分离
推荐:
[深度概念]·Softmax优缺点解析_简明AI工作室-CSDN博客_softmax的缺点
推荐:Triplet-Loss原理及其实现、应用_莫失莫忘的博客-CSDN博客_tripletloss
triplet loss 原理以及梯度推导_tangwei2014的专栏-CSDN博客_triplet-loss
卷积和反卷积的作用:卷积与反卷积操作使得神经网络可以处理二维以上的数据。它最大的好处在于:1.保持了数据在空间上的位置信息;2.权重共享使得计算复杂度大大降低。
从两个角度来分类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
tensorflow版本:
构建好图后,使用拓扑算法来决定执行哪一个节点,即对每个节点使用一个计数,值表示所依赖的未完成的节点数目,当一个节点的运算完成时,将依赖该节点的所有节点的计数减一。如果节点的计数为0,将其放入准备队列等待执行。
假设你的机器上有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
手写特点
就是神经网络神经元的初始化类似,根据输入输出的神经元的数量来进行初始化
L1正则和L2正则的比较分析详解_Learning from the mistakes-CSDN博客_l1正则和l2正则的区别
channel shuffle:作者提出把每个组的特征图分为一定组在每一层都进行一定程度的乱序结合,以这样的方式增加特征图的连接融合次数
完全瞄准轻量化这个目标而设计。广泛使用的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。
正是为了解决信息过载(Information overload)的问题,人们提出了推荐系统(与搜索引擎对应,人们习惯叫推荐系统为推荐引擎)。
推荐引擎更倾向于人们没有明确的目的,或者说他们的目的是模糊的,通俗来讲,用户连自己都不知道他想要什么,这时候正是推荐引擎的用户之地,推荐系统通过用户的历史行为或者用户的兴趣偏好或者用户的人口统计学特征来送给推荐算法。
长尾理论(人们只关注曝光率高的项目,而忽略曝光率低的项目)可以很好的解释推荐系统的存在,试验表明位于长尾位置的曝光率低的项目产生的利润不低于只销售曝光率高的项目的利润。推荐系统正好可以给所有项目提供曝光的机会,以此来挖掘长尾项目的潜在利润。
如果说搜索引擎体现着马太效应(会造成越流行的东西随着搜索过程的迭代会越流行,使得那些越不流行的东西石沉大海)的话,那么长尾理论则阐述了推荐系统所发挥的价值。
利用项目的内在品质或者固有属性来进行推荐,建立在项目的内容信息上作出推荐的,而不需要依据用户对项目的评价意见,更多地需要用机器学习的方法从关于内容的特征描述的事例中得到用户的兴趣资料。
基于项目的相似度来通过最近邻获取与目标项目最相似的项目列表,然后把用户没有行为记录并且评分高的项目推荐给特定用户。
通过集体智慧的力量来进行工作,过滤掉那些用户不感兴趣的项目;协同过滤是基于这样的假设:为特定用户找到他真正感兴趣的内容的好方法是首先找到与此用户有相似兴趣的其他用户,然后将他们感兴趣的内容推荐给此用户。
一般采用最近邻技术,利用用户的历史喜好信息计算用户之间的距离,然后利用目标用户的最近邻居用户对商品评价的加权评价值来预测目标用户对特定商品的喜好程度,系统从而根据这一喜好程度来对目标用户进行推荐,通常需要用到UI矩阵的信息。协同过滤推荐又可以根据是否运用机器学习的思想进一步划分为基于内存的协同过滤推荐(Memory-based CF)和基于模型的协同过滤推荐(Model-based CF)。
基于内存的推荐系统(Memory-based CF)主要是通过启发式的方法来进行推荐,主要步骤一个是相似性函数的选择,如何选择合适的相似性函数来更好的度量两个项目或者用户的相似性是关键;另一个主要步骤是如何进行推荐,最简单的推荐方法是基于大多数的推荐策略,即推荐那些大多数人产生过行为而目标用户未产生过行为的项目。
基于模型的协同过滤推荐
基于模型的推荐系统(Model-based CF)主要是运用机器学习的思想来进行推荐,说到机器学习思想那真是不胜枚举
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。