Deep Learning - 3 改进神经网络的学习方式
反向传播算法是大多数神经网络的基础,我们应该多花点时间掌握它。
还有一些技术能够帮助我们改进反向传播算法,从而改进神经网络的学习方式,包括:
- 选取更好的代价函数
- 正则化方法
- 初始化权重的方法
- 如何选择网络的超参
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所期望的相应地输出
均方误差代价函数和交叉熵代价函数都有两个特点
交叉熵是正数
- 由Sigmoid激活函数的特性可以知道,激活值a的取值介于0和1之间,它们的对数是负数
- 求和后的数是负数
- 整个等式前面有一个符号,最终$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 时:
- 我们先随机临时删除网络中的一半的隐藏神经元,同时输入层和输出层的神经元保持不变。
- 在一个 mini-batch 中,前向传播输入 x ,通过修改后的网络,然后反向传播结果,并通过这个修改后的网络。然后对有关权值和偏置进行更新。
- 重复上面的过程,先重置弃权的神经元,再选择一个新的隐藏神经元的随机子集,对这个不同的 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 改进神经网络的学习方式的更多相关文章
- Deep Learning In NLP 神经网络与词向量
0. 词向量是什么 自然语言理解的问题要转化为机器学习的问题,第一步肯定是要找一种方法把这些符号数学化. NLP 中最直观,也是到目前为止最常用的词表示方法是 One-hot Representati ...
- deep learning(1)BP神经网络原理与练习
具体原理参考如下讲义: 1.神经网络 2.反向传导 3.梯度检验与高级优化 看完材料1和2就可以梳理清楚bp神经网络的基本工作原理,下面通过一个C语言实现的程序来练习这个算法 //Backpropag ...
- Coursera Deep Learning笔记 卷积神经网络基础
参考1 参考2 1. 计算机视觉 使用传统神经网络处理机器视觉的一个主要问题是输入层维度很大.例如一张64x64x3的图片,神经网络输入层的维度为12288. 如果图片尺寸较大,例如一张1000x10 ...
- 吴恩达 Deep learning 第二周 神经网络基础
逻辑回归代价函数(损失函数)的几个求导特性 1.对于sigmoid函数 2.对于以下函数 3.线性回归与逻辑回归的神经网络图表示 利用Numpy向量化运算与for循环运算的显著差距 import nu ...
- Deep Learning(深度学习)学习笔记整理
申明:本文非笔者原创,原文转载自:http://www.sigvc.org/bbs/thread-2187-1-3.html 4.2.初级(浅层)特征表示 既然像素级的特征表示方法没有作用,那怎样的表 ...
- 【转载】Deep Learning(深度学习)学习笔记整理
http://blog.csdn.net/zouxy09/article/details/8775360 一.概述 Artificial Intelligence,也就是人工智能,就像长生不老和星际漫 ...
- Deep Learning速成教程
引言 深度学习,即Deep Learning,是一种学习算法(Learning algorithm),亦是人工智能领域的一个重要分支.从快速发展到实际应用,短短几年时间里, ...
- 大牛deep learning入门教程
雷锋网(搜索"雷锋网"公众号关注)按:本文由Zouxy责编,全面介绍了深度学习的发展历史及其在各个领域的应用,并解释了深度学习的基本思想,深度与浅度学习的区别和深度学习与神经网络之 ...
- Deep Learning(深度学习)学习系列
目录: 一.概述 二.背景 三.人脑视觉机理 四.关于特征 4.1.特征表示的粒度 4.2.初级(浅层)特征表示 4.3.结构性特征表示 4.4 ...
随机推荐
- JavaScript中的注释问题详解? 部分3
注释:解释代码的含义,浏览器中不执行. 方便其他程序员了解代码 ,也可以注释自己不需要的代码(开发过程中)! 1. 单行注释 // 用于一行代码上面 2.多行注释 /* */ 用于一段代码上面 或者是 ...
- C/C++结构体成员偏移量获取
分析代码节选自muduo. 以下代码通过offsetof获取sin_family在sockaddr_in6中的字段偏移量. static_assert(offsetof(sockaddr_in6, s ...
- 2,linux入门到上手-ssh安装配置及虚拟机基本使用
ssh配置 1,打开"终端窗口",输入 "sudo apt-get update" --> 回车 --> "输入当前登录用户的管理员密码& ...
- Python 中的object takes no parameters错误
Python是一门面向对象的语言,中我们首先创建一个类: class Student(object): def _init_(self,name,score): self.name = name se ...
- Redis(1)---五种数据结构
五种数据结构 一.全局key操作 --删 flushdb --清空当前选择的数据库 del mykey mykey2 --删除了两个 Keys --改 --将当前数据库中的 mysetkey 键移入到 ...
- mybatis框架(4)---输入输出映射
输入输出映射 通过parameterType制定输入参数类型 类型可以是简单类型(int String)也可以是POJO本身 或者包装类 1输入映射 关于输入简单类型和pojo本身的我就不写了,因为比 ...
- Netdata 服务器前端监控平台
Netdata 是一款 Linux 性能实时监测工具.Netdata是Linux系统实时性能监测工具,提供web界面的界面视角. 它用可视化的手段,将被监测者最细微的细节,展现了出来.这样,你便可以清 ...
- TCP/IP 笔记 - TCP拥塞控制
拥塞控制是TCP通信的每一方需要执行的一系列行为,这些行为有特定算法规定,用于防止网络因为大规模的通信负载而瘫痪.其基本方法是当有理由认为网络即将进入拥塞状态(或已由于拥塞而出现路由丢包情况)时减缓T ...
- find命令高级参数
find 命令参数大全 转自[https://www.cnblogs.com/yorkyang/p/6294894.html] Linux中find常见用法示例 ·find path -op ...
- 【原创】Github团队协作之Pull请求
首先声明:Github上关于代码团队协作方式有很多种,这里只讲述Github上其中的一种代码团队协作方式. Pull请求(Pull request) 1 综述 协作者通过fork一个新的代 ...