深度学习实战第四课

本文是fastai课程第4课笔记,上来先是前3课学生做的一些优秀笔记:

Improving the way we work with learning rate

The Cyclical Learning Rate technique

Exploring Stochastic Gradient Descent with Restarts (SGDR)

Transfer Learning using differential learning rates

Getting Computers To See Better Than Humans

课程覆盖内容概览,当前在第4课。

Dropout [04:59]

learn:输出我们在卷基层后加入的网络,上面显示的是precompute=True时,我们需要训练的网络层

(0), (4):BatchNorm将会在最后一课讲述

(1), (5): Dropout

(2):Linear 全连接层

(3):ReLU 去除负值

(6): Linear 第二个全连接层,输出为类别数

7): LogSoftmax 通过log提高运算精度

什么是 Dropout 和 p? [08:17]

Dropout(p=0.5)

p代表我们需要随机丢弃的激活层输出,p=0.5 表示我们随机丢弃50%的输出,Dropout是一种防止过拟合的正则化方法。

注意

默认情况下第一层的p=0.25,第二层是0.5[17:54],如果我们训练中发现过拟合,尝试增大p到0.5,如果还是过拟合则到0.7。

ResNet34 相对来说网络层数少,还不是很复杂,我们可以使用默认的dropout,但是像ResNet50,如果出现过拟合,我们将调大dropout。

为什么我们在实际训练中经常发现val-loss小于train-loss的情况,特别是在训练刚开始的时候?因为我们在做 inference 的时候,dropout=0,即利用了所有信息。

在fast.ai中我们通过参数ps来设置新增网络的层的dropout,我们不会去改变pre-trained网络的dropout,因为这些都是已经训练好的了。

learn = ConvLearner.pretrained(arch, data, ps=0.5, precompute=True)

我们可以设置ps=0,但是会发现训练几个epoch后就会出现过拟合现象(training loss ≪ validation loss):

[2. 0.3521 0.55247 0.84189]

当ps=0.的时候,Dropout都不会加进模型中:

我们可以发现上面我们默认添加了2个全连接层,我们可以通过参数xtra_fc来控制。

问题:我们是否可以设置不同的dropout,当然可以,通过参数ps来控制。

我们没有什么理论来指导我们是前面的层dropout大还是后面的层大

当我们不确定的时候,我们最好使用相同的dropout

一般只在最后一层设置Dropout

结构化、时序数据学习[25:03]

有两种类别的列数据:类别(Categorical),一般有不同的level,连续(continuous),一般是浮点数

像 Year , Month 这种整数,我们可以将其看做连续也可以是类别,如果是类别,那就是告诉神经网络Year的不同值是完全不同的,而如果是连续,则是找到一个函数进行fit,更具体的解释可以看到之前的文章为什么要做one-hot

选择Categorical和continuous是需要在建模阶段做出的决策,一般来说如果数据是Categorical的,那就是Categorical,如果数据是continuous的,我们需要决定是continuous还是Categorical

一般来说,如果值是浮点型,我们很难将其转换为Categorical(我们将类别的数目称为 Cardinality)

Categorical 变量 [50:49]

通过embed方式,我们将DayOfWeek由一个number转换为了一个4维向量。

问题:我们怎么去选择embed size?

上面我们列举出了所有的categorical variable 和它的 cardinality

我们每个类别都加了一个1,目的是如果该列出现空值,可以用0表示

选择 embed size 的经验是:将 cardinality / 2,最大不超过50

emb_szs = [(c, min(50, (c+1)//2)) for _,c in cat_sz]

问题:embeddings 适合所有的 categorical variable 嘛?

假设我们有 600,000 行数据,并且某列特征有 600,000 个不同值,此时是非常不好的 categorical variable。

问题:我们如何处理dates and times类型的数据?

fastai中有个<code>add_datepart/<code>函数,能够将一个时间列转换为多个列。

举个例子来说明这么处理的好处,假设我们发现数据有周期性的特征,在Mondays上升,Wednesdays下降,如果没有dayOfWeek特征,我们很难让网络自己去根据2018-02-23去学习出来,但是有了dayOfWeek就容易很多。

下面总结下整个处理过程:

本文是 fastai 课程的第四课结构化处理部分,欢迎持续关注。

fastai正式版本地址

第四课wiki地址

你的鼓励是我继续写下去的动力,期待我们共同进步,欢迎关注。