反向传播算法是大多数神经网络的基础,我们应该多花点时间掌握它。

还有一些技术能够帮助我们改进反向传播算法,从而改进神经网络的学习方式,包括:

  • 选取更好的代价函数
  • 正则化方法
  • 初始化权重的方法
  • 如何选择网络的超参

Cost Function

这里来看一个非常简单的神经元,我们输入1,期望它输出0。

我们看看 Gradient Descent 是如何帮助我们学习 Weights 和 Biases 的。

Round 1

我们的初始值如下:
$$
Weight = 0.6 \
Bias = 0.9 \
\eta = 0.15
$$

这个神经元的初始输出是 0.82 。

我们看到神经元能够迅速地学习 Weights 和 Biases ,经过300 epoch 的学习,最终输出是 0.09,已经很接近我们的预期 0 ,这个结果已经足够好了。

Round 2

我们修改下初始值,再来看下:
$$
Weight = 2 \
Bias = 2 \
\eta = 0.15
$$

这个神经元的初始输出是 0.98 。

尽管 Learning Rate 一样,但是我们看到学习在一开始非常缓慢。看起来在前150 epoch ,Weights 和 Biases 都没有改变太多。

从这个例子我们可以看出,人工神经元在误差很大的时候,学习遇到了问题,学习速度变慢了。

为什么学习速度变慢

神经元的学习方式:

通过计算代价函数的偏导 $\frac{\partial C}{\partial w}$ 和 $\frac{\partial C}{\partial b}$ 来改变 Weights 和 Biases 。

我们说学习速度变慢,实际上是在说偏导很小。

为什么偏导很小

我们的代价函数是均方误差代价函数
$$
C = \frac{ (y-a)^2 }{2}
$$

  • a是x=1时神经元的输出
  • y=0是期待的输出

在激活函数是Sigmoid函数时
$$
a = \sigma(z) \
z = wx+b
$$
代价函数的偏导是
$$
\frac{\partial C}{\partial w} = (a-y) \sigma'(z) x \
\frac{\partial C}{\partial b} = (a-y) \sigma'(z) \
$$
当x=1,y=0时
$$
\frac{\partial C}{\partial w} = a \sigma'(z) \
\frac{\partial C}{\partial b} = a \sigma'(z) \
$$
我们来看下Sigmoid函数的形状

当神经元的输出接近1时,曲线变得非常平缓,$\sigma'(z)$ 就变得非常小,从而 代价函数的偏导 $\frac{\partial C}{\partial w}$ 和 $\frac{\partial C}{\partial b}$ 也会变得非常小。

这就是学习速度变慢的根源。

Cross Entropy Cost Function

那么,我们换个代价函数能不能解决上面的问题?

再看拥有多个输入变量神经元模型


$$
z = \sum_j w_j x_j + b
$$

  • 这里 z 是输入的加权求和。

我们为这个神经元定义交叉熵代价函数如下:
$$
C = -\frac{1}{n} \sum_x \left[y \ln a + (1-y ) \ln (1-a) \right]
$$

  • n是训练数据的个数
  • 求和是针对所有训练输入样本x
  • y是我们对每个样本x所期望的相应地输出

均方误差代价函数和交叉熵代价函数都有两个特点

交叉熵是正数
  1. 由Sigmoid激活函数的特性可以知道,激活值a的取值介于0和1之间,它们的对数是负数
  2. 求和后的数是负数
  3. 整个等式前面有一个符号,最终$C>0$
当所有输入x的输出都能接近期望输出y时,代价函数接近0

比如对于样本x,它的
$$
y = 0 \
a \approx 0
$$
这样,等式的第一项就是0

从图上可以看出,等式的第二项$\ln(1-a) \approx 0$

对于样本x
$$
y = 1 \
a \approx 1
$$
等式的第二项为0

等式的第一项$\ln a \approx 0$

上面两种情况,交叉熵代价函数都约等于0

交叉熵独有的特点

先看下交叉熵关于权重的偏导
$$
\frac{\partial C}{\partial w_j} = -\frac{1}{n} \sum_x \left(
\frac{y }{\sigma(z)} -\frac{(1-y)}{1-\sigma(z)} \right)
\frac{\partial \sigma}{\partial w_j}
\
= -\frac{1}{n} \sum_x \left(
\frac{y}{\sigma(z)}
-\frac{(1-y)}{1-\sigma(z)} \right)\sigma'(z) x_j
$$
通分简化后
$$
\begin{eqnarray}
\frac{\partial C}{\partial w_j} & = & \frac{1}{n}
\sum_x \frac{\sigma'(z) x_j}{\sigma(z) (1-\sigma(z))}
(\sigma(z)-y).
\tag{60}\end{eqnarray}
$$
我们知道$\sigma'$
$$
\sigma(z) = \frac{1}{1+e^{-z}} \
\sigma'(z) = \sigma(z)(1-\sigma(z))
$$
代入到上面的公式中
$$
\frac{\partial C}{\partial w_j} = \frac{1}{n} \sum_x x_j(\sigma(z)-y)
$$
从交叉熵关于权重的偏导中,我们看到权重的学习速率可以是被输出结果的误差所控制。

之前均方误差关于权重的偏导中,误差太大导致$\sigma'(z)$非常小,造成学习速度非常慢。

现在交叉熵关于权重的偏导中,$\sigma'(z)$被抵消掉了,因此不会担心误差太大会导致学习速度慢。相反,误差越大我们的神经元学习速率越大。

Round 3

再来看看使用交叉熵代价函数时的学习速度。
$$
Weight = 0.6 \
Bias = 0.9 \
\eta = 0.15
$$

对于交叉熵代价函数而言,Learning Rate = 0.15 太高了,学得太快,以至于我们看不清楚代价函数的值是如何变化的。

这里将 Learning Rate 换成 0.005 再看一次。
$$
Weight = 0.6 \
Bias = 0.9 \
\eta = 0.005
$$

我们看到和之前一样好。

Round 4

$$
Weight = 2 \
Bias = 2 \
\eta = 0.005
$$

我们看到误差太大没有导致学习速度变慢。

Softmax

激活函数除了Sigmoid,还有Softmax。

第j个输出神经元的激活值 $a_j^L$ 是
$$
a_j^L = \frac{e^{z_j^L}}{\sum_k e^{z_k^L}}
$$
分母是对所有输出神经元求和。

从公式我们可以看出,Softmax层的所有输出激活值都是正数,并且它们加起来和为1。

这样就可以把Softmax层得到的输出看作是一个概率分布,将数据激活值 $a_j^L$看作是神经网络认为结果是 j 的概率。

Softmax的单调性

函数的单调性,指函数的自变量增大或减小,函数值也增大或减小。

Softmax也有这样的特性,当加权输入 $z_j^L$ 增加时,激活值 $a_j^L$ 也增加。

Softmax的非局部性

sigmoid层的第j个神经元的输出是
$$
a_j^L = \sigma(z_j^L)
$$
它是只关于第j个神级元的加权输入的一个函数。

而 Softmax 层的任何一个 $a_j^L$ ,都要依赖该层所有神经元的加权输入。

反转Softmax层

我们有一个带有Softmax层的神经网络,已知激活值,那么加权输入为:
$$
z_j^L = \ln a_j^L + C
$$

Log-Likelihood Cost Function

Sigmoid 输出层与 Cross-Entropy 代价函数搭配

Softmax 输出层与 Log-Likelihood 代价函数搭配

Log-Likelihood 代价函数的公式是:
$$
C \equiv - \ln a_y^L
$$

  • x表示输入网络的训练样本
  • y是期待的输出,用One-Hot向量表示。y=7表示向量的第7位是1,其余位是0

如果输入的是数字 7 对应的图像,那么 Log-Likelihood 代价是
$$
-\ln a_7^L
$$
如果网络工作很好,对输出 7 非常自信,$a_7^L$ 会非常接近1,那么$-\ln a_7^L$ 就会很小。

如果网络工作不好,概率 $a_7^L$ 会很小,而 $-\ln a_7^L$ 会很大。

学习速度不会衰退

$$
\frac{\partial C}{\partial b^L_j} = a^L_j-y_j
\
\frac{\partial C}{\partial w^L_{jk}} = a^{L-1}_k (a^L_j-y_j)
$$

这些表达式确保我们不会遇到学习速度衰退的问题。

反向传播

$\delta_j^L = a_j^L - y_j$

过拟合和正则化

Johnny von Neumann 说四个参数可以模拟一头大象,五个参数可以让它摇动鼻子。

Enrico Fermi 认为,拥有大量自由参数的模型能够描述一个足够宽泛的现象。即使这样的模型与现有数据拟合得非常好,但它并没有真正地洞察到现象背后的本质,以至于不能普及到新的情况上。

训练数据的代价

测试数据的准确度

测试数据的代价

训练数据的准确度

我们看到,训练数据的代价一直在下降,这可能让我们觉得模型似乎一直在改进。

但是从测试数据的准确度来看,280 epoch 后就几乎停止改善。

从测试数据的代价来看,更直观,在15 epoch前代价一直在降低,但之后却开始变大。而训练数据的代价是一直在降低的。

从训练数据的准确度来看,训练数据的准确率上升到100%,能正确分类所有的训练数据,但是在测试数据上的准确率却直邮82.27% 。

以上种种迹象表明,280 epoch 开始的网络产生了 OverFitting 。

在含有大量 Weights 和 Biases 参数时,神经网络很容易过拟合。我们需要跟踪网络训练过程中测试数据的准确度,如果测数据集的准确度不在提高,就应该停止训练。

Validation Data

我们引入 Validation Data,每一步训练后,计算 Validation Data 的分类准确度,一旦分类准确度达到饱和,就停止训练。这种策略叫做 Early Stopping(提前终止)。

为什么使用 Validation Data 而不是使用 Test Data 来苹果结果去设置超参

如果基于 Test Data 去做,有可能我们最后的网络是对 Test Data 过拟合的,网络的性能不能推广到其它数据集。

可以将 Validation Data 看作帮助我们学习合适超参的一种训练数据。

这里超参是指网络层数,隐藏层神经元个数,学习率,批次大小。

增加数据训练数据

增加训练数据是降低过拟合的最好方法之一。

一样的超参,只是训练图片从1000增加到50000,测试数据和训练数据的准确度更加接近,差距从之前17.73%降低到1.53% 。

虽然过拟合依然存在,但已经大大降低,我们的网络能从训练数据更好地泛化到测试数据。

Regularization

除了增加训练数据,还能通过减小网络规模去避免过拟合。但是我们觉得大型网络更有潜力,不愿意减小规模。

在固定网络规模和固定训练数据大小的时候,我们还可以选择 Regularization(正则化)技术。

L2 Weight Decay

权重衰减是最常用的正则化技术,也叫 L2 Regularization(L2 正则)。它的思想是在代价函数中加入一个额外的正则化项。
$$
C = C_0 + \frac{\lambda}{2n} \sum_w w^2
$$

  • $C_0$ 是原本没有正则化的代价函数
  • 第二项是网络中所有 Weights 的平方和
  • $\lambda$ 是 regularization parameter(正则化参数),并且 $\lambda > 0$

当 $\lambda$ 较小时,我们偏好最小化原来的代价函数,当 $\lambda$ 较大时,我们让网络偏好学习更小的 Weights 。

在随机梯度下降算法中应用正则化

在正则化的网络中应用随机梯度下降算法,对上面的公式求偏导可知:
$$
\frac{\partial C}{\partial w} = \frac{\partial C_0}{\partial w} + \frac{\lambda}{n} w \
\frac{\partial C}{\partial b} = \frac{\partial C_0}{\partial b}
$$
只要照常使用反向传播,并把 $\frac{\lambda}{n} w$ 代入
$$
b \rightarrow b - \eta \frac{\partial C_0}{\partial b} \
w \rightarrow w - \eta \frac{\partial C_0}{\partial w} - \frac{\eta \lambda}{n} w \
= \left(1 - \frac{\eta \lambda}{n}\right) w - \eta \frac{\partial C_0}{\partial w}
$$
我们看到,跟之前唯一的变化时,我们用 $\left(1 - \frac{\eta \lambda}{n}\right) $ 来调整 Weights ,这种调叫做 Weight Decay(权重衰减)。

之前我们的随机梯度下降,时在包含m个训练样本的mini-batch数据中进行平均以估计$\frac{\partial C_0}{\partial w}$,现在对于随机梯度下降法而言正则化的学习方法变成了:
$$
w \rightarrow \left(1 - \frac{\eta \lambda}{n}\right) w - \frac{\eta}{m} \sum_x \frac{\partial C_x}{\partial w} \
b \rightarrow b - \frac{\eta}{m} \sum_x \frac{\partial C_x}{\partial wb}
$$
$\sum$ 是针对mini-batch中所有训练样本进行求和

$C_x$ 是每个样本未进行正则化的代价

我们看到,正则化只是增加了权重衰减。

Round 1

我们使用 $n = 1000$ 个训练样本再跑一次,这次由30个隐藏层神经元,每个mini-batch的大小是10,学习率是0.5,使用交叉熵代价函数,正则化参数 $\lambda = 0.1$。使用1000个训练样本。

我们看到训练数据的代价函数一直在下降,与之前没有进行正则化时一样。

但是从测试数据的准确度,我们看到应用正则化抑制了过拟合。

准确度也从之前的82.27上升到87.1 。

Round 2

这次将训练样本增加到 $n=50000$ ,相应的,也需要调整正则化参数 $\lambda = 5$,让权重衰减跟之前保持一样。

我们之前看到过,对于50000样本量的训练数据,过拟合已经不再是个大问题了。但是应用正则化后,我们在测试数据上的准确度从95.49%提升到96.49% 。

从经验来看,正则化让我们的网络声称得更好,并有效地减弱了过拟合效应。

正则化的好处

  • 减弱过拟合,
  • 提升分类准确率,
  • 避免陷入代价函数的局部最优中

使用随机 Weights 初始化时,经常卡在代价函数的局部最优中,结果就是每次运行可能产生相当不同的结果。

而应用了正则化后,每次运行可以提供更容易复现的结果。

为什么正则化能够降低过拟合

一般的说法是:某种程度上,越小的权重复杂度越低,能更简单有效地描绘数据,所以我们倾向于选择这样的权重。

L1

$$
C = C_0 + \frac{\lambda}{n} \sum_w |w|
$$

我们再来看下L2正则的代价函数
$$
C = C_0 + \frac{\lambda}{2n} \sum_w w^2
$$
对L1代价函数求偏导
$$
\frac{\partial C}{\partial w} = \frac{\partial C_0}{\partial w} + \frac{\lambda}{n} sgn(w)
$$
$sgn(w)$是取w的符号,当w为正数时,$sgn(w) = +1$。当w为负数时,$sgn(w) = -1$。

对反向传播进行修改,使用基于L1正则化的随机梯度下降进行学习。
$$
w \rightarrow w' = w - \frac{\eta \lambda}{n} sgn(w) - \eta \frac{\partial C_0}{\partial w}
$$
我们可以使用 mini-batch 的均值去估计 $\frac{ \partial C_0}{\partial w}$,
$$
w \rightarrow w' = (1 - \frac{\eta \lambda}{n}) w - \eta \frac{\partial C_0}{\partial w}
$$
我们再来看下L2正则的:
$$
w \rightarrow w' = \left(1 - \frac{\eta \lambda}{n}\right) w - \frac{\eta}{m} \sum_x \frac{\partial C_x}{\partial w}
$$

共同点

L1 和 L2 的共同点是都惩罚大的权重。

不同点

L1 中,权值通过一个常量向 0 缩小。

L2中,权值通过一个和 w 成比例的量进行缩小。

  • 当 $|w|$ 很大时,L1 比 L2 缩小得少。
  • 当 $|w|$ 很小时,L1 比 L2 缩小得多。

结果是,L1 会将权值保留在少量的高重要度的连接上,其它权值会趋向0接近。

Dropout 弃权

L1 和 L2 正则化是对代价函数的修改。Dropout 是改变网络本身。

假设我们有训练数据 x,和输出 y,一般会通过在网络中正向传播 x 进行训练,再反向传播确定梯度的贡献。

当使用 Dropout 时:

  1. 我们先随机临时删除网络中的一半的隐藏神经元,同时输入层和输出层的神经元保持不变。
  2. 在一个 mini-batch 中,前向传播输入 x ,通过修改后的网络,然后反向传播结果,并通过这个修改后的网络。然后对有关权值和偏置进行更新。
  3. 重复上面的过程,先重置弃权的神经元,再选择一个新的隐藏神经元的随机子集,对这个不同的 mini-batch 估计它的梯度,然后再更新权值和偏置。

我们弃权掉不同的神经元几何,这样就像是我们在训练不同的神经元集合。弃权过程如同大量不同网络的效果的平均。不同的网络会以不同的方式过度拟合,所以弃权过的网络效果会减轻过拟合。

比如我们训练了五个网络,其中三个把数字分类为3,那很可能就是3了。

在图像、语音识别、自然语言处理时,很有效。大规模深度网络时也很有用,因为这样的网络过拟合问题特别突出。

人为扩展训练数据

一般我们认为大量的训练数据会得到更好的性能。

但这个代价很大。有时我们可以人为扩展训练数据,比如图片5,将其做一个旋转,转换,扭曲,都懂,使用扩展后的训练数据来提升网络的性能。

更多的训练数据能补偿不同算法的差距。

权值初始化

之前我们一直用均值为0,标准差为1的独立高斯随机变量来选择权值和偏置。

其实用归一化的高斯分布不是最好的。

跟以前的归一化问题一样,如果权值大,$z$ 也大,$\sigma ( z )$ 就接近 1 或 0,隐藏层神经元会饱和,梯度下降算法学习慢。

之前我们通过选择不同的代价函数来解决,但那只是对输出神经元有效,对隐藏神经元不起作用。

假设我们有一个神经元,它的输入权值是 $n_{in}$,然后我们用均值是0,标准差是 $\frac{1}{\sqrt{n_{in}}}$ 的高斯随机变量来初始化这些权值。

这样,$z = \sum_j w_j x_j +b$ 的取值更小。

这样的神经元更不容易饱和,也更不可能使学习速度下降。

$\frac{1}{\sqrt{n_{in}}}$ 权值初始化,可以加快训练速度,有时也能提升网络的最终性能。

如何选择超参数

每一 epoch 的精确度一直下降,但是我们一开始并不知道哪些超参数应该被调整。

  • 也许问题在于无论我们怎么选择超参数,30个隐藏神经元网络永远都不会工作得很好。
  • 我们可能真的需要至少100个隐藏神经元?或300个隐藏神经元?或多个隐藏层?
  • 可能我们的网络正在学习,但是需要更多的 epoch。
  • 可能 mini-batch 太小了。
  • 可能我们我们应该换回 均方误差代价函数。
  • 可能我们需要尝试一个不同的途径来初始化权值。
  • 等等。

我们很容易就会迷失方向。这里我们解释一些启发式的方法,帮助你开发一个工作流,能让你更好地设置超参数。

Broad Strategy 宽泛策略

宽泛策略不好。

Learning Rate

  • $\eta = 0.025$,代价函数平滑下降到最后回合。

  • $\eta = 0.25$ ,代价在20回合时接近饱和。后面微震荡和随机抖动。
  • $\eta = 2.5$,代价一直震荡。

震荡的原因是$\eta$太大,使算法在接近最小值时,又越过谷底。

随机梯度下降期望我们能够逐渐地抵达代价函数的谷底。

学习率太大,代价一直震荡,太小又算法变慢,如果可变学习速度会更好。开始时使用$\eta = 0.25$,接近谷底换成$\eta = 0.025$。

策略是:

  • 一开始就找到使代价震荡的 $\eta$ 的量级,也就是 $\eta$ 的 threshold。
  • 如果0.01没有震荡,加到0.1, 1.0。
  • 如果0.01就震荡,减到0.001,0.0001。
  • 先找量级,再确定 threshold,再将 $\eta$ 设为 threshold 的一半。

Early Stopping

在每个 epoch 结束时,我们都会在验证数据上计算分类精度。当分类精度不再提升时,我们就结束它。Early Stopping 会自动防止过拟合。但是在试验的早期阶段,我们会关闭 Early Stopping ,这样我们能够看到任何过拟合的信号,并用这些信息去选择正则化算法。

即使是总体趋势在提升的情况下,我们也能看到精度在抖动和震荡。如果我们在精度刚开始下降的时候就终止它,我们肯定会错过更好的模型。一个更好的准则是当最好的分类精度一段时间都没有提升时,再终止它。这样既不会错过什么,也不会等太久。

这里有一个准则:连续十次没有提升就终止。但是网络有时会在很长一段时间内,分类精度很平缓,然后才会有提升。如果你想要获得更好的性能,这个准则就太草率了。

Learning Rate Schedule

我们一直将 $\eta$ 设置为常量。一开始,我们会使用一个大的学习速率,让权值变化地快一点。然后,我们减小学习速率,这样可以对权值做出更加精良的调整。

一个观点是保持学习速率不变,直到验证数据集精度开始变差时,按照 1/2 或 1/10 去降低学习速率。这样重复几次,直到学习学习速率变为初始值的 1/1000,就停止。

Deep Learning - 3 改进神经网络的学习方式的更多相关文章

  1. Deep Learning In NLP 神经网络与词向量

    0. 词向量是什么 自然语言理解的问题要转化为机器学习的问题,第一步肯定是要找一种方法把这些符号数学化. NLP 中最直观,也是到目前为止最常用的词表示方法是 One-hot Representati ...

  2. deep learning(1)BP神经网络原理与练习

    具体原理参考如下讲义: 1.神经网络 2.反向传导 3.梯度检验与高级优化 看完材料1和2就可以梳理清楚bp神经网络的基本工作原理,下面通过一个C语言实现的程序来练习这个算法 //Backpropag ...

  3. Coursera Deep Learning笔记 卷积神经网络基础

    参考1 参考2 1. 计算机视觉 使用传统神经网络处理机器视觉的一个主要问题是输入层维度很大.例如一张64x64x3的图片,神经网络输入层的维度为12288. 如果图片尺寸较大,例如一张1000x10 ...

  4. 吴恩达 Deep learning 第二周 神经网络基础

    逻辑回归代价函数(损失函数)的几个求导特性 1.对于sigmoid函数 2.对于以下函数 3.线性回归与逻辑回归的神经网络图表示 利用Numpy向量化运算与for循环运算的显著差距 import nu ...

  5. Deep Learning(深度学习)学习笔记整理

    申明:本文非笔者原创,原文转载自:http://www.sigvc.org/bbs/thread-2187-1-3.html 4.2.初级(浅层)特征表示 既然像素级的特征表示方法没有作用,那怎样的表 ...

  6. 【转载】Deep Learning(深度学习)学习笔记整理

    http://blog.csdn.net/zouxy09/article/details/8775360 一.概述 Artificial Intelligence,也就是人工智能,就像长生不老和星际漫 ...

  7. Deep Learning速成教程

          引言         深度学习,即Deep Learning,是一种学习算法(Learning algorithm),亦是人工智能领域的一个重要分支.从快速发展到实际应用,短短几年时间里, ...

  8. 大牛deep learning入门教程

    雷锋网(搜索"雷锋网"公众号关注)按:本文由Zouxy责编,全面介绍了深度学习的发展历史及其在各个领域的应用,并解释了深度学习的基本思想,深度与浅度学习的区别和深度学习与神经网络之 ...

  9. Deep Learning(深度学习)学习系列

    目录: 一.概述 二.背景 三.人脑视觉机理 四.关于特征        4.1.特征表示的粒度        4.2.初级(浅层)特征表示        4.3.结构性特征表示        4.4 ...

随机推荐

  1. dedecms中arclist标签做分页以及分页点击模块样式错乱问题

    in 使用织梦建站,通常会调用到一个文章列表,dedecms官网list标签没有提供typeid的属性,首页或多列表部分情况下使用分页并不方便,这就需要用arclist标签实现一个分页功能:以下还是展 ...

  2. vue android低版本 白屏问题 你是不是用了Object.assign ??

    问题描述 在部分比较低版本的手机中,发现apk安装后白屏,但是大部分手机都能安装. 本人在使用android4.4时候,也是安装后打开白屏. 原因: 代码写法不兼容 this.user = Objec ...

  3. (转)python生态环境简介

    Python生态环境简介 作者: Mir Nazim 原文: Python Ecosystem - An Introduction 译者: dccrazyboy  原译: Python生态环境简介 当 ...

  4. Java实现敏感词过滤 - DFA算法

    Java实现DFA算法进行敏感词过滤 封装工具类如下: 使用前需对敏感词库进行初始化: SensitiveWordUtil.init(sensitiveWordSet); package cn.swf ...

  5. Linux 在文件夹的所有文件中查找某字符

    命令: grep -r -e string directory eg: 在 /home 目录下的所有文件中查找包含 test 字符串的文件. grep -r -e "test" / ...

  6. python练习三—解析xml

    使用python解析xml,主要使用sax的ContentHandler中的标签开始和标签结束的方法驱动,然后在开始(或者结束)事件中决定使用什么处理方法,使用dispatcher来决定并分发到指定方 ...

  7. 简单快速的让你的json解析速度快上加快

    背景 最近小编在做公司的一个需求.要求是把系统内的一些大型文本文件上传到第三方那里,而且第三方要求的交互数据的方式是采用post请求发送json串的形式进行的. 问题 做到中途才发现问题,由于单个文本 ...

  8. maven 聚合工程 用spring boot 搭建 spring cloud 微服务 模块式开发项目

    项目的简单介绍: 项目采用maven聚合工程 用spring boot 搭建 spring cloud的微服务 模块式开发 项目的截图: 搭建开始: 能上图 我少打字 1.首先搭建maven的聚合工程 ...

  9. linux解压war包的命令

    网上很多人说用jar包解压,但jar命令解压时不能指定目录,推荐使用unzip解压war包. 一.命令名: unzip 功 能说明:解压缩zip文 件 语 法:unzip [-cflptuvz][-a ...

  10. mysql累积聚合

    累积聚合为聚合从序列内第一个元素到当前元素的数据,如为每个员工返回每月开始到现在累积的订单数量和平均订单数量 行号问题有两个解决方案,分别是为使用子查询和使用连接.子查询的方法通常比较直观,可读性强. ...