https://www.yuque.com/lart/ml-newer/
版本号
|
作者
|
时间
|
改动内容
|
0.1
|
Lart
|
2018年10月17日
|
创建文档
|
0.2
|
Lart
|
2018年10月18日10:59:28
|
调整部分内容
|
由于卷积层的 参数共享 设定,导致两种理解是等价的. 而实际运算中,是以第一种理解更为直观,所以多用第一种理解方式来解释问题.
在计算卷积核的卷积时,每一次卷积运算都会有一个偏置项,这一点到时更贴合第2点的理解,每一个神经元的输入连接都有一个偏置项.
注意
有一种设定是不同深度,这会导致更为复杂一些的情况.
沿着深度方向排列、感受野相同的神经元集合称为深度列(depth column),也有人使用纤维(fibre)来称呼它们。
最近一个研究(Fisher Yu和Vladlen Koltun的论文)给卷积层引入了一个新的叫扩张(dilation)的超参数。到目前为止,我们只讨论了卷积层滤波器是连续的情况。但是,让滤波器中元素之间有间隙也是可以的,这就叫做扩张。换句话说,操作中存在1的间隙。在某些设置中,扩张卷积与正常卷积结合起来非常有用,因为在很少的层数内更快地汇集输入图片的大尺度特征。
每个卷积核对应的输出数据体在空间上的尺寸可以通过 输入数据体尺寸(W),卷积层中神经元的 感受野尺寸(F) ,步长(S) 和 零填充的数量(P) 的函数来计算。(这里假设输入数组的空间形状是正方形,即高度和宽度相等)
输出数据体的空间尺寸为
应该使用 小尺寸滤波器(比如3x3或最多5x5),使用步长。
还有一点非常重要,就是对输入数据进行零填充,这样卷积层就不会改变输入数据在空间维度上的尺寸。比如,当,那就使用来保持输入尺寸。当,一般对于任意,当的时候能保持输入尺寸。如果必须使用更大的滤波器尺寸(比如7x7之类),通常只用在第一个面对原始图像的卷积层上。
直观说来,最好选择带有小滤波器的卷积层组合,而不是用一个带有大的滤波器的卷积层。
前者可以表达出输入数据中更多个强力特征,使用的参数也更少 。
唯一的不足是,在进行 反向传播时,中间的卷积层可能会导致占用更多的内存。
通常,在 连续的卷积层之间会周期性地插入 一个汇聚层。
它的作用是 逐渐降低数据体的空间尺寸,这样的话就能减少网络中参数的数量,使得计算资源耗费变少,也能有效控制过拟合。
在大型网络中,一般担心的是过拟合的问题,而欠拟合关心的少些。
汇聚层使用MAX操作
,对输入数据体的每一个深度切片独立进行操作,改变它的空间尺寸。
在实践中,最大汇聚层通常只有两种形式:一种是也叫重叠汇聚(overlapping pooling),另一个更常用的是对更大感受野进行汇聚需要的汇聚尺寸也更大,而且往往对网络有破坏性。
除了最大汇聚,汇聚单元还可以使用其他的函数,比如平均汇聚(average pooling)或L-2范式汇聚(L2-norm pooling)。平均汇聚历史上比较常用,但是现在已经很少使用了。因为实践证明,最大汇聚的效果比平均汇聚要好。
负责对输入数据的空间维度进行降采样。最常用的设置是用2x2感受野(即)的最大值汇聚,步长为2()。
注意
max
操作的一个求导问题,在向前传播经过汇聚层的时候,通常会把池中最大元素的索引记录下来(有时这个也叫作道岔(switches)),这样在反向传播的时候梯度的路由就很高效。在全连接层中,神经元对于前一层中的所有激活数据是全部连接的,这个常规神经网络中一样。它们的激活可以先用矩阵乘法,再加上偏差。
注意
在两种变换中,将全连接层转化为卷积层在实际运用中更加有用。
补充
卷积神经网络最常见的形式就是将一些卷积层和ReLU层放在一起,其后紧跟汇聚层,然后重复如此直到图像在空间上被缩小到一个足够小的尺寸,在某个地方过渡成全连接层也较为常见。最后的全连接层得到输出,比如分类评分等。换句话说,最常见的卷积神经网络结构如下:
INPUT -> [[CONV -> RELU]*N -> POOL?]*M -> [FC -> RELU]*K -> FC
其中*__指的是重复次数,POOL?指的是一个可选的汇聚层。其中__N >=0,通常N<=3,M>=0,K>=0,通常K<3。
例如,下面是一些常见的网络结构规律:
激活函数的理论作用是使神经网络成为一个普适近似器。
实际建议
在同一个网络中混合使用不同类型的神经元是非常少见的,虽然没有什么根本性问题来禁止这样做。
用ReLU非线性函数。注意设置好学习率,或许可以监控你的网络中死亡的神经元占的比例。
如果单元死亡问题困扰你,就试试Leaky ReLU或者Maxout,不要再用sigmoid了。
也可以试试tanh,但是其效果应该不如ReLU或者Maxout。
在训练完毕后,虽然不知道网络中每个权重的最终值应该是多少,但如果数据经过了恰当的归一化的话,就可以假设所有权重数值中大约一半为正数,一半为负数。
这样,一个听起来蛮合理的想法就是把这些权重的初始值都设为0吧,因为在期望上来说0是最合理的猜测。这个做法错误的!
因为如果网络中的每个神经元都计算出同样的输出,然后它们就会在反向传播中计算出同样的梯度,从而进行同样的参数更新。换句话说,如果权重被初始化为同样的值,神经元之间就失去了不对称性的源头。
实际建议 当前的推荐是使用ReLU激活函数,并且使用w = np.random.randn(n) * sqrt(2.0/n)
来进行权重初始化.网络中可以使用批量归一化来动态处理权重.
主要目的是为了防止网络过拟合.
主要分为两类.
一类是作为损失函数的正则化损失部分, 常见的是L范数.
L1正则化的神经元最后使用的是它们最重要的输入数据的稀疏子集,同时对于噪音输入则几乎是不变的了。
L2正则化中的权重向量大多是分散的小数字。
实际建议 如果不是特别关注某些明确的特征选择,一般说来L2正则化都会比L1正则化效果好。
L1和L2正则化也可以进行组合:,这也被称作Elastic net regularizaton。
另外一类是网络传递中的操作, 如随机失活.
""" 普通版随机失活: 不推荐实现 """
p = 0.5 # 激活神经元的概率. p值更高 = 随机失活更弱,越容易保留神经元
def train_step(X):
""" X中是输入数据 """
# 3层neural network的前向传播
H1 = np.maximum(0, np.dot(W1, X) + b1) # 第一层输出
U1 = np.random.rand(*H1.shape) < p # 第一个随机失活遮罩,要失活的位置就是0,也就是值大于p的要失活
H1 *= U1 # drop!
H2 = np.maximum(0, np.dot(W2, H1) + b2) # 第二层输出
U2 = np.random.rand(*H2.shape) < p # 第二个随机失活遮罩
H2 *= U2 # drop!
out = np.dot(W3, H2) + b3 # 第三层输出 = 第三层输入
# 反向传播:计算梯度... (略)
# 进行参数更新... (略)
def predict(X):
# 前向传播时模型集成
H1 = np.maximum(0, np.dot(W1, X) + b1) * p # 注意:激活数据要乘以p
H2 = np.maximum(0, np.dot(W2, H1) + b2) * p # 注意:激活数据要乘以p
out = np.dot(W3, H2) + b3
注意 在训练的时候,要随机失活,但是在预测的时候,不进行随机失活,但是对于两个隐层的输出都要乘以,调整其数值范围.
"""
反向随机失活: 推荐实现方式.
在训练的时候drop和调整数值范围,测试时不做任何事.
"""
p = 0.5 # 激活神经元的概率. p值更高 = 随机失活更弱
def train_step(X):
# 3层neural network的前向传播
H1 = np.maximum(0, np.dot(W1, X) + b1)
U1 = (np.random.rand(*H1.shape) < p) / p # 第一个随机失活遮罩. 注意/p!
H1 *= U1 # drop!
H2 = np.maximum(0, np.dot(W2, H1) + b2)
U2 = (np.random.rand(*H2.shape) < p) / p # 第二个随机失活遮罩. 注意/p!
H2 *= U2 # drop!
out = np.dot(W3, H2) + b3
# 反向传播:计算梯度... (略)
# 进行参数更新... (略)
def predict(X):
# 前向传播时模型集成
H1 = np.maximum(0, np.dot(W1, X) + b1) # 不用数值范围调整了
H2 = np.maximum(0, np.dot(W2, H1) + b2)
out = np.dot(W3, H2) + b3
注意 在训练的时候,要随机失活,并除以对应的概率,但是在预测的时候,不进行随机失活,对于两个隐层的输出不再需要乘以.
实际建议
值一般默认设为0.5,也可能在验证集上调参。
我们已经讨论过损失函数的正则化损失部分,它可以看做是对模型复杂程度的某种惩罚。
损失函数的第二个部分是数据损失,它是一个有监督学习问题,用于衡量分类算法的预测结果(即分类评分)和真实标签结果之间的一致性。数据损失是对所有样本的数据损失求平均。
在该问题中,假设有一个装满样本的数据集,每个样本都有一个唯一的正确标签(是固定分类标签之一)。
当标签集非常庞大(例如字典中的所有英语单词,或者ImageNet中的22000种分类),就需要使用 分层Softmax(Hierarchical Softmax) 了(参考文献)。
分层softmax将标签分解成一个树。每个标签都表示成这个树上的一个路径,这个树的每个节点处都训练一个Softmax分类器来在左和右分枝之间做决策。树的结构对于算法的最终结果影响很大,而且一般需要具体问题具体分析。
上面两个损失公式的前提,都是假设每个样本只有一个正确的标签。但是如果是一个二值向量,每个样本可能有,也可能没有某个属性,而且属性之间__并不相互排斥__呢?
比如在Instagram上的图片,就可以看成是被一个巨大的标签集合中的某个子集打上标签,一张图片上可能有多个标签。
在这种情况下,一个明智的方法是为每个属性创建一个独立的二分类的分类器。
一个方法: 针对每个分类的二分类器会采用下面的公式:.
上式中,求和是对所有分类,的值为1或者-1,具体根据__第i个样本是否被第j个属性打标签__而定,当该类别__被正确预测并展示__的时候,分值向量为正,其余情况为负。
也就是说,第i个样本是(1)否(-1)被第j个属性打标签时,又是(+)否(-)被预测为该类别,结果为负时,就计算损失.即被打了标签,却没有预测为该类,没打标签却被预测为该类时就计算损失.
另一种方法: 对每种属性训练一个独立的逻辑回归分类器。
然后损失函数最大化这个对数似然函数,问题可以简化为:
是预测实数的值的问题,比如预测房价,预测图片中某个东西的长度等。对于这种问题,通常是计算预测值和真实值之间的损失。然后用L2平方范式或L1范式度量差异。
L2范式 :;
L1范式 则是要将每个维度上的绝对值加起来:
注意 L2损失比起较为稳定的Softmax损失来,其 最优化过程要困难很多 。
所以在面对一个回归问题时,先考虑将输出变成二值化是否真的不够用。例如,如果对一个产品的星级进行预测,使用5个独立的分类器来对1-5星进行打分的效果一般比使用一个回归损失要好很多。分类还有一个额外优点,就是能给出关于回归的输出的分布,而不是一个简单的毫无把握的输出值。
实际建议 如果确信分类不适用,那么使用L2损失吧,但是一定要谨慎:L2非常脆弱,在网络中使用随机失活(尤其是在L2损失层的上一层)不是好主意。
当面对一个回归任务,首先考虑是不是必须这样。一般而言,尽量把你的输出变成二分类,然后对它们进行分类,从而变成一个分类问题。
结构化损失是指 标签可以是任意的结构 ,例如图表、树或者其他复杂物体的情况。通常这种情况还会 假设结构空间非常巨大,不容易进行遍历 。结构化SVM背后的基本思想就是 在正确的结构 和得分最高的非正确结构之间画出一个边界 。
解决这类问题,并不是像解决一个简单无限制的最优化问题那样使用梯度下降就可以了,而是需要设计一些特殊的解决方案,这样可以有效利用对于结构空间的特殊简化假设。