欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

CS231n Lecture6

程序员文章站 2022-07-12 17:09:06
...

Activation Function

输入经线性变换后需经过非线性**才能作为下一层的输入。

Sigmoid

σ(x)=11+ex\sigma(x) = \frac{1}{1+e^{-x}},取值范围为 (0,1)(0,1) ,该**函数存在一些问题:

  1. 神经元的**值大小在1或者-1时会杀死梯度;
  2. 输出不以0为均值,这样使得 WW 的允许更新方向要不全为正的,要不全为负的(从整个神经网络框架来看,这里可以这么理解,由于更新权重的方向只与 LW\frac{\partial L}{\partial W} 与 输入 XX 有关,前边一项不由 WW 决定,后边一项由于sigmoidsigmoid 的输出符号不以0为中心,因此符号一致,因此所有参数只能按照全正或全反两个方向更新),使得不能很好的遍历参数空间
  3. 指数元素的计算复杂度很高

tanh

解决了输出不以0为中心的问题,但是另外两个问题仍然存在。

ReLU

f(x)=max(0,x) f(x) = \max(0, x)
优点:

  1. 不存在饱和点(梯度很小)
  2. 计算迅速
  3. 实际应用中比tanh和sigmoid收敛快
  4. 从生物学的角度更加合理

缺点:

  1. 输出不以0为均值
  2. 对于小于0的值没有**

基于上述原因,人们更喜欢以一个稍微正的偏差来初始化ReLU(如偏差为0.01的高斯模型初始化)。

Leaky ReLU

f(x)=max(0.01x,x)f(x) = \max(0.01x, x)
输入为负数时也会被**,但是在实际实现时的表现性能不一定比ReLU更好

Parametric Rectifier(PReLU)

f(x)=max(αx,x)f(x) = \max(\alpha x, x)
通过神经网络的学习决定参数 α\alpha

ELU

f(x)=xif  x>0 f(x) = x\quad\text{if} \; x > 0
f(x)=α(exp(x)1)if  x0 f(x) = \alpha (\exp(x) - 1) \quad\text{if}\;x \le 0
相较于Leaky ReLU,对于负值输入添加了更多对噪声的鲁棒性。

Maxout Neuron

max(ω1Tx+b1,ω2Tx+b2)\max(\omega_1^Tx + b_1, \omega_2^Tx + b_2)
通过训练求解 ω1\omega_1b1b_1ω2\omega_2b2b_2
ReLU和Leaky ReLU是其一般形式,缺点也很明显成倍增大了参数的数目

TLDR

先用ReLU测试,同时注意learning rate的调节
尝试Leaky ReLU/Maxout/ELU
尝试tanh,但一般没有提升
sigmoid不需要尝试

Data Preprocessing

为什么要对输入做均值零化:如果全为正(负),那么在backward时,对 ω\omega 的梯度也只有正和负,那么更新方向只有zigzag,不能充分遍历参数空间
为什要做normalization:保证每个特征在相同的值域内且贡献相同,对于图像问题,通常会进行均值归0,但不尽兴normalization,因为对于图像我们认为每个位置已经得到了可比较的范围和分布。
除了mean-zero和normalization,通常使用的预处理方法还有PCA和whitening。
对图像而言,我们的mean-zero需要针对每个channel独立归零,通常也不尽兴PCA,normalization,whitening。

Weight initialization

若所有的参数初始0,那么在更新过程中不会打破对称性,无法遍历参数空间。

Small random numbers

W = 0.01 * np.ramdom.randn(D, H)

对于小网络符合要求,对于深层网络会存在很多问题
深层网络在后边层的**值会全部变成0,由于后边层的输入在0附近,所以参数更新的权重都很小,优化速度很慢。

W = np.random.randn(D,H)*1

我们的分析是基于tanh**函数的,如果用此办法进行**,输出的值很大,每个神经元接近饱和,梯度的更新为0

W = np.random.randn(D,W)/np.sqrt(D)

解决了后层输出的过小或过大的问题,但是当使用ReLU时,破坏了本身的非线性性质,后边层的输出会越来越倾向于0,且神经元会失活

W = np.random.randn(D,W)/np.sqrt(D/2)

Batch Normalization

x^(k)=x(k)E[x(k)]Var[x(k)]\hat{x}^{(k)} = \frac{x^(k) - E[x^{(k)}]}{\sqrt{\text{Var}[x^{(k)}]}}
batch normalization中的batch是与SGD中的batch对应,对于batch normalization,均值和方差的计算有两种方法:将一层所有数据来计算均值和方差;只选取SGD中的batch来计算均值和方差。均值和方差的计算是基于每一层而言的。
batch normalization通常在全连接层和非线性**函数之间,为了使网络中有更灵活的均值和方差,batch normalization最后需要进行均值和方差的调节
y(k)=γ(k)x^(k)+β(k)y^{(k)} = \gamma^{(k)}\hat{x}^{(k)} + \beta^{(k)}
batch normalization的优点:

  1. 提高了网络中的gradient
  2. 允许更高的学习率
  3. 降低了对初始化值的强依赖
  4. 也是一种正则化的方法,可以减少对drop out的需求

在测试阶段,batch normalization的均值方差是基于训练时的均值方差得到的(一种方法是对训练时用到的均值和方差取平均)。

Babysitting the learning rate

首先对数据做预处理,再选择网络结构,在运行之前对loss检测添加regularization之后loss是否会提高,同时检测是否能对很小的训练值过拟合(准确度达到很高)。
开始训练时可以从很小的regularization开始找到可以使loss下降的learning rate。如果loss不下降,那么learning rate可能太小(这种情况下可能出现loss没什么变化但是准确度提高,因为loss的梯度虽然弥散,但是权重一直在更新);如果更新过程中出现NaN,则说明learning rate太大。在实际调试时,我们可以选择不同的learning rate进行交叉验证。

Hyperparameter Optimization

交叉验证

首先用几个小epoch来获取可以使用的参数,然后再对这些参数进行调试(finer search)。
最终选择的参数不能只考虑准确度,如果该准确度所对应的学习率很大,那么要担心该超参下的参数是否很好遍历了整个参数空间。
finer search 选择参数时最好使用random layout(随机选择),而不是使用gird layout。
参数选择时最好在log空间内选择。