计算机视觉CS231n学习(3)
卷积神经网络 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 + dxx -= learning_rate * vx
建立“速度(velocity)”作为梯度的移动平均值
rho代表“摩擦系数”;典型取值为rho=0.9或0.99
-
Nesterov Momentum
while True:dx = compute_gradient(x)old_v = vv = rho*v - learning_rate*dxx += -rho*old_v + (1+rho)*v
-
AdaGrad
grad_squared = 0 while True:dx = compute_gradient(x)grad_squared += dx*dxx -= 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*dxx -= 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)*dxsecond_moment = beta2 * second_moment + (1-beta2)*dx*dxx -= 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)*dxsecond_moment = beta2 * second_moment + (1-beta2)*dx*dxfirst_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 微调
-