卷积神经网络 CNN
history:省略
卷积层 convolution layer
作用:提取特征
用什么提取特征:卷积核(卷积核的尺寸是超参数;卷积核中的值在反向传播中被更新;卷积核的深度与输入特征图的深度相同(默认))
卷积过程:就是卷积核在输入特征图上进行滑动,可以设置stride滑动步长;可以设置padding填充输入特征图,可以实现统一输入特征图和输出特征图的尺寸,提取到更多的边缘特征
输出:输出特征图(有几个卷积核就会输出多少个特征图)(关于输出特征图的尺寸,其实很好求,没必要套公式,画画图模拟一下就可以求出来了)(公式:(输入特征图大小+padding*2 - 卷积核大小)/ stride + 1)
池化层 pooling layer
作用:减少特征
用什么减少特征:最大池化(一个区域内保留最大值) 均值池化(一个区域内保留均值)
池化过程:也是需要设置stride,但是池化操作不改变输出特征图的个数,池化操作filter无参,无需反向传播更新
输出:输出特征图(数量不变,大小改变)
全连接层 full connected layer
作用:y = wx + b ;预测结果
用什么预测结果:神经网络(输入-隐藏-输出)(反向传播的时候利用梯度下降方法来更新参数,以减小loss值)
输出:softmax输出预测结果
激活层 activation layer
可以在卷积层后,可以在全连接层后,增加非线性特性,从而使神经网络能够表示和学习复杂的非线性关系
以上layer在不同的CNN当中都有不同的个数
训练神经网络
mini-batch SGD
LOOP:
- 采样一batch数据
- 前向传播,得到loss
- 反向传播,计算梯度
- 根据梯度更新参数
- 直到loss值平稳几乎不再变化
激活函数 activation function
sigmoid
问题:
饱和神经元会"杀死"梯度;
Sigmoid函数的输出不以零为中心;(sigmoid的输出为正数,作为下一层的输入,它通过 “输入信号的单向性” 限制了权重梯度的更新方向,导致网络学习效率低下、收敛缓慢,甚至可能陷入局部最优。)
exp() 计算比较复杂
tanh
问题:
- 饱和神经元会"杀死"梯度;
ReLU
问题:
- Sigmoid函数的输出不以零为中心;
- x<0时的梯度:0
- x=0时的梯度:0(通过实验验证)
leaky ReLU
Maxout
问题:
- 参数/神经元的数量翻倍
ELU
问题:
- exp() 计算比较复杂
数据预处理 data preprocessing
- Z-score 标准化
X -= np.mean(X,axis=0) #均值 X /= np.std(X,axis=0) #方差
- 数据的PCA(主成分分析)和白化处理
权重初始化 Weight Initialization
正确的初始化方法是当前研究的热点领域…
批归一化 Batch Normalization
计算计算每个维度的实验均值和方差
归一化
BN层经常在全连接层或者卷积层后插入,在非线性层前插入
监督学习过程 Babysitting the Learning Process
预处理数据
选择结构
确认损失值是否合理
确保能对训练数据中非常小的部分进行过拟合
从小规模正则化开始寻找能使损失下降的学习率
损失不下降:学习率太小;损失爆炸:学习率太高
超参数优化 Hyperparameter Optimization
交叉验证策略:cross-validation strategy
随机小批量的应用随机采样的超参数,第一阶段:仅进行少量训练周期以初步确定有效参数范围;
第二阶段:延长训练时长,进行更精细的参数搜索 …(按需重复该过程)观察loss、acc
反向传播参数更新优化
SGD
while True: weights_grad = evaluate_gradient(loss_fun,data,weights) weights -= step_size * weights_grad
problem:
沿浅维度进展极其缓慢,沿陡峭方向颤抖
如果损失函数存在局部最小或者鞍点怎么办?零梯度,梯度下降陷入停滞
我们的梯度是来自mini-batches所以有很多噪声
SGD + Momentum
vx = 0 while True: dx = compute_gradient(x) vx = rho * vx + dx x -= learning_rate * vx
建立“速度(velocity)”作为梯度的移动平均值
rho代表“摩擦系数”;典型取值为rho=0.9或0.99
Nesterov Momentum
while True: dx = compute_gradient(x) old_v = v v = rho*v - learning_rate*dx x += -rho*old_v + (1+rho)*v
AdaGrad
grad_squared = 0 while True: dx = compute_gradient(x) grad_squared += dx*dx x -= learning_rate*dx/(np.sqrt(grad_squared)+1e-7)
基于各维度历史平方和的梯度逐元素缩放
RMSProp
grad_squared = 0 while True: dx = compute_gradient(x) grad_squared = decay_rate * grad_squared + (1-decay_rate)*dx*dx x -= learning_rate*dx/(np.sqrt(grad_squared)+1e-7)
Adam (almost)
first_moment = 0 second_moment = 0 while True: dx = compute_gradient(x) first_moment = beta1 * first_moment + (1-beta1)*dx second_moment = beta2 * second_moment + (1-beta2)*dx*dx x -= learning_rate*first_moment/(np.sqrt(second_moment)+1e-7)
Adam (full form)
first_moment = 0 second_moment = 0 for t in range(num_iterations): dx = compute_gradient(x) first_moment = beta1 * first_moment + (1-beta1)*dx second_moment = beta2 * second_moment + (1-beta2)*dx*dx first_unbias = first_moment / (1-beta1**t) second_unbias = second_moment / (1-beta2**t) x -= learning_rate*first_unbias/(np.sqrt(second_unbias)+1e-7)
采用β1=0.9、β2=0.999和学习率=1e-3或5e-4的Adam优化器 是许多模型的理想初始选择
Adam一般是首选
以上所有的各种参数更新方法都有超参数学习率
可以采取学习率随时间衰减策略:
每隔几个训练周期将学习率减半
指数衰减
1/t衰减
一阶优化(上述采取的算法都是)First-Order Optimization
采用梯度形式线性近似,最小化近似值的步骤
二阶优化
利用梯度和海森矩阵构建二次逼近,步进至逼近函数的极小值点
没有超参数 没有学习率
不是很适合深度学习
L-BFGS
如果有能力进行全批次更新,那么可以尝试L-BFGS,通常在完整批次、确定性模式下表现优异 即若存在单一确定性函数f(x)时 L-BFGS优化算法往往能发挥出色效果
正则化 Regularization
加入损失函数
loss = loss + 入R(W)
dropout
在前向传播过程中,随机将部分神经元置零,丢弃概率是一个超参数,通常设为0.5
更常见的情况:“反向随机失活” inverted dropout
一个常见的模式
训练:添加一些随机性
测试:消除随机性(有时是近似)
Batch Normalization
数据增强 Data Augmentation
水平翻转 horizontal flips
随机裁剪和缩放 random crops and scales
色彩抖动 color jitter
…
dropConnect
max pooling
stochastic depth 随机深度:跳过某些层
迁移学习 transfer learning
train on ImageNet
small dataset(改变最后全连接分类的层结构,训练,更新参数,前面的网络结构不变-冻结)
bigger dataset(改变最后全连接层,训练,更新参数,前面的网络结构不变-冻结)
fine tune 微调