【深度学习】图像去噪 是在 【深度学习】计算机视觉 系列文章的基础上,再次针对深度学习(尤其是图像去噪方面)的基础知识有更深入学习和巩固。
1 DnCNN
1.1 网络结构
1.1.1 残差学习
1.1.2 Batch Normalization (BN)
1.1.2.1 背景和目标
批归一化是DnCNN第二个特点。在阅读代码的时候,我对model.train()
和model.eval()
产生了疑问,它们的作用是什么?
一般用法是:在训练开始之前写上 model.trian() ,在测试时写上 model.eval() 。
- model.train():启用BN层和Dropout。
- model.eval():不启用BN层和Dropout。
Dropout此处不做过多解释,对于BN层,model.train()是保证BN层能够用到每一批数据的均值和方差;model.eval()是保证BN层能够用全部训练数据的均值和方差。训练完 train 样本后,生成的模型 model 要用来测试样本了,在 model(test) 之前,需要加上model.eval(),否则的话,有输入数据,即使不训练,它也会改变权值。
如果在测试的时候启用了Dropout,那么网络会随机丢弃某几个神经元,这样神经网络每一次生成的结果不是固定的,生成的质量也不稳定。那BN是如何影响网络的?这就要先学习BN具体是如何实现的。
1.1.2.2 核心问题
在CNN训练时,绝大多数都采用mini-batch使用随机梯度下降算法进行训练,那么随着输入数据的不断变化,以及网络中参数不断调整,网络的各层输入数据的分布则会不断变化,那么各层在训练的过程中就需要不断的改变以适应这种新的数据分布,从而造成网络训练困难,难以拟合的问题。
我的理解:针对网络的每一层(例如x层),我们需要保证不管输入什么样的图片(数据),经过网络层层输入到达x层后,它们的数据分布总是类似的,这样我们就能针对x层的特点去修改x层的权重,慢慢拟合,而不是刚适应了某张图片的数据特点,换了一张图片又要大幅度调整。
BN算法解决的就是这样的问题,他通过对每一层的输入进行归一化,保证每层的输入数据分布是稳定的,从而达到加速训练的目的。
1.1.2.3 步骤
-
Standardization:首先对𝑚个𝑥进行 Standardization,得到 zero mean unit variance的分布𝑥̂ 。
其中, x k x^{k} xk表示输入数据的第k维, E [ x k ] E[x^{k}] E[xk]表示该维的平均值, V a r [ x k ] \sqrt{Var[x^{k}]} Var[xk]为标准差。 -
scale and shift:然后再对𝑥̂ 进行scale and shift,缩放并平移到新的分布𝑦,具有新的均值𝛽方差𝛾。
我们思考一个问题,在第一步中,减均值除方差得到的分布是正态分布,我们能否认为正态分布就是最好或最能体现我们训练样本的特征分布呢?不能。这种分布不一定是前面一层要学习到的数据分布,这样强行归一化就会破坏掉刚刚学习到的特征,比如数据本身就很不对称(不符合正态分布),或者激活函数未必是对“方差为1”的数据最好的效果,比如Softmax激活函数,在-1~1之间的函数的梯度不大,那么非线性变换的作用就不能很好的体现。换言之就是,减均值除方差操作后可能会削弱网络的性能。
针对上述问题,BN算法在第二步中设置了两个可学习的变量γ和β,然后用这两个可学习的变量去还原上一层应该学到的数据分布。
1.1.2.4 BN算法在训练和测试时的应用
了解完BN的原理后我又有个疑问,如果训练过程中启用了BN,但是在测试的时候没有启用BN,那么输入的测试图片在x层没有经过处理,它的分布可能不适用于我们训练好的权重,影响模型效果。而且DnCNN最终的输出是噪声图,所以我们不需要担心正则化会影响原始图片或者输入图片,为什么要禁用呢?其实我这里的启用和禁用理解错了。
训练时:首先提取每次迭代时的每个mini-batch的平均值和方差进行归一化,再通过两个可学习的变量恢复要学习的特征。
测试时:没有mini-batch了,即平均值为所有mini-batch的平均值的平均值,而方差为每个batch的方差的无偏估计。
所以BN的启用和不启用,不是说这层的存在与否,而是说这层的参数是否固定。
参考来源:
【Pytorch】model.train() 和 model.eval() 原理与用法
深度学习——Batch Normalization算法原理和作用
Batch Normalization的原理和作用
什么是无偏估计?
无偏估计
均值和期望的关系