BN究竟起了什么作用?一个闭门造车的分析
By 苏剑林 | 2019-10-11 | 119333位读者 |BN,也就是Batch Normalization,是当前深度学习模型(尤其是视觉相关模型)的一个相当重要的技巧,它能加速训练,甚至有一定的抗过拟合作用,还允许我们用更大的学习率,总的来说颇多好处(前提是你跑得起较大的batch size)。
那BN究竟是怎么起作用呢?早期的解释主要是基于概率分布的,大概意思是将每一层的输入分布都归一化到$\mathcal{N}(0,1)$上,减少了所谓的Internal Covariate Shift,从而稳定乃至加速了训练。这种解释看上去没什么毛病,但细思之下其实有问题的:不管哪一层的输入都不可能严格满足正态分布,从而单纯地将均值方差标准化无法实现标准分布$\mathcal{N}(0,1)$;其次,就算能做到$\mathcal{N}(0,1)$,这种诠释也无法进一步解释其他归一化手段(如Instance Normalization、Layer Normalization)起作用的原因。
在去年的论文《How Does Batch Normalization Help Optimization?》里边,作者明确地提出了上述质疑,否定了原来的一些观点,并提出了自己关于BN的新理解:他们认为BN主要作用是使得整个损失函数的landscape更为平滑,从而使得我们可以更平稳地进行训练。
本博文主要也是分享这篇论文的结论,但论述方法是笔者“闭门造车”地构思的。窃认为原论文的论述过于晦涩了,尤其是数学部分太不好理解,所以本文试图尽可能直观地表达同样观点。
(注:阅读本文之前,请确保你已经清楚知道BN是什么,本文不再重复介绍BN的概念和流程。)
一些基础结论 #
在这部分内容中我们先给出一个核心的不等式,继而推导梯度下降,并得到一些关于模型训练的基本结论,为后面BN的分析铺垫。
核心不等式 #
假设函数$f(\theta)$的梯度满足Lipschitz约束($L$约束),即存在常数$L$使得下述恒成立
\begin{equation}\Vert \nabla_{\theta} f(\theta + \Delta \theta) - \nabla_{\theta} f(\theta)\Vert_2\leq L\Vert \Delta\theta\Vert_2\end{equation}
那么我们有如下不等式
\begin{equation}f(\theta+\Delta\theta) \leq f(\theta) + \left\langle \nabla_{\theta}f(\theta), \Delta\theta\right\rangle + \frac{1}{2}L \Vert \Delta\theta\Vert_2^2\label{eq:core-eq}\end{equation}
证明并不难,定义辅助函数$f(\theta + t\Delta\theta),t\in[0, 1]$,然后直接得到\begin{equation}\begin{aligned}f(\theta + \Delta\theta) - f(\theta)=&\int_0^1\frac{\partial f(\theta + t\Delta\theta)}{\partial t} dt\\
=&\int_0^1\left\langle\nabla_{\theta} f(\theta + t\Delta\theta), \Delta\theta\right\rangle dt\\
=&\left\langle\nabla_{\theta} f(\theta), \Delta\theta\right\rangle + \int_0^1\left\langle\nabla_{\theta} f(\theta + t\Delta\theta) - \nabla_{\theta} f(\theta), \Delta\theta\right\rangle dt\\
\leq&\left\langle\nabla_{\theta} f(\theta), \Delta\theta\right\rangle + \int_0^1\Vert\nabla_{\theta} f(\theta + t\Delta\theta) - \nabla_{\theta} f(\theta)\Vert_2 \cdot \Vert \Delta\theta\Vert_2 dt\\
\leq&\left\langle\nabla_{\theta} f(\theta), \Delta\theta\right\rangle + \int_0^1 L \Vert \Delta\theta\Vert_2^2 t dt\\
= &\left\langle\nabla_{\theta} f(\theta), \Delta\theta\right\rangle + \frac{1}{2} L \Vert \Delta\theta\Vert_2^2
\end{aligned}\end{equation}
梯度下降 #
假设$f(\theta)$是损失函数,而我们的目标是最小化$f(\theta)$,那么这个不等式告诉我们很多信息。首先,既然是最小化,自然是希望每一步都在下降,即$f(\theta+\Delta\theta) < f(\theta) $,而$\frac{1}{2}L \Vert \Delta\theta\Vert_2^2$必然是非负的,所以要想下降的唯一选择就是$\left\langle \nabla_{\theta}f(\theta), \Delta\theta\right\rangle < 0$,这样一个自然的选择就是
\begin{equation}\Delta\theta = -\eta \nabla_{\theta}f(\theta)\label{eq:gd}\end{equation}
这里$\eta > 0$是一个标量,即学习率。
可以发现,式$\eqref{eq:gd}$就是梯度下降的更新公式,所以这也就是关于梯度下降的一种推导了,而且这个推导过程所包含的信息量更为丰富,因为它是一个严格的不等式,所以它还可以告诉我们关于训练的一些结论。
Lipschitz约束 #
将梯度下降公式代入到不等式$\eqref{eq:core-eq}$,我们得到
\begin{equation}f(\theta+\Delta\theta) \leq f(\theta) + \left(\frac{1}{2}L\eta^2 - \eta\right) \Vert \nabla_{\theta}f(\theta)\Vert_2^2\end{equation}
注意到,保证损失函数下降的一个充分条件是$\frac{1}{2}L\eta^2 - \eta < 0$,为了做到这一点,要不就要$\eta$足够小,要不就要$L$足够小。但是$\eta$足够小意味着学习速度会相当慢,所以更理想的情况是$L$能足够小,降低了$L$就可以用更大的学习率了,能加快学习速度,这也是它的好处之一。
但$L$是$f(\theta)$的内在属性,因此只能通过调整$f$本身来降低$L$。
BN是怎样炼成的 #
本节将会表明:以降低神经网络的梯度的$L$常数为目的,可以很自然地导出BN。也就是说,BN降低了神经网络的梯度的$L$常数,从而使得神经网络的学习更加容易,比如可以使用更大的学习率。而降低梯度的$L$常数,直观来看就是让损失函数没那么“跌宕起伏”,也就是使得landscape更光滑的意思了。
注:我们之前就讨论过$L$约束,之前我们讨论的是神经网络关于“输入”满足$L$约束,这导致了权重的谱正则和谱归一化(请参考《深度学习中的Lipschitz约束:泛化与生成模型》),本文则是要讨论神经网络(的梯度)关于“参数”满足$L$约束,这导致了对输入的各种归一化手段,而BN是其中最自然的一种。
梯度分析 #
以监督学习为例,假设神经网络表示为$\hat{y}=h(x;\theta)$,损失函数取$l(y,\hat{y})$,那么我们要做的事情是
\begin{equation}\theta = \mathop{\text{argmin}}_{\theta}\, \mathbb{E}_{(x,y)\sim p(x,y)}\left[l(y, h(x;\theta))\right]\end{equation}
也就是$f(\theta)=\mathbb{E}_{(x,y)\sim p(x,y)}\left[l(y, h(x;\theta))\right]$,所以
\begin{equation}\begin{aligned}\nabla_{\theta}f(\theta)=&\mathbb{E}_{(x,y)\sim p(x,y)}\left[\nabla_{\theta}l(y, h(x;\theta))\right]\\
=&\mathbb{E}_{(x,y)\sim p(x,y)}\left[\nabla_{h}l(y, h(x;\theta))\nabla_{\theta}h(x;\theta)\right]\end{aligned}\end{equation}
顺便说明一下,本文的每个记号均没有加粗,但是根据实际情况不同它既有可能表示标量,也有可能表示向量。
非线性假设 #
显然,$f(\theta)$是一个非线性函数,它的非线性来源有两个:
1、损失函数$l(y,\hat{y})$一般是非线性的;
2、神经网络$h(x;\theta)$中的激活函数是非线性的。
关于激活函数,当前主流的激活函数基本上都满足一个特性:导数的绝对值不超过某个常数。我们现在来考虑这个特性能否推广到损失函数中去,即(在整个训练过程中)损失函数的梯度$\nabla_{h}l(y, h(x;\theta))$是否会被局限在某个范围内?
看上去,这个假设通常都是不成立的,比如交叉熵是$-\log p$,而它的导数是$-1/p$,显然不可能被约束在某个有限范围。但是,损失函数联通最后一层的激活函数一起考虑时,则通常是满足这个约束的。比如二分类是最后一层通常用sigmoid激活,这时候配合交叉熵就是
\begin{equation}-\log \text{sigmoid}(h(x;\theta)) = \log \left(1 + e^{-h(x;\theta)}\right)\end{equation}
这时候它关于$h$的的梯度在-1到1之间。当然,确实存在一些情况是不成立的,比如回归问题通常用mse做损失函数,并且最后一层通常不加激活函数,这时候它的梯度是一个线性函数,不会局限在一个有限范围内。这种情况下,我们只能寄望于模型有良好的初始化以及良好的优化器,使得在整个训练过程中$\nabla_{h}l(y, h(x;\theta))$都比较稳定了。这个“寄望”看似比较强,但其实能训练成功的神经网络基本上都满足这个“寄望”。
柯西不等式 #
我们的目的是探讨$\nabla_{\theta}f(\theta)$满足$L$约束的程度,并且探讨降低这个$L$的方法。为此,我们先考虑最简单的单层神经网络(输入向量,输出标量)$h(x;w,b)=g\left(\left\langle x, w\right\rangle + b\right)$,这里的$g$是激活函数。这时候
\begin{equation}\begin{aligned}\mathbb{E}_{(x,y)\sim p(x,y)}\left[\nabla_{b}f(w,b)\right]&=\mathbb{E}_{(x,y)\sim p(x,y)}\left[\frac{\partial l_{w,b}}{\partial g}\dot{g}\left(\left\langle x, w\right\rangle + b\right)\right]\\
\mathbb{E}_{(x,y)\sim p(x,y)}\left[\nabla_{w}f(w,b)\right]&=\mathbb{E}_{(x,y)\sim p(x,y)}\left[\frac{\partial l_{w,b}}{\partial g}\dot{g}\left(\left\langle x, w\right\rangle + b\right)x\right]
\end{aligned}\label{eq:grads}\end{equation}
基于我们的假设,$\frac{\partial l_{w,b}}{\partial g}$和$\dot{g}\left(\left\langle x, w\right\rangle + b\right)$都被限制在某个范围之内,所以可以看到偏置项$b$的梯度是很平稳的,它的更新也应当会是很平稳的。但是$w$的梯度不一样,它跟输入$x$直接相关。
关于$w$的梯度差,我们有
\begin{equation}\begin{aligned}
&\big\Vert\mathbb{E}_{(x,y)\sim p(x,y)}\left[\nabla_{w}f(w+\Delta w,b)\right] - \mathbb{E}_{(x,y)\sim p(x,y)}\left[\nabla_{w}f(w,b)\right]\big\Vert_2\\
=&\Bigg\Vert\mathbb{E}_{(x,y)\sim p(x,y)}\left[\left(\frac{\partial l_{w+\Delta w,b}}{\partial g}\dot{g}\left(\left\langle x, w+\Delta w\right\rangle + b\right) - \frac{\partial l_{w,b}}{\partial g}\dot{g}\left(\left\langle x, w\right\rangle + b\right)\right)x\right]\Bigg\Vert_2
\end{aligned}\end{equation}
将圆括号部分记为$\lambda(x, y; w,b,\Delta w)$,根据前面的讨论,它被约束在某个范围之内,这部分依然是平稳项,既然如此,我们不妨假设它天然满足$L$约束,即
\begin{equation}\Vert\lambda(x, y; w,b,\Delta w)\Vert_2=\mathcal{O}\left(\Vert\Delta w\Vert_2\right)\end{equation}
这时候我们只需要关心好额外的$x$。根据柯西不等式,我们有
\begin{equation}\begin{aligned}&\Big\Vert\mathbb{E}_{(x,y)\sim p(x,y)}\left[\lambda(x, y; w,b,\Delta w) x\right]\Big\Vert_2\\
\leq & \sqrt{\mathbb{E}_{(x,y)\sim p(x,y)}\left[\lambda(x, y; w,b,\Delta w)^2\right]}\times \sqrt{\big|\mathbb{E}_{x\sim p(x)}\left[x\otimes x\right]\big|_1}
\end{aligned}\label{eq:kexi}\end{equation}
这样一来,我们得到了与(当前层)参数无关的$\big|\mathbb{E}_{x\sim p(x)}\left[x\otimes x\right]\big|_1$,如果我们希望降低$L$常数,最直接的方法是降低这一项。
减均值除标准差 #
要注意,虽然我们很希望降低梯度的$L$常数,但这是有前提的——必须在不会明显降低原来神经网络拟合能力的前提下,否则只需要简单乘个0就可以让$L$降低到0了,但这并没有意义。
式$\eqref{eq:kexi}$的结果告诉我们,想办法降低$\big|\mathbb{E}_{x\sim p(x)}\left[x\otimes x\right]\big|_1$是个直接的做法,这意味着我们要对输入$x$进行变换。然后根据刚才的“不降低拟合能力”的前提,最简单并且可能有效的方法就是平移变换了,即我们考虑$x \to x - \mu$,换言之,考虑适当的$\mu$使得
\begin{equation}\big|\mathbb{E}_{x\sim p(x)}\left[(x-\mu)\otimes (x-\mu)\right]\big|_1\end{equation}
最小化。这只不过是一个二次函数的最小值问题,不难解得最优的$\mu$是
\begin{equation}\mu = \mathbb{E}_{x\sim p(x)}\left[x\right]\label{eq:mu}\end{equation}
这正好是所有样本的均值。于是,我们得到:
结论1: 将输入减去所有样本的均值,能降低梯度的$L$常数,是一个有利于优化又不降低神经网络拟合能力的操作。
接着,我们考虑缩放变换,即$x - \mu \to \frac{x - \mu}{\sigma}$,这里的$\sigma$是一个跟$x$大小一样的向量,而除法则是逐位相除。这导致
\begin{equation}\big|\mathbb{E}_{x\sim p(x)}\left[(x-\mu)\otimes (x-\mu)\right]\big|_1 \to \left|\frac{\mathbb{E}_{x\sim p(x)}\left[(x-\mu)\otimes (x-\mu)\right]}{\sigma\otimes \sigma}\right|_1\end{equation}
$\sigma$是对$L$的一个最直接的缩放因子,但问题是缩放到哪里比较好?如果一味追求更小的$L$,那直接$\sigma\to \infty$就好了,但这样的神经网络已经完全没有拟合能力了;但如果$\sigma$太小导致$L$过大,那又不利于优化。所以我们需要一个标准。
以什么为标准好呢?再次回去看梯度的表达式$\eqref{eq:grads}$,前面已经说了,偏置项的梯度不会被$x$明显地影响,所以它似乎会是一个靠谱的标准。如果是这样的话,那相当于将输入$x$的这一项权重直接缩放为1,那也就是说,$\frac{\mathbb{E}_{x\sim p(x)}\left[(x-\mu)\otimes (x-\mu)\right]}{\sigma\otimes \sigma}$变成了一个全1向量,再换言之:
\begin{equation}\sigma = \sqrt{\mathbb{E}_{x\sim p(x)}\left[(x-\mu)\otimes (x-\mu)\right]}\label{eq:sigma}\end{equation}
这样一来,一个相对自然的选择是将$\sigma$取为输入的标准差。这时候,我们能感觉到除以标准差这一项,更像是一个自适应的学习率校正项,它一定程度上消除了不同层级的输入对参数优化的差异性,使得整个网络的优化更为“同步”,或者说使得神经网络的每一层更为“平权”,从而更充分地利用好了整个神经网络,减少了在某一层过拟合的可能性。当然,如果输入的量级过大时,除以标准差这一项也有助于降低梯度的$L$常数。
于是有结论:
结论2: 将输入(减去所有样本的均值后)除以所有样本的标准差,有类似自适应学习率的作用,使得每一层的更新更为同步,减少了在某一层过拟合的可能性,是一个提升神经网络性能的操作。
推导穷,BN现 #
前面的推导,虽然表明上仅以单层神经网络(输入向量,输出标量)为例子,但是结论已经有足够的代表性了,因为多层神经网络本质上也就是单层神经网络的复合而已(关于这个论点,可以参考笔者旧作《从Boosting学习到神经网络:看山是山?》)。
所以有了前面的两个结论,那么BN基本就可以落实了:训练的时候,每一层的输入都减去均值除以标准差即可,不过由于每个batch的只是整体的近似,而期望$\eqref{eq:mu},\eqref{eq:sigma}$是全体样本的均值和标准差,所以BN避免不了的是batch size大点效果才好,这对算力提出了要求。此外,这个分析过程的一个结论是:BN应当放在全连接/卷积前面。
此外,我们还要维护一组变量,把训练过程中的均值方差存起来,供预测时使用,这就是BN中通过滑动平均来统计的均值方差变量了。至于BN的标准设计中,减均值除标准差后还补充上的$\beta,\gamma$项,我认为仅是锦上添花作用,不是最必要的,所以也没法多做解释了。
简单的总结 #
本文从优化角度分析了BN其作用的原理,所持的观点跟《How Does Batch Normalization Help Optimization?》基本一致,但是所用的数学论证和描述方式个人认为会更简单易懂写。最终的结论是减去均值那一项,有助于降低神经网络梯度的$L$常数,而除以标准差的那一项,更多的是起到类似自适应学习率的作用,使得每个参数的更新更加同步,而不至于对某一层、某个参数过拟合。
当然,上述诠释只是一些粗糙的引导,完整地解释BN是一件很难的事情,BN的作用更像是多种因素的复合结果,比如对于我们主流的激活函数来说,$[-1, 1]$基本上都是非线性较强的区间,所以将输入弄成均值为0、方差为1,也能更充分地发挥激活函数的非线性能力,不至于过于浪费神经网络的拟合能力。
总之,神经网络的理论分析都是很艰难的事情,远不是笔者能胜任的,也就只能在这里写写博客,讲讲可有可无的故事来贻笑大方罢了~
转载到请包括本文地址:https://kexue.fm/archives/6992
更详细的转载事宜请参考:《科学空间FAQ》
如果您还有什么疑惑或建议,欢迎在下方评论区继续讨论。
如果您觉得本文还不错,欢迎分享/打赏本文。打赏并非要从中获得收益,而是希望知道科学空间获得了多少读者的真心关注。当然,如果你无视它,也不会影响你的阅读。再次表示欢迎和感谢!
如果您需要引用本文,请参考:
苏剑林. (Oct. 11, 2019). 《BN究竟起了什么作用?一个闭门造车的分析 》[Blog post]. Retrieved from https://kexue.fm/archives/6992
@online{kexuefm-6992,
title={BN究竟起了什么作用?一个闭门造车的分析},
author={苏剑林},
year={2019},
month={Oct},
url={\url{https://kexue.fm/archives/6992}},
}
October 11th, 2019
沙发!
October 17th, 2019
只有我不知道 这个符号什么意思吗。。
⟨∇θf(θ+tΔθ),Δθ⟩
$\nabla_{\theta} f(\theta)$就是$f(\theta)$关于$\theta$的梯度,是一个向量;$\Delta\theta$也是一个向量;$\langle\nabla_{\theta} f(\theta),\Delta\theta\rangle$就是两个向量的内积,结果是一个标量。
这都是基本的微积分记号,如果看不懂,那还是先别看这篇文章了,好好补习高数相关内容吧。
苏神,原来内积符号可以这么写。。。见笑了
这是内积的标准写法之一
October 18th, 2019
⟨∇θf(θ+tΔθ),Δθ⟩是方向导数的另一种形式,等于公式(3)第一个等式的左边∂f(θ+tΔθ)/∂t。但该式有误,应为⟨∇θf(θ),Δθ⟩,且Δθ为单位向量。
修正一下错误公式(3)应该还是∇θf(θ+tΔθ),但Δθ应为单位向量
那为什么这个式子 ⟨∇θf(θ+tΔθ),Δθ⟩ ,等于 ⟨∇θf(θ),Δθ⟩ + ⟨tΔθ,Δθ⟩ 了?
⟨∇θ f(θ),Δθ⟩ + ⟨ ∇θ tΔθ,Δθ⟩
$\Delta\theta$不是单位向量,$\Delta\theta$就是任意增量,不要乱点鸳鸯。
$\frac{df(\theta + t\Delta\theta)}{dt}=\langle\nabla_{\theta} f(\theta+t\Delta\theta),\Delta\theta\rangle$就是一个恒等式。
苏神你好,这个恒等式的左式,自变量可以是 θ, 而不是t 吗? 可以写成 df(t)/ dt 吗?
不好意思,之前是我的笔误,现在已经修正。你看修正之后的还有什么疑惑?
这个公式能在哪里找到吗?
这个公式
$\frac{df(\theta + t\Delta\theta)}{dt}=\langle\nabla_{\theta} f(\theta+t\Delta\theta),\Delta\theta\rangle$
为什么不是
$\frac{df(\theta + t\Delta\theta)}{dt} = \frac{ \Delta\theta df(\theta + t\Delta\theta)}{d(\theta + t\Delta\theta)}$
$\frac{df(\theta + t\Delta\theta)}{dt}=\langle\nabla_{\theta+t\Delta\theta} f(\theta+t\Delta\theta),\Delta\theta\rangle$
$\nabla_{\theta+t\Delta\theta} f(\theta+t\Delta\theta)$难道不等于$\nabla_{\theta} f(\theta+t\Delta\theta)$嘛?
November 23rd, 2019
这篇文章:https://arxiv.org/abs/1903.00925,把batch norm写成了loss形式,$L_{bn}=KL(P_z||N_0)-KL(P_z||N_{mv})$,N0是标准正态分布,Nmv的mv是从mini-batch算出的均值方差。
实验效果比batch norm差些,不过理论上更自然。
感谢推荐,我去看看~
December 3rd, 2019
经常在文章中看到landscape一词,一直不知道给如何翻译,苏神觉得应该怎么理解这个单词
可以直接翻译为“景观”、“图像”,直观感受是“一眼望过去”所看到的样子(一眼望过去,我们首先会关注眼前景观的突兀之处,这正是landscape主要关心的性质之一)。
December 3rd, 2019
还有一个疑问想请教,如果使用BN,是不是输入的数据最好也要标准化一下,只是简单的除以255(比如图像数据)是不是不太合适
这个差别不大,就算输入不标准化,也就是第一层没标准化而已,后面带BN的层也还是会自动标准化。
April 25th, 2020
这个分析过程的一个结论是:BN应当放在全连接/卷积前面。也就是说BN应该在激活函数后面
August 18th, 2020
苏神,你好,有个疑问想要请教下,等式12实际上得到了梯度差的上界,L常数这一项(等式1)实际上也是梯度差的上界,如何通过一个上界的减小来判断另一个上界也减小呢?盼解答。
如果$a < b$恒成立,那么缩小$b$不能保证$a$也随之缩小,但是由于$a$总是不超过$b$的,所以$b$缩小得足够小时,也能限制$a$到一定范围内,这相当于是一个充分条件。更理想的情况下,如果$a,b$具有比较强的相关性,那么缩小$b$的话,$a$也能在一定范围内同步缩小。
August 5th, 2021
有个小疑问,之前看有的博文分析BN应当放在全连接/卷积后面,激活函数前面,因为激活函数往往会将输出变得不太高斯分布了,也就是不对称,当然这个结论只是感性的分析,不知道对不对?感觉BN有点类似正态变换的意思,正态变换之间是存在等式变换的,如果BN的计算对象也是正态分布的话,感觉好像容易理解不会减低拟合能力;如果放在全连接和卷积之前的话,是不是就等于是在激活函数之后了,那这样BN的计算对象感觉不太像正态分布了,不知道会不会导致效果上的差异。
BN似乎放在哪里都有道理,目前比较流行的是ResNetV2那种做法~
February 23rd, 2022
苏老师,从现在的L约束观点出发,比原来ICS的观点更好的一个方面,我觉得是:
目前使用的BN,在最后会增加一个放射变换,实际是将均值方差映射成了$\beta, \gamma^2$,本质上,在其他层来看,BN层的均值方差也在不断变化。本身就和ICS的解释相悖了。
而在L约束观点来看,样本的均值方差实际上是对数据的直接处理,和网络参数无关。进而不视作网络的一部分。而引入的仿射变换的参数,却可以视作网络的一部分,那么在这个基础上,实际上网络的输入在经过BN后,是在L约束的意义下进行了优化。而且如果可以验证引入的放射变换的均值小于样本的累积均值,那么更能证明L约束解释的有效性。
不知道这样理解对不对
其实很多BN的解释,都不依赖于$\beta,\gamma$,也就是说$\beta,\gamma$的作用目前都很玄学,没有完全说得清的。
bn原理解释的论文我看的不多,一个是原始论文,一个就是这篇文章介绍的L约束。
我的核心观点就是原始论文里面ICS的出发点和最后加入$\beta,\gamma$的放射变化是相悖的。
更能接受L约束的解释。L约束的解释和最后的放射变化没有矛盾的地方。