深度学习一些概念整理

全连接层转换为卷积层

如何转换

卷积层与全连接层可以相互转换,例如,对于输入为 7 7 512 的有 4096 个神经元的全连接层,可以表示为如下的卷积层:

  • Kernel size: 7
  • Padding: 0
  • Stride: 1
  • Filters: 4096

这样卷积层输出就是 1 1 4096,与全连接层的输出相同。

转换的原理

还是以上面的为例,全连接层的每个输出(1/4096)需要输入的每一个元素都参与,即:

Dense_{out_i} = \Sigma_{j=1}^{25088}{(w_{ij} * in_j)} \\ i = 1, 2, \dots, 4096

而对应的卷积层的输出也是需要每个元素的参与,即:

Conv_{out_i} = \Sigma_{j=1}^{512}{\Sigma_{k=1}^{49}{(w_{ijk} * in_{jk})}} \\ i = 1, 2, \dots, 4096

可以看出来,本质没有变,只是形式变了。

转换的作用

  • 便于计算不同分辨率的输入

比如 AlexNet 输入为 227 227,如果输入为 384 384 则到了全连接层会报错,而如果进行了如上转换,则会正常输出,不过输出结果为 6 6 1000 而非 1 1 1000。

实际上,常用于分割任务上的全卷积网络(FCN)就使用了这种方法去掉了全连接层以支持不同分辨率的输入。

1 * 1 卷积核作用

  • 实现数据维度改变

可以把维度从 m n 10 改变到 m n 5 或者 m n 50,只需要改变 filter 的数量

  • 实现跨通道的交互信息的整合

由于次个卷积会把多个通道的信息汇总,因此这个 1 * 1 卷积的过程也会把跨通道的交互信息整合起来

  • 增加非线性

通过卷积之后的非线性激活函数来实现

具体讲解参考这篇文章

Global Average Pooling (GAP) 作用

GAP 是用来将每个通道的信息统一到同一个像素上,比如输入为 7 7 512 的张量,经过 GAP 之后输出就是 1 1 512。

  • 代替全连接层

CNN 最后一层卷积的输出就是一个高度提取的 feature map(本质上是特征),而全连接层就是将最后一层卷积得到的特征整合起来映射到样本空间(分类,识别等)(由于有非线性激活函数,因此不是线性映射)。

具体理解参照这个回答

关于 GAP 的效果对比可以参考这篇博客

我自己在小型的神经网络上训练的结果(GAP 代替了 128 FC)是使用 GAP 提高了 2% 左右的准确度。

batch

深度学习更新参数通常不是由一个数据来决定的,不然更新的方向可能会差别较大(一下这边一下那边)。

一批里面有多个数据更容易朝着正确的方向进行,利用各个数据之间的一些共性。

另外,使用批处理也避免了一次使用所有数据进行训练,减小了显存的压力,也更有可能找到极小值。

epoch

一个完整的数据集经过网络一次并返回一次的结果。一个 epoch 并不一定能让网络达到最佳的方向,因而要训练多个 epoch,但是训练过多会过拟合。

Batch Normalization 作用

将一个 batch 中的各个元素归一化(各个通道分别进行 BN),通常放到激活函数之前。

好处:

  • 减小梯度弥散(梯度消失/爆炸)

改变激活函数的输入,让数据分布更均匀,从而杀掉的神经元更少。

  • 训练更快,可以用更高的学习率

数据分布更均匀,神经网络不用去适应各种分布

  • 一定程度增加泛化能力,避免过拟合

数据通过 BN 处理引入的随机噪声能够起到对模型参数进行正则化的作用,有利于增强模型泛化能力

缺陷:

  • 不适用 batch 非常小
  • 不适用 RNN

关于 BN 的理解,尤其是背后的原理理解参考这篇文章

验证/测试集的作用

验证集

  • 与测试集同分布,用来观察训练的走向(是否过拟合等)
  • 选择超参数

测试集

评估模型的训练状况,检验泛化能力

Softmax 是什么

Softmax 函数用来产生 k 个概率,而 Softmax 损失函数,准确来说是用 Softmax 的结果来计算交叉熵分类损失函数。

Softmax 函数可以参考这篇博文,交叉熵可以参考这篇博文

logits 是什么

出现于 tf.nn.softmax_cross_entropy_with_logits,简单来说就是 softmax 的输入。更多内容可以参考这个问题

weight 的冷知识

weight decay = 对 weight 施加 norm = 对输入数据增加方差小的噪音