介绍
深度学习基础
representation learning 表示学习
transfer learning 迁移学习
multi-task learning 多任务学习 低层特征共享,产生分支完成各自的任务
end-to-end learning 端到端学习 一步到位,就是一种表示学习
计算机视觉四大基本任务
计算机视觉其他应用
统计学习知识和网络细节
常识
通俗理解的话,离散即分类,连续即回归,回归是有误差度量的,比如5和6差为1,5和7差为2,分类除了分类为5为对其他均为错,误差度量离散二值化了
李宏毅GAN教程:
**Regression-**output a scalar **Classification-**output a “class” **Structured Learning/Prediction-**output a sequence, a matrix , a graph, a tree…
output is composed of components with dependency 带有依赖的元素的组合
Head/Neck/Backbone
输入->主干->脖子->头->输出。主干网络提取特征,脖子提取一些更复杂的特征,然后头部计算预测输出
backbone:主干网络,就代表其是网络的一部分,那么是哪部分呢?这个主干网络大多时候指的是提取特征的网络,其作用就是提取图片中的信息,共后面的网络使用。这些网络经常使用的是resnet、VGG等,而不是我们自己设计的网络,因为这些网络已经证明了在分类等问题上的特征提取能力是很强的。在用这些网络作为backbone的时候,都是直接加载官方已经训练好的模型参数,后面接着我们自己的网络。让网络的这两个部分同时进行训练,因为加载的backbone模型已经具有提取特征的能力了,在我们的训练过程中,会对他进行微调,使得其更适合于我们自己的任务。
head:head是获取网络输出内容的网络,利用之前提取的特征,head利用这些特征,做出预测。
**neck:**是放在backbone和head之间的,是为了更好的利用backbone提取的特征。
bottleneck:**在ResNet中,bottleneck主要是指每个block进来一个特征图现有一个压缩的步骤**,然后3x3卷积,然后再扩张。如果bottleneck是指行为的话,就是指压缩这一行为,如果bottleneck是指特征图的话,就是指压缩后或扩张前的通道数较少的特增图。
GAP:Global Average Pool全局平均池化,就是将某个通道的特征取平均值,经常使用AdaptativeAvgpoold(1),在pytorch中,这个代表自适应性全局平均池化,说人话就是将某个通道的特征取平均值。
Embedding:深度学习方法都是利用使用线性和非线性转换对复杂的数据进行自动特征抽取,并将特征表示为“向量”(vector),这一过程一般也称为“嵌入”(embedding)
False Positive:假阳性,其实这个说法就已经揭示了如何分辨,就比如一个试纸,测出来是阳性,但其实是假的,换句话说就是网络预测出来是真的,其实是假的
3x3的卷积有padding一般是1,5x5的卷积有padding一般是2,7x7的卷积有padding一般是3
归一/标准/正则
Differences between Normalization, Standardization and Regularization
翻译成中文是归一化,标准化,正则化,前两个是特征缩放,最后一个是减少过拟合
Normalization

Standardization
特征缩放,在许多学习算法中,标准化是一种广泛使用的预处理步骤,其目的是将特征缩放到零均值和单位方差:
$$
x^{’}=\frac{x-u}{\sigma}
$$
也是特征缩放,但是更加动态和具有弹性,与整体样本的分布有关,加速收敛
当整体较为集中时,方差更小,标准化后就会更宽松;如果较为宽松,方差更大,标准化后就会变紧。
用这些大数据集的均值和方差,代替真实的均值和方差
coco数据集的均值和方差(三分量顺序是RGB)
mean = [0.471, 0.448, 0.408]
std = [0.234, 0.239, 0.242]
ImageNet数据集的均值和方差(三分量顺序是RGB)
mean = [0.485, 0.456, 0.406]
std = [0.229, 0.224, 0.225]
注意,经过数据标准化之后图像的范围可能就不在[0-1]范围内了
Regularization
正则化,减少过拟合,损失函数后加正则项
贝叶斯学派观点来看,正则项是在模型训练过程中引入了某种模型参数的先验分布[后验由数据得出,先验就是理性推断,不拘束于数据。
范数$L_P-norm$
p=1,曼哈顿距离,p=2,欧式距离,p为无穷,无穷范数或最大范数。
做正则项时,称为Lp-正则项。L1-正则项也叫LASSO正则项,L2-正则项也叫Tikhonov或Ringe正则项
L1正则化主要是在损失函数中添加权重参数的绝对值的和,得到的参数通常比较稀疏,常用于特征选择。L2正则化则是在损失函数中添加权重参数的平方项,得到的模型参数通常比较小。
在这里,我们需要关注的最主要是范数的「非负性」。我们刚才讲,损失函数通常是一个有下确界的函数。而这个性质保证了我们可以对损失函数做最优化求解。如果我们要保证目标函数依然可以做最优化求解,那么我们就必须让正则项也有一个下界。非负性无疑提供了这样的下界,而且它是一个下确界——由齐次性保证[当 c=0 时]
因此,我们说,范数的性质使得它天然地适合作为机器学习的正则项。而范数需要的向量,则是机器学习的学习目标——参数向量。
L0范数表示向量中非零元素的个数
我们考虑这样一种普遍的情况,即:预测目标背后的真是规律,可能只和某几个维度的特征有关;而其它维度的特征,要不然作用非常小,要不然纯粹是噪声。在这种情况下,除了这几个维度的特征对应的参数之外,其它维度的参数应该为零。若不然,则当其它维度的特征存在噪音时,模型的行为会发生预期之外的变化,导致过拟合。引入L0范数
L0范数不好,又引入L1范数,L1范数也可以在梯度更新时使得参数趋于0.
L1使得参数稀疏化,L2使得参数稠密的趋近于0
提前停止
提前停止可看做是时间维度上的正则化。直觉上,随着迭代次数的增加,如梯度下降这样的训练算法倾向于学习愈加复杂的模型。在实践维度上进行正则化有助于控制模型复杂度,提升泛化能力。在实践中,提前停止一般是在训练集上进行训练,而后在统计上独立的验证集上进行评估;当模型在验证集上的性能不在提升时,就提前停止训练。最后,可在测试集上对模型性能做最后测试。
偏差-方差分解
误差来源有三种:随机误差、偏差和方差
随机误差是高斯白噪声
偏差bias描述的是通过学习拟合出来的结果之期望,与真实规律之间的差距,记作$Bias(X)=E[\hat{f}(X)]-f(X)$
方差variance即是统计学中的定义,描述的是通过学习拟合出来的结果自身的不稳定性,记作$Var(X)=E[(\hat{f}(X)-E[\hat{}f(X)])^2]$
均方误差可以分解为:$Bias^2+Variance+Random Error$

VC维
损失函数:度量模型一次预测的好坏
风险函数:度量平均意义下的模型预测好坏
激活函数
激活函数应满足的性质:
- 非线性,这是必须的,也是添加激活函数的原因
- 几乎处处可微:反向传播中,损失函数要对参数求偏导,如果激活函数不可微,那就无法使用梯度下降方法更新参数了。(ReLU只在零点不可微,但是梯度下降几乎不可能收敛到梯度为0)
- 计算简单:神经元(units)越多,激活函数计算的次数就越多,复杂的激活函数会降低训练速度。
- 非饱和性:饱和指在某些区间梯度接近于零,使参数无法更新。Sigmoid和tanh都有这个问题,而ReLU就没有,所以普遍效果更好。因为是链式求导,所以你一个是0乘以其他的还是0,不好。
- 有限的值域:这样可以使网络更稳定,即使有很大的输入,激活函数的输出也不会太大。
sigmoid
$$
\sigma(x)=\frac{1}{1+e^{-x}}\
\sigma’(x)=\sigma(x)[1-\sigma(x)]
$$
易饱和问题:

$x$在大部分范围的梯度都趋近于0,同时该函数单调递增,所以梯度始终>0
非零均值问题:
如果每一层的激活函数都是用$sigmoid$,那么假设有:
$f(x,w,b)=\sigma(\sum w_ix_i+b)$,$x_i$是上一层的输出,这一层的出入。
$w_i$的更新为:$w_i-\alpha \frac{\partial L}{\partial w_i} \to w_i$
$L(x)$对$w_i$求偏导:$\frac{\partial L}{\partial w_i}=\frac{\partial L}{\partial y} \cdot \frac{\partial y}{\partial a}\cdot \frac{\partial a}{\partial w_i}$
$\frac{\partial L}{\partial w_i}=\frac{\partial L}{\partial y}\cdot y(1-y)\cdot x_i$
$y(1-y)>0$,对于$\frac{\partial L}{\partial y}$,设$L=(y_{true}-y)^2/2$,求完导之后:$y-y_{true}$,是个常数,跟具体的某个$w_i$无关,又因为$x_i$是上一层的输出,那么经过$sigmoid$激活之后,$x_i>0$,所以所有的$w_i$更新的方向一致。所有的权重只能一起变大或变小,这样模型收敛就需要消耗很多的时间,如下图所示。

幂运算问题:幂运算相对较为耗时,这个不算太大的问题。
Tanh
Tanh函数是 0 均值的,因此实际应用中 Tanh 会比 sigmoid 更好。但是仍然存在梯度饱和与exp计算的问题。
$$
f(x)=\frac{e^x-e^{-x}}{e^x+e^{-x}}\
f(x)’=1-[f(x)]^2
$$
ReLU
ReLU的Dead ReLU问题
如果某一次权重更新用力过猛,啪的一下,大部分权重都是负的了,下一次前向输出很容易是负的,一激活,就是0,之后就不更新了,就完蛋了
两个原因:1初始化太糟糕 2learning rate设太高导致用力过猛
了解ELU和Maxout,之前的问题解决了,但计算量和参数量会有损失。
输出层选择
输出层的激活函数和损失函数由任务类型决定,见下表。它们与隐藏层的激活函数的选择是独立的。

隐藏层一般就是$ReLU$,至于为什么输出层的激活函数不用$ReLU$呢?输出是$0$到正无穷,没办法分类,你**还得自己设置阈值来确定哪个是哪一类!**输入过来的值是负的的话,所有的输出值都是0,那就没办法区分了。
损失函数
损失函数,就是计算真实分布与预测分布的差异性,差异性越小,损失函数越小,预测的越好
概率与似然
概率大家都比较了解,主要是似然的了解。
在数理统计学中,似然函数(likelihood function)**是一种关于统计模型中的参数的函数,表示模型参数中的似然性**(英语:likelihood)。似然函数在统计推断中有重大作用,如在最大似然估计和费雪信息之中的应用等等。文字意义上,“似然性”与“概率”意思相近,都是指某种事件发生的可能性,但是在统计学中,“似然性”和“概率”(或然性)有明确的区分:==概率,用于在已知一些参数的情况下,预测接下来在观测上所得到的结果;似然性,则是用于在已知某些观测所得到的结果时,对有关事物之性质的参数进行估值,也就是说已观察到某事件后,对相关参数进行猜测。==
在这种意义上,似然函数可以理解为条件概率的逆反。在已知某个参数B时,事件A会发生的概率写作:
$$
P(A|B)=\frac{P(A,B)}{P(B)}
$$
利用贝叶斯定理,
$$
P(B|A)=\frac{P(A|B)P(B)}{P(A)}
$$
因此,我们可以反过来构造表示似然性的方法:已知有事件A发生,运用似然函数$L(B|A)$,我们估计或猜测参数B的不同值的可能性。形式上,似然函数也是一种条件概率函数,但我们关注的变量改变了:
$$
b\to P(A|B=b)
$$
在英语语境里,likelihood 和 probability 的日常使用是可以互换的,都表示对机会 (chance) 的同义替代。但在数学中,probability 这一指代是有严格的定义的,即符合柯尔莫果洛夫公理 (Kolmogorov axioms) 的一种数学对象(换句话说,不是所有的可以用0到1之间的数所表示的对象都能称为概率),而 likelihood (function) 这一概念是由Fisher提出,他采用这个词,也是为了凸显他所要表述的数学对象既和 probability 有千丝万缕的联系,但又不完全一样的这一感觉。中文把它们一个翻译为概率一个翻译为似然也是独具匠心。
概率和似然类似$2^b$和$a^2$,而p(x|θ)
也是一个有着两个变量的函数。如果,你将θ设为常量,则你会得到一个概率函数(关于x的函数);如果,你将x设为常量你将得到似然函数(关于θ的函数)。
有一个硬币,它有θ的概率会正面向上,有1-θ的概率反面向上。θ是存在的,但是你不知道它是多少。为了获得θ的值,你做了一个实验:将硬币抛10次,得到了一个正反序列:x=HHTTHTHHHH。
无论θ的值是多少,这个序列的概率值为 θ⋅θ⋅(1-θ)⋅(1-θ)⋅θ⋅(1-θ)⋅θ⋅θ⋅θ⋅θ = θ⁷ (1-θ)³
比如,如果θ值为0,则得到这个序列的概率值为0。如果θ值为1/2,概率值为1/1024。
但是,我们应该得到一个更大的概率值,所以我们尝试了所有θ可取的值,画出了下图:

这个曲线就是θ的似然函数,通过了解在某一假设下,已知数据发生的可能性,来评价哪一个假设更接近θ的真实值。
==因为这么多种情况偏偏这种情况发生了,肯定是这种情况发生的概率尽可能大,此时的$\theta$就更可能是真实的$\theta$==
如图所示,最有可能的假设是在θ=0.7的时候取到。但是,你无须得出最终的结论θ=0.7。事实上,根据贝叶斯法则,0.7是一个不太可能的取值(如果你知道几乎所有的硬币都是均质的,那么这个实验并没有提供足够的证据来说服你,它是均质的)。但是,0.7却是最大似然估计的取值。
因为这里仅仅试验了一次,得到的样本太少,所以最终求出的最大似然值偏差较大,如果经过多次试验,扩充样本空间,则最终求得的最大似然估计将接近真实值0.5。在这篇博客中有详细的过程,就不再赘述。
信息熵
信息熵是消除不确定性所需信息量的度量。信息熵就是信息的不确定性程度,信息熵越小,信息越确定。
信息熵=$\sum_{x=1}^N$(信息$x$发生的概率$\times$验证信息$x$需要的信息量)
举个列子,比如说:今年中国取消高考了,这句话我们很不确定(甚至心里还觉得这TM是扯淡),那我们就要去查证了,这样就需要很多信息量(去查证);反之如果说今年正常高考,大家回想:这很正常啊,不怎么需要查证,这样需要的信息量就很小。从这里我们可以学到:根据信息的真实分布,我们能够找到一个最优策略,以最小的代价消除系统的不确定性,即最小信息熵。
简而言之,概率越低,需要越多的信息去验证,所以验证真假需要的信息量和概率成反比。我们需要用数学表达式把它描述出来,推导:

信息熵即所有信息量的期望:
$$
H(x)=-\sum_xp(x)log(p(x))=-\sum_{i=1}^Np(x_i)log(p(x_i))
$$
编码层面的解释:
一个事件结果的出现概率越低,对其编码的bit长度就越长。以期在整个随机事件的无数次重复试验中,用最少的 bit 去记录整个实验历史。即无法压缩的表达,代表了真正的信息量。
熵的本质的另一种解释:最短平均编码长度。编码方案完美时,最短平均编码长度。编码方案完美就是指一个事件结果的出现概率越低,对齐编码的bit长度就越长。
假设一个随机变量X的正确分布p如下:
$A:\frac{1}{2}\quad B:\frac{1}{4}\quad C:\frac{1}{4}$
可以简单认为,平均每发送4个符号其中就有2个A,1个B,1个C。因为我们知道信道传输是只能传二进制编码的,所以必须对A、B、C进行编码,根据哈夫曼树来实现,如下所示:
A被编码为0,B被编码为10,C被编码为11。所以每4个字符的平均编码长度为:
$$
\frac{2+2+2}{4}=1.5
$$
那么这个随机变量的信息熵是什么呢?
$H(x)=-1/2log(1/2)-1/4log(1/4)-1/4log(1/4)=1.5$
编码的话以2为底。
交叉熵
有了信息熵的概念后,然后就去看看交叉熵的物理含义。假设我们用一个错误的分布q,对随机变量编码,q的分布如下:
$A:\frac{1}{4}\quad B:\frac{1}{4}\quad C:\frac{1}{2}$
也就是说A被编码为11,B被编码为10,C被编码为0。但是实际上,平均每4个字符还是2个A,1个B,1个C。所以在这种情况下,平均编码长度变成了:
$$
\frac{4+1+2}{4}=1.75
$$
交叉熵此时等于:
$H(p,q)=-1/2log(1/4)-1/4log(1/4)-1/4log(1/2)=1.75$
相对熵
有了交叉熵和信息熵,那么相对熵更好理解了。其实际含义就是用错误分布对随机变量编码时,其产生多余的编码长度。这里就是 $D_{KL}(p||q)=1.75-1.5=0.25$.
相对熵衡量两个概率分布之间的差值,如下:
$$
D_{KL}(p||q)=\sum_{i=1}^Np(x_{i})\cdot (logp(x_i)-logq(x_i))\
=E[logp(x)-logq(x)]\
=\sum_{i=1}^Np(x_{i})\cdot log\frac{p(x_i)}{q(x_i)}\
\quad \quad \quad \quad \quad=\sum_{i=1}^Np(x_{i})logp(x_i)-\sum_{i=1}^Np(x_i)logq(x_i))\
=-H(x)+cross_entropy
$$
在机器学习中,往往$p$用来描述真实分布,$q$用来描述预测分布。
第一行为啥是$p(x_i)$?后面的是他们的信息量,用它们的概率分布,但实际算期望的时候还是要看真实的概率。实际$A,B,C$出现还是要按照真实的概率出现。
实际KL散度算的是预测分布减去真实分布的熵,其实就是错误分布多使用的信息量。
交叉熵,第四行和第五行显示了交叉熵,因为真实分布是确定的,所以H(x)是固定的,交叉熵可以替代KL散度。
总结:😄
信息熵完美编码,
交叉熵不完美编码,
相对熵是两者的差值,交叉熵减去信息熵。差值即差异,也即KL散度。
以上内容参考:
如何通俗的解释交叉熵与相对熵? - erwin的回答 - 知乎
如何通俗的解释交叉熵与相对熵? - 小锋子Shawn的回答 - 知乎
为什么能用交叉熵作为损失函数?
在机器学习中,比如分类问题,如果把结果当作是概率分布来看:
- 标签表示的就是数据真实的概率分布,实际所属类别概率为1,其他类别概率为0。
- 由softmax函数产生的结果其实是对于数据的预测分布,每个类别有一个预测的概率。
按照之前的理解,相当于对于某一张图片分类或语义分割的某一个像素:
真实分布为:$a:1,b:0,c:0,…,z:0$
预测分布为:$a:p_a,b:p_b,c:p_c,…,z:p_z$
二元交叉熵解决sigmoid梯度饱和
与$MSE$对比,对$w$链式求导时:
$MSE=(y_{true}-y)^2/2,\part MSE/\part w_i=(y-y_{true})\cdot \sigma’\cdot x_i$,结果是包含$\sigma’$,这就会导致梯度饱和;
$\part BCE/\part w_i=(y-y_{true})\cdot x_i$,二元交叉熵只包含$\sigma$(即$y$),不包含$\sigma’$,所以缓解了$sigmoid$的梯度饱和问题。
Bootstrapped Cross Entropy Loss
对数损失函数/负对数似然
概率用于在已知参数的情况下,预测接下来的观测结果;似然性用于根据一些观测结果,估计给定模型的参数可能值。数值上相等,意义上不同
$L(\theta|x)=f_\theta(x)=P_\theta(X=x)=P(X=x|\theta)=P(X=x;\theta)$
负对数似然:$L(y)=-log(y)$ 负对数似然常和softmax结合使用,$0<=P<=1$
我们希望得到的概率越大越好,因此概率越接近于1,则函数整体值越接近于0,即使得损失函数取到最小值。
==这里的$P(y_i|x_i)$就是图片为$x_i$,预测出来正好就是正确的对应类别$y_i$的概率。只把这个预测正确的概率加起来。交叉熵损失除了$c_{ii}$为1,别的都为0,就只剩下了$-loga_{ii}$。综上两个都是只把类别预测正确的那个概率加起来了。所以是一致的。==
右边的关键的一步应该是应用大数定律
结构风险本质
结构风险是对经验风险模型复杂度的惩罚
结构化风险(正则项)其实是加入了模型参数分布的先验知识,也就是贝叶斯学派为了将模型往人们期望的地方去发展,继而加入了先验分布,由于是人为的先验,因此也就是一个规则项(这也就是正则项名称的由来)。这样一来,风险函数将进一步考虑了被估计量的先验概率分布
统计学习方法=模型+策略+算法
由决策函数表示的模型为非概率模型,由条件概率表示的模型为概率模型。
当模型是条件概率分布、损失函数是对数损失函数、模型复杂度由模型的先验概率表示时,结构风险最小化就等价于最大后验概率估计。
当模型是条件概率分布,损失函数是对数损失函数时,经验风险最小化就等价于极大似然估计
logsoftmax
首先是softmax公式:
$$
softmax(x)=\frac{e^{x_i}}{\sum_je^{x_i}}
$$
求导如下:

logsoftmax()就是在softmax()之后对结果再多一次log操作:
$$
softmax(x)=log\frac{e^{x_i}}{\sum_je^{x_i}}
$$
求导:

为什么要加一次log呢?
log_softmax能够解决函数上溢出和下溢出的问题,加快运算速度,提高数据稳定性。

由于是指数操作,所以当输入比较大的时候,可能导致上溢出,为啥下溢出?
尽管在数学表示式上是对softmax取对数,但在实操中是通过:

来实现,其中$M=max(x_i),i=1,2,3,…,n$,即$M$为所有$x_i$中最大的值。在加快运算速度的同时,可以保持数值的稳定性。
L1和L2损失函数
L1,又称为LAD:
$$
\sum^n_{i=1}|y_i-f(x_i)|
$$
L2,又称为LSE:
$$
\sum^n_{i=1}(y_i-f(x_i))^2
$$
在大多数情况下,通常首选使用L2损失函数。但是L2收到离群点的影响更大(因为有了平方),所以当出现异常值的时候,L2损失函数的效果就不佳了
评价指标
Precision&Recall


有时候查准率更重要,有时候查全率更重要,一般两者都是越高越好。
机器学习问答
梯度下降or 求导=0
$$
\theta=(X^TX)^{-1}X^TY
$$
使用梯度下降进行线性回归的主要原因是计算复杂性:在某些情况下,使用梯度下降找到解决方案的计算成本较低(较快)。
$(X^TX)^{-1}X^T$是X 的伪逆
数据量很大的情况下求$X^TX$的逆是非常消耗内存以及时间的。
梯度下降为什么不用二阶求导?
a. 牛顿法使用的是目标函数的二阶导数,在高维情况下这个矩阵非常大,计算和存储都是问题。
b. 在小批量的情况下,牛顿法对于二阶导数的估计噪声太大。
c**.目标函数非凸的时候,牛顿法容易受到鞍点或者最大值点的吸引。**
最大的问题就是*计算复杂度。二阶一次迭代更新的复杂度是nn,这在高维的时候是不可行的**
稳定性。越简单的东西往往越robust,对于优化算法也是这样。
二阶求导不易
二阶方法能够更快地求得更高精度的解,但是在神经网络这类深层模型中,不高的精度对模型还有益处,能够提高模型的泛化能力。
优化算法
指数加权平均
$v_t=\beta v_{t-1} + (1-\beta)\theta_t $
指数式递减加权 优势:我们可以看到指数加权平均的求解过程实际上是一个递推的过程,那么这样就会有一个非常大的好处,每当我要求从0到某一时刻(n)的平均值的时候,我并不需要像普通求解平均值的作为,保留所有的时刻值,类和然后除以n。
而是只需要保留0-(n-1)时刻的平均值和n时刻的温度值即可。也就是每次只需要保留常数值,然后进行运算即可,这对于深度学习中的海量数据来说,是一个很好的减少内存和空间的做法。
$v_t=(1-\beta)\theta_t+(1-\beta)\beta\theta_{t-1}+(1-\beta)\beta^2\theta_{t-1}+(1-\beta)\beta^3\theta_{t-2}+…$
形成了指数衰减,所以越靠前的影响就越小,所以$\beta$越大,则相当于平均了过去越多天的信息。
偏差修正:比如$\beta=0.98$,那么$(1-\beta)\times\theta_t$远小于初始值,这会导致刚开始的时候有偏差,刚开始的平均值预测小于实际值,所以需要偏差修正,如下:

应得到绿色曲线,实际得到紫色曲线,偏差修正即$v_t$除以$1-\beta^t$,即$\frac{v_t}{1-\beta^t}$,初始时修正,随着t变大,分母趋向1.
当然很多人不用修正是因为只要熬过初始偏差就好,但是如果关心初始时期的正确率的话,就要用到偏差修正。
动量梯度下降法
momentum:动量
计算梯度的指数加权平均数,并利用该梯度更新你的权重
On iteration t:
Compute $dw$,$db$ on current mini-batch.
$V_{dw}=\beta V_{dw}+(1-\beta)d_w$
$V_{db}=\beta V_{db}+(1-\beta)d_b$
$w=w-\alpha V_{dw}$
$b=b-\alpha V_{db}$
纵轴的摆动被平均了,而横轴一直向右。
我倾向于这么理解,$\beta$和$1-\beta$是质量,而$V_{dw}$和$d_w$是速度,$\beta V_{dw}$是原有动量,而$(1-\beta)d_w$是新加的动量,$\beta$越大,惯性越大,不同左右摇摆,而是垂直落入碗中。
RMSprop
root mean square prop
指数加权平均平方的根

On iteration t:
Compute $d_w,d_b$ on current mini-batch:
$S_{dw}=\beta_2 S_{dw}+(1-\beta_2)d_w^2$
$S_{db}=\beta_2 S_{db}+(1-\beta_2)d_b^2$
$w=w-\alpha \frac{d_w}{\sqrt{S_{dw}+\epsilon}}$
$b=b-\alpha\frac{d_b}{\sqrt{S_{db}+\epsilon}}$
上下抖动大,除以大的变小;左右幅度小,除以小的变大。
Adam
Adaptive Momentum Estimation
相当于将Momentum和RMSprop结合起来,具体公式如下:
$V_{dw}=0,S_{dw}=0,V_{db}=0,S_{db}=0$
On iteration t:
Compute $d_w,d_b$using current mini-batch
$V_{dw}=\beta_1V_{dw}+(1-\beta_1)d_w,V_{db}=\beta_1V_{db}+(1-\beta_1)d_b$
$S_{dw}=\beta_2S_{dw}+(1-\beta_2)d_w^2,S_{db}=\beta_2S_{db}+(1-\beta_2)d_b^2$
$V_{dw}^{corrected}=\frac{V_{dw}}{1-\beta_1^t},V_{db}^{corrected}=\frac{V_{db}}{1-\beta_1^t}$
$S_{dw}^{corrected}=\frac{S_{dw}}{1-\beta_2^t},S_{db}^{corrected}=\frac{S_{db}}{1-\beta_2^t}$
$$
w=w-\alpha\frac{V_{dw}^{corrected}}{\sqrt{S_{dw}}+\epsilon},b=b-\alpha\frac{V_{db}^{corrected}}{\sqrt{S_{db}}+\epsilon}
$$
通常$\beta_1=0.9,\beta_2=0.999,\epsilon=10^{-8}$
学习率设计
learing rate decay
polynominal learning rate
$base\cdot (1-\frac{iter}{max_iter})^{power}$

呈多项式曲线下降
weight decay
Weight decay (commonly called $L2$ regularization), might be the most widely-used technique for regularizing parametric machine learning models.
To penalize the size of the weight vector, we must somehow add $||W||$ to the loss function, but how should the model trade off the standard loss for this new additive penalty? In practice, we characterize this tradeoff via the regularization constant λ, a non-negative hyperparameter that we fit using validation data:
$$
L(w,b)+\frac{\lambda}{2}||w||^2
$$
$$
\begin{split}\begin{aligned} w_1 &\leftarrow \left(1- \eta\lambda \right)w_1 - \frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}}x_1^{(i)} \left(x_1^{(i)} w_1 + x_2^{(i)} w_2 + b - y^{(i)}\right),\ w_2 &\leftarrow \left(1- \eta\lambda \right)w_2 - \frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}}x_2^{(i)} \left(x_1^{(i)} w_1 + x_2^{(i)} w_2 + b - y^{(i)}\right). \end{aligned}\end{split}
$$
可见,$L_2$范数正则化令权重$w_1$和$w_2$先自乘小于1的数,再减去不含惩罚项的梯度。因此,$L_2$范数正则化又叫权重衰减。权重衰减通过惩罚绝对值较大的模型参数为需要学习的模型增加了限制,这可能对过拟合有效。实际场景中,我们有时也在惩罚项中添加偏差元素的平方和。
warm up
为什么warm up策略有效?
warm up策略:在训练最初使用较小的学习率来启动,并很快切换到大学习率而后进行常见的 decay。
这个问题目前还没有被充分证明,我们只能从直觉上和已有的一些论文[1,2,3]得到推测:
- 有助于减缓模型在初始阶段对mini-batch的提前过拟合现象,保持分布的平稳
- 有助于保持模型深层的稳定性
刚开始模型对数据的“分布”理解为零,或者是说“均匀分布”(当然这取决于你的初始化);在第一轮训练的时候,每个数据点对模型来说都是新的,模型会很快地进行数据分布修正,如果这时候学习率就很大,极有可能导致开始的时候就对该数据“过拟合”,后面要通过多轮训练才能拉回来,浪费时间。当训练了一段时间(比如两轮、三轮)后,模型已经对每个数据点看过几遍了,或者说对当前的batch而言有了一些正确的先验,较大的学习率就不那么容易会使模型学偏,所以可以适当调大学习率。这个过程就可以看做是warmup。那么为什么之后还要decay呢?当模型训到一定阶段后(比如十个epoch),模型的分布就已经比较固定了,或者说能学到的新东西就比较少了。如果还沿用较大的学习率,就会破坏这种稳定性,用我们通常的话说,就是已经接近loss的local optimal了,为了靠近这个point,我们就要慢慢来。
mini-batch size较小,样本方差较大。在训练的过程中,如果有mini-batch内的数据分布方差特别大,这就会导致模型学习剧烈波动,使其学得的权重很不稳定,这在训练初期最为明显,最后期较为缓解(所以我们要对数据进行scale也是这个道理)。
局部最优问题

不太可能困在局部最优,而更有可能是鞍点。
鞍点会导致平滑段训练速度减慢,这也是优化算法的作用。
Transformer中改变LayerNorm的位置甚至可以不同warm up
感受野
感受野是个相对概念,某层feature map上的元素看到前面不同层上的区域范围是不同的,通常在不特殊指定的情况下,感受野指的是看到输入图像上的区域。
感受野大小
$$
r_l=r_{l-1}+(k_l-1)\cdot j_{l-1}\
=r_{l-1}+(k_l-1)\cdot \prod_{i=1}^{l-1} s_i
$$
Layer l 一个元素的感受野rl等价于Layer l−1 上k×k 个感受野的叠加;
Layer l−1 上连续k 个元素的感受野可以看成是,第1个元素看到的感受野加上剩余k−1步扫过的范围

如上图,Conv1的感受野是3,Conv2的感受野是5
所有的卷积
卷积
卷积核
- 卷积核默认第三维与输入图片的第三维(通道数)一样,并进行多层卷积,产生一个二维结果
- 1个卷积核产生一个二维结果,n个卷积核产生第三维为n的三维结果
- 卷积核n的个数就是输出的通道数
- 卷积核个数通常为奇数
为什么out_channel要大于in_channel?
Out_channels要能反映图片的多种特征,每个kernel对不同的特征有不同的敏感度
大的卷积核尺寸意味着更大的感受野
1 通用公式
$$
o=\frac{i+2p-k}{s}+1 \
D2=K(filters_num)
$$
https://zhuanlan.zhihu.com/p/512123584 解释,注意o向下取整
2 没有填充,单位步长
$$
s=1,p=0,o=i-k+1
$$
3有零填充,单位步长
3.1same padding
$$
p=0,s=1\
o=i-k+1
$$
3 Half/same padding $p=\lfloor \frac{k}{2}\rfloor$
$$
k=2n+1,n\in N \
s=1,p=\lfloor \frac{k}{2}\rfloor=n\
o=i
$$
3.2 Full padding $p=k-1$
$$
p=k-1,s=1\
o=i+k-1
$$
4 没有零填充,非单位步长
$$
p=0,o=\lfloor\frac{i-k}{s}\rfloor+1
$$
5 零填充,非单位步长 $odd$
$$
o=\lfloor \frac{i+2p-k}{s}\rfloor+1
$$
填充方式有三种:full same valid,一般为零填充
我们平时所接触的卷积其实是滤波,不是真正的数学定义上的卷积。
步长为2的卷积可以看做步长为1的卷积结果的S=2的采样,因此可以认为是下采样的一种。
卷积的性质
普通卷积的计算看起来是挪动,其实不是挪动,效率太低。计算机会将卷积核转换成等效的矩阵,将输入转换为向量。通过输入向量和卷积核矩阵的相乘获得输出向量。输出的向量经过整形便可得到我们的二维输出特征。
在CNN提出之前,我们所提到的人工神经网络应该多数情况下都是前馈神经网络,两者区别主要在于CNN使用了卷积层,而前馈神经网络用的都是全连接层,而这两个layer的区别又在于全连接层认为上一层的所有节点下一层都是需要的,通过与权重矩阵相乘层层传递,而卷积层则认为上一层的有些节点下一层其实是不需要的,所以提出了卷积核矩阵的概念。
如果卷积核的大小是nxm,那么意味着该卷积核认为上一层节点每次映射到下一层节点都只有nxm个节点是有意义的。到这里,有些初学者会认为全连接层也可以做到,只要让权重矩阵某些权重赋值为0就可以实现了,例如假设在计算当前层第2个节点时认为上一层的第1个节点我不需要,那么设置w01=0就可以了。其实没错,卷积层是可以看做全连接层的一种特例,卷积核矩阵是可以展开为一个稀疏的包含很多0的全连接层的权重矩阵。
卷积的key ideas:
局部连接
卷积神经网络有两种神器可以降低参数数目,局部感知野和权值共享。先来说说局部感知也,一般认为人对外界的认知是从局部到全局的,而图像的空间联系也是局部的像素联系较为紧密,而距离较远的像素相关性则较弱。因而,每个神经元其实没有必要对全局图像进行感知,只需要对局部进行感知,然后在更高层将局部的信息综合起来就得到了全局的信息。即,局部感受野指卷积层的神经元只和上一层map的局部相联系。
权值共享
==隐含的原理是:图像中的一部分的统计特性与其他部分是一样的。==
平移不变形Translation Invariance
不变形意味着即使目标的外观发生了某种变化,但是你依然可以把它识别出来。这对==图像分类来说是一种很好的特性,==因为我们希望图像中目标无论是被平移,被旋转,还是被缩放,甚至是不同的光照条件、视角,都可以被成功地识别出来。
还有各种不变形,如旋转/视角不变形 Ration/Viewpoint Invariance 尺度不变性Size Invariance 光照不变性illumination Invariance
==而对于其它问题,比如物体检测(detection)、物体分割(segmentation)来说,这个性质则不应该有,原因是当输入发生平移时,输出也应该相应地进行平移。这种性质又称为平移等价性(translation equivalence)。这两个概念是比较混淆的,但确实是两个不同的东西(敲黑板)。==
图像在平移后再特征图上的表示也是同样平移的,这就使图像拥有了一定的平移不变性。
但有人也提出了反驳:
Why do deep convolutional networks generalize so poorly to small image transformations?
【平移不变性对应的有一个概念是平移同变性(translation equivariance),这个是用在图像的目标检测中的,如果输入图像中的目标进行了平移,那么最终检测出来的候选框应该也相应的移动,这就是同时改变。】
==卷积到底有没有平移不变性?有的说有,有的说没有,我的观点是没有,但两个观点我都会讲明白==
对于卷积,参数共享的特殊形式使得神经网络层具有==平移等变性(equivariance)==。例如,当处理时间序列数据时,这意味着通过卷积可以得到一个由输入中出现不同特征的时刻所组成的时间轴。如果我们把输入中的一个事件向后延时,在输出中仍然会有完全相同的表示,只是时间延后了。也就是说,卷积对输入数据的时刻是敏感的,在输出中有对应的表示。
关于池化,无论采用何种池化函数,当输入作出少量平移时,池化能帮助输入的表示近似不变(invariant)**。对于平移的不变性是指当我们对输入进行少量平移时,经过池化函数后的大多数输出并不会发生改变**。这意味着==池化对特征位置不敏感,只有当我们不关心特征具体出现的位置时,池化才是合理的,这正是胶囊网络的动机之一。==
==总结来说,CNN 中的卷积操作具有平移等变性,但池化操作具有局部平移不变性。两者矛盾地统一于 CNN 中。胶囊网络完全去掉了池化操作,达到了对平移等变性的追求。==
为什么说近似不变?
平移小鸟位置的时候,预测结果是有很大的波动


差距很大
平移不变性的公式
$$
U(D(X))=U(D(X_{shift}))
$$

回不去了
如何实现平移不变性:
==全局平均池化,消除了位置的影响==
转置卷积
1 p=0,s=1
$$
p=0,s=1\
k’=k,s’=s,p’=k-1\
o’=i’+(k-1)
$$
2 s=1
$$
s=1\
p’=k-p-1\
o’=i’+(k-1)-2p
$$
3 Half/same padding
$$
k=2n+1,n\in N,s=1,p=\lfloor\frac{k}{2}\rfloor=n\
k’=k,s’=s,p’=p\
o’=i’
$$
4 Full padding
$$
s=1,p=k-1\
k’=k,s’=s,p’=0\
o’=i’-(k-1)
$$
5 p=0 ,non-unit strides
$$
p=0,(i-k)%s=0\
k’=k,s’=1,p’=k-1\
o’=s(\widetilde{i}’-1)+k\
\widetilde{i}’ :adding,s-1,zeros,between,each,input,unit
$$
6 zero-padding,non-unit strides
$$
(i+2p-k)%s=0\
k’=k,s’=1,p’=k-p-1\
o’=s(i’-1)+k-2p
$$
7 zero-padding,non-unit strides odd
$$
k’=k,s’=1,p’=k-p-1\
a=(i+2p-k)%s\
o’=s(i’-1)+a+k-2p
$$
也叫反卷积/分数步长卷积
先说一下为什么人们很喜欢叫转置卷积为反卷积或逆卷积。首先举一个例子,将一个4x4的输入通过3x3的卷积核在进行普通卷积(无padding, stride=1),将得到一个2x2的输出。而转置卷积将一个2x2的输入通过同样3x3大小的卷积核将得到一个4x4的输出,看起来似乎是普通卷积的逆过程。就好像是加法的逆过程是减法,乘法的逆过程是除法一样,人们自然而然的认为这两个操作似乎是一个可逆的过程。但事实上两者并没有什么关系,操作的过程也不是可逆的。


转置卷积公式
空洞/扩张卷积

扩张卷积增加了感受野,而不增加核的大小,因为中间插入的是空格,需要训练的卷积核参数量是不变的。
卷积核大小为k,dilation_rate=d,扩张后的卷积大小如下:
$$
\hat{k} = k + (k − 1)(d − 1)
$$
则
$$
o = \lfloor\frac{i+2p-\hat{k}}{s}\rfloor+1
$$
空洞卷积的作用
- 不丢失分辨率的情况下扩大感受野:在deep net中为了增加感受野且降低计算量,总要进行降采样(pooling或s2/conv),这样虽然可以增加感受野,但空间分辨率降低了。为了能不丢失分辨率,且仍然扩大感受野,可以使用空洞卷积。这在检测,分割任务中十分有用。一方面感受野大了可以检测分割大目标,另一方面分辨率高了可以精确定位目标。
- 调整扩张率获得多尺度上下文信息:空洞卷积有一个参数可以设置dilation rate,具体含义就是在卷积核中填充dilation rate-1个0,因此,当设置不同dilation rate时,感受野就会不一样,也即获取了多尺度信息。多尺度信息在视觉任务中相当重要啊。
- ps: 空洞卷积虽然有这么多优点,但在实际中不好优化,速度会大大折扣。
空洞卷积gridding问题
- 局部信息丢失:由于空洞卷积的计算方式类似于棋盘格式,某一层得到的卷积结果,来自上一层的独立的集合,没有相互依赖,因此该层的卷积结果之间没有相关性,即局部信息丢失。
- 远距离获取的信息没有相关性:由于空洞卷积稀疏的采样输入信号,使得远距离卷积得到的信息之间没有相关性,影响分类结果。
1x1卷积/Network in Network
feature map是卷积核卷出来的,一个卷积核卷出来一个feature,所有feature构成featuremap,feature map数量就是channels
作用:
- 进行卷积核通道数的降维和升维
- 实现跨通道的交互和信息整合
- 增加非线性特性
Inception中:
原图feature map:28x28x192 1x1 channel:64 3x3 channel:128 5x5 channel:32
左:$192 × (1×1×64) +192 × (3×3×128) + 192 × (5×5×32) = 387072$
右:$192 × (1×1×64) +(192×1×1×96+ 96 × 3×3×128)+(192×1×1×16+16×5×5×32)= 157184$
对于右边的池化层,原始的不能降channel,然后就会越来越多,这样也可以用1x1降channel
ResNet:
假设输入输出都是256 channel,参数真的差太多了!
左:$3 × 3 ×256×256×2=1179648$
右:$ 1×1×256×64 + 3×3×64×64 + 1×1×64×256 = 69632$
全连接层角度:

原channel 6,之后channel 5,只需要一个1x1x5的卷积核就行,参数很少,FC至少$w_0\cdot h_0 \cdot 6\cdot w_1\cdot h_1\cdot 5$
In Convolutional Nets, there is no such thing as “fully-connected layers”. There are only convolution layers with 1x1 convolution kernels and a full connection table-Yann LeCun
Separable Convlution
two main types:spatial separable conv and depthwise separable conv
spatial separable conv:
illustrates the idea of separating one convolution into two well,but have significant limitations,so not heavily used
这么命名是因为主要处理spatial dimensions:the width and the height.The other dimension, the “depth” dimension, is the number of channels of each image
一个kernel分解成两个更小的kernel,eg:

9次乘法下降到6次,网络运行速度更快。
主要的问题就是并不是所有的卷积核都可以分离,导致的结果就是所有可能分离的卷积中最终只有小部分可以分离。
depthwise separable conv:
更适用。This is the type of separable convolution seen in keras.layers.SeparableConv2D
or tf.layers.separable_conv2d
.
The depthwise separable convolution is so named because it deals not just with the spatial dimensions, but with the depth dimension — the number of channels — as well. An input image may have 3 channels: RGB. After a few convolutions, an image may have multiple channels. You can image each channel as a particular interpretation of that image; in for example, the “red” channel interprets the “redness” of each pixel, the “blue” channel interprets the “blueness” of each pixel, and the “green” channel interprets the “greenness” of each pixel. An image with 64 channels has 64 different interpretations of that image.
和spatial separable conv类似,depthwise separable conv将一个kernel分成两个kernel做两次卷积:the depthwise conv and the pointwise conv.
depthwise conv:

For an image:12x12x3,to get an output with size 8x8x3.正常的卷积需要5x5x3x3,对于depthwise conv,则需要5x5x1x3,channel之间不交互。
Pointwise conv:
但是如果我们需要8x8x256,那么就需要提升channel了。
The pointwise convolution is so named because it uses a 1x1 kernel, or a kernel that iterates through every single point. This kernel has a depth of however many channels the input image has; in our case, 3. Therefore, we iterate a 1x1x3 kernel through our 8x8x3 image, to get a 8x8x1 image.We can create 256 1x1x3 kernels that output a 8x8x1 image each to get a final image of shape 8x8x256.
What’s the point of creating a depthwise separable convolution?
参数量:$19200\to843$,乘法次数:$1228800\to53952$
池化
池化一般不涉及零填充
$$
o=\lfloor\frac{i-k}{s}\rfloor+1
$$
图像中的相邻像素倾向于具有相似的值,因此通常卷积层相邻的输出像素也具有相似的值。这意味着,卷积层输出中包含的大部分信息都是冗余的。
如果我们使用边缘检测滤波器并在某个位置找到强边缘,那么我们也可能会在距离这个像素1个偏移的位置找到相对较强的边缘。但是它们都一样是边缘,我们并没有找到任何新东西。
池化层解决了这个问题。这个网络层所做的就是通过减小输入的大小降低输出值的数量。
池化一般通过简单的最大值、最小值或平均值操作完成。
最大池化可以提取特征纹理
平均池化可以保留背景信息。
综述:最大池化,平均池化,全局最大池化和全局平均池化?区别原来是这样
上采样
三种方法:
- 基于线性插值的上采样
- 基于深度学习的上采样(转置卷积)
- Unpooling的方法 简单的补0或扩充
线性插值
双线性插值?
应用:
- 对数据中的缺失进行合理补偿
- 对数据进行放大或缩小
- 其他
根据下式计算目标像素在源图像中的位置:
$$
srcX=dstX\cdot \frac{srcWidth}{dstWidth}\
srcY=dstY\cdot \frac{srcHeight}{dstHeight}
$$
单线性插值:单变量只有一个x,对y进行插值,线性插值原理是两个点可以确定一条直线,又可以根据x确定y
$$
\frac{y-y_0}{x-x_0}=\frac{y_1-y_0}{x_1-x_0}\
y=\frac{x_1-x}{x_1-x_0}y_0+\frac{x-x_0}{x_1-x_0}y_1\
y=k\cdot y0+(1-k)\cdot y_1 \quad \quad
$$
双线性插值:有两个变量x、y,分别在x、y两个方向进行插值
对于一个目的像素,设置坐标通过反向变换得到的浮点坐标为$(i+u,j+v)$(其中$i、j$均为浮点坐标的整数部分,$u、v$为浮点坐标的小数部分,是取值[0,1)区间的浮点数),则这个像素得值$f(i+u,j+v)$可由原图像中坐标为$(i,j)(i+1,j)(i,j+1)(i+1,j+1)$所对应的周围四个像素的值决定,即:$f(i+u,j+v) = (1-u)(1-v)f(i,j) + (1-u)vf(i,j+1) + u(1-v)f(i+1,j) + uvf(i+1,j+1)$,在哪个方向离得近,比如距离是0.3,权重大,是0.7
现在假如目标图的象素坐标为$(1,1)$,那么反推得到的对应于源图的坐标是$(0.75,0.75)$, 这其实只是一个概念上的虚拟象素,实际在源图中并不存在这样一个象素,那么目标图的象素$(1,1)$的取值不能够由这个虚拟象素来决定,而只能由源图的这四个象素共同决定:$(0,0)(0,1)(1,0)(1,1)$,而由于$(0.75,0.75)$离$(1,1)$要更近一些,那么$(1,1)$所起的决定作用更大一些,这从公式1中的系数$uv=0.75×0.75$就可以体现出来,而$(1,1)$离$(0.75,0.75)$最远,所以$(0,0)$所起的决定作用就要小一些,公式中系数为$(1-u)(1-v)=0.25×0.25$也体现出了这一特点。
import numpy as np#矩阵运算最简单,所以最重要的是坐标如何对应!
a=np.array([[0.75,0.25]])
b=np.array([[1,3],#注意2和3位置反过来了
[2,4]])
c=np.array([[0.25],
[0.75]])
d=np.dot(a,b)
e=np.dot(d,c)
print(d)
print(e)
----------------------
>>> input = torch.arange(1, 5, dtype=torch.float32).view(1, 1, 2, 2)
>>> input
tensor([[[[ 1., 2.],
[ 3., 4.]]]])
>>> m = nn.Upsample(scale_factor=2, mode='nearest')
>>> m(input)
tensor([[[[ 1., 1., 2., 2.],
[ 1., 1., 2., 2.],
[ 3., 3., 4., 4.],
[ 3., 3., 4., 4.]]]])
>>> m = nn.Upsample(scale_factor=2, mode='bilinear') # align_corners=False
>>> m(input)
tensor([[[[ 1.0000, 1.2500, 1.7500, 2.0000],
[ 1.5000, 1.7500, 2.2500, 2.5000],
[ 2.5000, 2.7500, 3.2500, 3.5000],
[ 3.0000, 3.2500, 3.7500, 4.0000]]]])
>>> m = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)
>>> m(input)
tensor([[[[ 1.0000, 1.3333, 1.6667, 2.0000],
[ 1.6667, 2.0000, 2.3333, 2.6667],
[ 2.3333, 2.6667, 3.0000, 3.3333],
[ 3.0000, 3.3333, 3.6667, 4.0000]]]]
第一种,四个角对齐,均匀插值,公式:
$$
scale = (input_size-1)/(output_size-1)\
srcIndex=scale\cdot dstIndex
$$
第二种,不均匀,出界的只和有原坐标的算,公式:
$$
scale=input_size/output_size\
srcIndex=scale\cdot (dstIndex+0.5)-0.5
$$
深度学习
PixelShuffle
Normalization
Batch Normalization
直译过来就是批归一化。
激活之前进行BN,增加了两个学习参数scale和shift,再从线性变到非线性
有轻微的正则化作用,因为使用mint-batch,不同的mini-bath不同,所以会有一些噪音,所以有轻微的正则化效果
测试时逐样本处理,batch norm从之前训练时的$\mu$和$\sigma$做指数加权平均,方式很多,反正是从训练集得到的
第一节:Batchnorm主要解决的问题
深度神经网络主要就是为了学习训练数据的分布,并在测试集上达到很好的泛化效果。但是:
- 如果我们每一个batch输入的数据都具有不同的分布,显然会给网络的训练带来困难
- 数据经过一层层网络计算后,其数据分布也在发生着变化,此现象称为Internal Covariate Shift.
1.1 Internal Covariate Shift
首先Internal Covariate Shift是指训练深度网络的时候经常发生训练困难的问题,因为,每一次参数迭代更新后,上一层网络的输出数据经过这一层网络计算后,数据的分布会发生变化,为下一层网络的学习带来困难(神经网络本来就是要学习数据的分布,要是分布一直在变,学习就很难了)
1.2 Covariate Shift
Internal Covariate Shift和Covariate Shift是不同的,差就差在这个Internal,一个发生在神经网络内部,一个发生在输入数据上
==BatchNorm是归一化的一种手段,减小图像之间的绝对差异,突出相对差异==
举个例子,如下图所示:

假定当前输入$x1$和$x2$的分布如图中圆点所示,本次更新的方向是将直线$H_1$更新成$H_2$,本以为切分得不错,但是当前面层的权重更新完毕,当前层输入的分布换成了另外一番样子,直线相对输入分布的位置可能变成了$H_3$,下一次更新又要根据新的分布重新调整。直线调整了位置,输入分布又在发生变化,直线再调整位置,==就像是直线和分布之间的“追逐游戏”。==对于浅层模型,比如SVM,输入特征的分布是固定的,即使拆分成不同的batch,每个batch的统计特性也是相近的,因此只需调整直线位置来适应输入分布,显然要容易得多。而深层模型,每层输入的分布和权重在同时变化,训练相对困难。
第二节:Batchnorm 原理解读
为了减小Internal Covariate Shift,对神经网络的每一层做归一化不就可以了,假设将每一层输出后的数据都归一化到0均值,1方差,满足正态分布,但是,此时有一个问题,每一层的数据分布都是标准正态分布,导致其完全学习不到输入数据的特征,因为,费劲心思学习到的特征分布被归一化了,因此,直接对每一层做归一化显然是不合理的。但如果加上可学习的参数就好多了。
如果batch size为$m$,则在前向传播过程中,网络中每个节点都有$m$个输出,所谓的Batch Normalization,就是对该层每个节点的这$m$个输出进行归一化再输出,具体计算方式如下:

$\gamma$和$\beta$为待学习的scale和shift参数,用于控制$y_i$的方差和均值。==这样的话就是具有不同均值和方差的正态分布了,有利于权重和分布的相互协调==
第三节:BatchNorm实现
第四节:Batchnorm的优点
- 可以使用更大的学习率,训练过程更加稳定,极大提高了训练速度。
- 可以将bias置为0,因为Batch Normalization的Standardization过程会移除直流分量,所以不再需要bias。
- 权重初始化不再敏感,通常权重采样自0均值某方差的高斯分布,以往对高斯分布的方差设置十分重要,有了Batch Normalization后,对与同一个输出节点相连的权重进行放缩,其标准差σ也会放缩同样的倍数,相除抵消。
- 对权重的尺度不再敏感,理由同上,尺度统一由γ参数控制,在训练中决定。
- 深层网络可以使用sigmoid和tanh了,理由同上,BN抑制了梯度消失。
- Batch Normalization具有某种正则作用,不需要太依赖dropout,减少过拟合。
什么时候不能用BN?

==BN是保留Channel,在N,H,W上做操作==
肯定是batch size越大,使用BN的效果越好。为什么BN不做channel只做NHW,可能是因为每个channel都对应之前一个卷积核,逐channel代表逐卷积核的输出做归一化。
Group Normalization
- BN依赖于batch size,batch size较小时,BN效果不好,有些任务往往batch size只有1-2
- 训练,验证,测试这三个阶段存在inconsistency。
Layer Norm和Instance Norm就是Group Norm的特例,归一化避开了batch。
为什么工作?个人理解,每一层有很多的卷积核,这些核学习到的特征并不完全是独立的,某些特征具有相同的分布,因此可以被group。
Instance Norm
Instance Normalization(IN),一种更适合对单个像素有更高要求的场景的归一化算法(IST,GAN等)。IN的算法非常简单,计算归一化统计量时考虑单个样本,单个通道的所有元素。
对于图像风格迁移任务来说,每个样本的每个信息点都是非常重要的。对于BN对整个batch做归一化,可能造成每个样本独特细节的丢失;对于LN,忽略了不同通道之间的差异。
Layer Norm

均值为0,方差为1,只对最后的C进行归一化
网络权重初始化
如何判断模型收敛
特征融合
很多工作通过融合多层来提升检测和分割的性能,按照融合与预测的先后顺序,分类为早融合(Early fusion)和晚融合(Late fusion)。
Early fusion
先融合多层的特征,然后在融合后的特征上训练预测器(只在完全融合之后,才统一进行检测)。这类方法也被称为skip connection,即采用concat、add操作。这一思路的代表是Inside-Outside Net(ION)和HyperNet。
- concat
- add
Late fusion
同过结合不同层的检测结果改进检测性能(尚未完成最终的融合之前,在部分融合的层上就开始进行检测,会有多层的检测,最终将多个检测结果进行融合)。
代表思路有两种:
- feature不融合,多尺度的feture分别进行预测,然后对预测结果进行综合,如Single Shot MultiBox Detector (SSD) , Multi-scale CNN(MS-CNN)
- feature进行金字塔融合,融合后进行预测,如Feature Pyramid Network(FPN)等。
接下来主要归纳晚融合方法
多尺度设计
判断函数是否收敛?
两个算法,batch_size为4,epoch为30和batch_size为8,epoch为60,不同的算法是否有对应的大小关系呢?
主要是看两个,第一个epoch多少是否有影响,要看函数是否收敛?
第二个batch_size不同,要看是否能收敛到最小点,batch_size小容易收敛到鞍点,大的话容易收敛到最小点。
反向传播
back propagation传播,扩展
MLP

$x_1,x_2$是一个独立样本的两个维度,如果样本的维度是15维,那么MLP输入层的神经元就有15个。
链式法则-BP的基础
假设我们现在更新$w_1$,那么就要求$\frac{\partial E}{\partial w_1}$
$$
\frac{\partial E}{\partial w_1}=\frac{\partial E}{\partial y}\cdot \frac{\partial y}{\partial h_1}\cdot \frac{\partial h_1}{\partial w_1}
$$
最开始是损失函数,做分子的只能是神经元的值,参数只能做分母.
这里面还有激活函数,如果$y=\sigma(w_1x+b_1)$直接展开,那么就是$\frac{\partial y}{\partial w_1}$,如果看成是两步$y=\sigma(a),a=w_1x+b_1$,则为$\frac{\partial y}{\partial a}\cdot\frac{\partial a}{\partial w_1}$根据链式法则,算出来是一样的。
例子:$y=3a^2+1,a=3x+1$,算出来都是$54x+18$(如果是对$x$求偏导)
为什么现在是对$w$和$b$求导?
因为现在$x$和$y$数据已知,就像极大似然估计一样,现在是把$w$和$b$看做参数来反推$w$和$b$,所以需要对$w$和$b$求导。
CNN
池化
池化层一般对应在卷积层的后面,属于一对一的关系(它只影响当前深度的一个节点),不与其它卷积核做连接,所以没有权重参数需要学习。所以反向传播的时候,只需对输入参数求导,不需要进行权值更新。
对于最大池化和平均池化,也有不同:教程


Self attention与Transformer
直接看上面这篇文章
The Illustrated Transformer的翻译参考
A High-level Lokok
Transformer中的编码器是完全结构相同的,但是并不共享参数,每一个编码器都可以拆解成以下两个子部分:

解码器同样也有这些子层,但是在两个子层间增加了attention层,该层有助于解码器能够关注到输入句子的相关部分,与 seq2seq model 的Attention作用相似。

Bringing The Tensors Into the Picture
正如NLP应用的常见例子,先将输入单词使用embedding algorithm转成向量。

词的向量化仅仅发生在最底层的编码器的输入时,这样每个编码器的都会接收到一个list(每个元素都是512维的词向量),只不过其他编码器的输入是前个编码器的输出。list的尺寸是可以设置的超参,==通常是训练集的最长句子的长度==。
在对输入序列做词的向量化之后,它们流经编码器的如下两个子层:

这里能看到Transformer的一个关键特性,==每个位置的词仅仅流过它自己的编码器路径。在self-attention层中,这些路径两两之间是相互依赖的。前向网络层则没有这些依赖性,但这些路径在流经前向网络时可以并行执行。==
Now We’re Encoding !
正如之前所提,编码器接收向量的list作输入。然后将其送入self-attention处理,再之后送入前向网络,最后将输入传入下一个编码器。

每个位置的词向量被送入self-attention模块,然后是前向网络(对每个向量都是完全相同的网络结构)。
Self-Attention at a High Level
不要被self-attention这个词迷惑了,看起来好像每个人对它都很熟悉,但是在我读到Attention is All You Need这篇文章之前,我个人都没弄懂这个概念。下面我们逐步分解下它是如何工作的。
以下面这句话为例,作为我们想要翻译的输入语句“The animal didn’t cross the street because it was too tired”。句子中”it”指的是什么呢?“it”指的是”street” 还是“animal”?对人来说很简单的问题,但是对算法而言并不简单。
当模型处理单词“it”时,self-attention允许将“it”和“animal”联系起来。==当模型处理每个位置的词时,self-attention允许模型看到句子的其他位置信息作辅助线索来更好地编码当前词。==如果你对RNN熟悉,就能想到RNN的隐状态是如何允许之前的词向量来解释合成当前词的解释向量。Transformer使用self-attention来将相关词的理解编码到当前词中。

Self-Attention in Detail
我们先看下如何计算self-attention的向量,再看下如何以矩阵方式计算。
第一步,==根据编码器的输入向量,生成三个向量==,比如,对每个词向量,生成$query$, $key$, $value$三个vector
生成方法为分别乘以三个矩阵,这些矩阵在训练过程中需要学习。【注意:==不是每个词向量独享3个matrix,而是所有输入共享3个转换矩阵;==权重矩阵是基于输入位置的转换矩阵;有个可以尝试的点,如果每个词独享一个转换矩阵,会不会效果更厉害呢?】
注意到这些新向量的维度比输入词向量的维度要小(512–>64),并不是必须要小的,是为了让多头attention的计算更稳定。

第二步,计算attention就是计算一个分值。对“Thinking Matchines”这句话,对“Thinking”(pos#1)计算attention 分值。我们需要计算每个词与“Thinking”的评估分,这个分决定着编码“Thinking”时(某个固定位置时),每个输入词需要集中多少关注度。
==这个分,通过“Thing”对应query-vector与所有词的key-vec依次做点积得到。==所以当我们处理位置#1时,第一个分值是q1和k1的点积,第二个分值是q1和k2的点积。

每个是一个Vector,可以用矩阵加速计算
第三步和第四步,除以8($d_k$,为query和key向量的维度),这样梯度会更稳定。然后加上softmax操作,归一化分值使得全为正数且加和为1。

softmax分值决定着在这个位置,每个词的表达程度(关注度)。很明显,这个位置的词应该有最高的归一化分数,但大部分时候总是有助于关注该词的相关的词。
第五步,将softmax分值与value-vec按位相乘。==保留关注词的value值,削弱非相关词的value值。==
第六步,将所有加权向量加和,产生该位置的self-attention的输出结果。

上述就是self-attention的计算过程,生成的向量流入前向网络。在实际应用中,上述计算是以速度更快的矩阵形式进行的。下面我们看下在单词级别的矩阵计算。
Matrix Calculation of Self-Attention
第一步是计算Query,Key和Value矩阵。 为此,我们将embeddings堆叠成矩阵X,然后将其乘以我们训练过的权重矩阵(WQ,WK,WV)。

X矩阵中的每一行对应于输入句子中的一个单词。
最后,由于我们要处理矩阵,因此我们可以将步骤2到6压缩成一个公式,以计算self attention layer的输出。

The Beast With Many Heads
本文通过添加一种称为“多头”注意力的机制,进一步完善了self attention layer。 这样可以通过两种方式提高attention layer的性能:
- 它==扩展了模型专注于不同位置的能力==。在上面的例子中,==z1只包含了其他所有encoding的一点点,但是它很可能由实际该单词本身主导==。如果我们要翻译这样的句子: “The animal didn’t cross the street because it was too tired”,那么我们会想知道”it”指什么,多头注意力很有用。
- 它为关注层提供了多个“表示子空间”。正如我们接下来要看到的,在multi-headed attention下有多组Query/Key/Value的权重matrix,而非仅仅一组(论文中使用8-heads)。每一组都是随机初始化,==然后,在训练之后,将每组用于将input embeddings(或 vectors from lower encoders/decoders)投影到不同的表示子空间representation subspace中。==

为每个头维护单独的$W_Q$,$W_K$和$W_V$,与$X$乘完之后获得$Q$,$K$,$V$
如果我们执行与上面的概述相同的self attention计算,我们最终将得到八个不同的$Z$矩阵

这给我们带来了一些挑战。==前馈层不希望有8个矩阵,它只要一个矩阵(a vector for each word)==。因此,我们需要一种将这8个矩阵压缩为1个矩阵的方法。
==我们该怎么做?concat 然后乘以额外的权重矩阵==$W_O$

这就是multi-headed self attention的全部。 我知道,矩阵很多。 让我尝试将它们全都放在一个视觉中,以便我们可以在一处查看它们。

Representing The Order of The Sequence Using Positional Encoding
扩散模型
参考:
https://segmentfault.com/a/1190000043744225
https://zhuanlan.zhihu.com/p/563661713
马尔科夫链
马尔科夫链定义本身比较简单,它假设某一时刻状态转移的概率只依赖于它的前一个状态。
$p(z^{m+1}|z^{1},…,z^{m})=p(z^{m+1}|z^{m})$
具有马尔可夫性的随机序列$X={X_0,X_1,…,X_T,… }$称为马尔可夫链,或马尔可夫过程。
DDPM
扩散过程
总共包含$T$ 步的扩散过程的每一步都是对上一步得到的数据$x_{t-1}$按如下方式增加高斯噪音
$$
q(x_t|x_{t-1})=N(x_t;\sqrt{1-\beta_t}x_{t-1},\beta_t I)
$$
这边这个分号前的$x_t$应该是意味着是关于$x_t$,后面两个分别是均值和方差。${\beta_t}^{T}_{t=1}$是每一步所采用的方差,介于0-1之间。
对于扩散模型,我们往往称不同step的方差设定为variance schedule或者noise schedule,通常情况下,越后面的step会采用更大的方差,即满足$\beta_1<\beta_2<…<\beta_T$。
在一个设计好的variance schedule下,的如果扩散步数$T$足够大,那么最终得到的$X_T$就完全丢失了原始数据而变成了一个随机噪音。 扩散过程的每一步都生成一个带噪音的数据$x_t$,整个扩散过程也就是一个马尔可夫链:
$$
q(x_{1:T}|x_0)=\prod_{t=1}^Tq(x_t|x_{t-1})
$$
$q(x_2|x_1)\times q(x_1|x_0) = q(x_2|x_0) $,利用条件概率和马尔克夫的定义严格证明我还不会,但是对当前这个条件,$q(x_t|x_{t-1})= N(x_t;\sqrt{1-\beta_t}x_{t-1},\beta_tI)$,当前这个确实满足啊~
上面好像是错误的,$x_{1:T}$好像是代表一个联合分布
条件概率的一般形式:
$1:P(A,B,C)=P(C|BA)P(B,A)=P(C|BA)P(B|A)P(A)$
$2: P(B,C|A)=P(B|A)P(C|A,B)$
推导:$P(BC|A)=P(ABC)/P(A)=P(C|AB)P(AB)/P(A)=P(C|AB)\times P(B|A) $
马尔可夫概率的一般形式:
$1:P(A,B,C)=P(C|BA)P(B,A)=P(C|B)P(B|A)P(A)$
$2: P(B,C|A)=P(B|A)P(C|B)$
扩散过程的一个重要特性是我们可以直接基于原始数据$x_0$来对任意$t$步的$x_t$进行采样。

从前一步采样,如何从$x_{t-1}$直接算出来$x_t$呢,这一步公式是关键,$x_t=\sqrt{1-\beta_t}x_{t-1}+\sqrt{\beta_t}\epsilon$,相当于对原图像乘以一个值,然后加上一个正态分布,其实相当于对$x_{t-1}$逐点进行高斯采样,采样就是以当前点的值为均值,方差为$\beta_t$,即$x_t\sim N(\sqrt{1-\beta_t}x_{t-1},\beta_tI)$.
$\sqrt{\bar{a}_t}$和$\sqrt{1-\bar{a}_t}$分别称为signal_rate和noise_rate,随着$\beta$增大,分别趋向0和1
反向过程
去噪声操作的数学形式是怎么样的?怎么让神经网络来学习它呢?数学原理表明,当$\beta_t$足够小时,每一步加噪声的逆操作也满足正态分布。
$$
x_{t-1} \sim N(\tilde{\mu_t},\tilde{\beta_t}I)
$$
为了描述所有去噪声操作,神经网络应该根据当前的时刻$t$、当前的图像$x_t$,拟合当前时刻的加噪声逆操作的正态分布,也就是拟合当前的均值$\tilde{\mu}_t$和方差$\tilde{\beta_t}$。
加噪声的逆操作不太可能从理论上求得,我们只能用一个神经网络去拟合它。去噪声操作和加噪声逆操作的关系,就是神经网络的预测值和真值的关系。
$$
q(x_{t-1}|x_t,x_0)=q(x_t|x_{t-1},x_0)\frac{q(x_{t-1}|x_0)}{q(x_t|x_0)}
$$
推导:
$$
q(x_{t-1}|x_t,x_0)=\frac{q(x_{t-1},x_t,x_0)}{q(x_t,x_0)}\
=\frac{q(x_t|x_{t-1},x_0)\times q(x_{t-1}|x_{0})\times q(x_0)}{q(x_t,x_0)}\
=q(x_t|x_{t-1},x_0)\frac{q(x_{t-1}|x_0)}{q(x_t|x_0)}
$$
原来如此~

神经网络拟合均值时,$x_t$是已知的(别忘了,图像是一步一步倒着去噪的)。式子里唯一不确定的只有$\epsilon$,所以干脆拟合噪声,所以最终噪声的误差函数可写成:
$$
L=||\epsilon_t-\epsilon_\theta(x_t,t)||^2
$$
DDIM
看了半天看不懂,简单总结
找到了一种能满足DDPM逆向条件,且能减少采样步骤的逆向公式:
$$
q_{\sigma}(x_{1:T}|x_0)=q_{\sigma}(x_{T}|x_0)\prod^t_{t=2}q_{\sigma}(x_{t-1}|x_t,x_0)\
=N(x_{t-1};\sqrt{\bar{\alpha}_{t-1}}x_0+\sqrt{1-\bar{\alpha}_{t-1} -\sigma^2_t}\cdot \frac{x_t-\sqrt{\bar{\alpha}_t}x_0}{\sqrt{1-\bar{\alpha}_t}},\sigma^2_tI)
$$
或者是这样:

Conditional Diffusion Models
训练的时候,sample $(x_0,\tilde{x})\sim q(x_0,\tilde{x})$从成对的数据分布,如一个clean和一个noisy,则在反向过程就可以提供$\tilde{x}$作为输入在反向过程中:
$$
p_\theta(x_{0:T}|\tilde{x})=p(x_T)\prod^T_{t=1}p_\theta(x_{t-1}|x_t,\tilde{x})
$$
所以现在对应的优化目标变为$\epsilon_\theta(x_t,\tilde{x},t)$,$x$和$\tilde{x}$在通道维度被concat,所以最终输入图像的channel是C=6
所以对应的DDIM中的公式为:
$$
x_{t-1}=\sqrt{\bar{\alpha}_{t-1}}(\frac{x_t-\sqrt{1-\bar{\alpha}_t}\cdot \epsilon_\theta(x_t,\tilde
{x},t)}{\sqrt{\bar{\alpha}t}})+\sqrt{1-\bar{\alpha}{t-1}}\cdot \epsilon_\theta(x_t,\tilde{x},t)
$$
从$x_T\sim N(0,I)$开始
搜广推相关八股
auc和roc是什么?