[关闭]
@zhuanxu 2018-02-23T09:42:56.000000Z 字数 4768 阅读 928

深度学习实战第四课

fast-ai


上来先是前3课学生做的一些优秀笔记:

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

Dropout [04:59]

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

learn
Sequential(
(0): BatchNorm1d(1024, eps=1e-05, momentum=0.1, affine=True)
(1): Dropout(p=0.5)
(2): Linear(in_features=1024, out_features=512)
(3): ReLU()
(4): BatchNorm1d(512, eps=1e-05, momentum=0.1, affine=True)
(5): Dropout(p=0.5)
(6): Linear(in_features=512, out_features=120)
(7): LogSoftmax()
)

(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是一种防止过拟合的正则化方法。

注意

为什么我们在实际训练中经常发现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都不会加进模型中:

Sequential(
(0): BatchNorm1d(4096, eps=1e-05, momentum=0.1, affine=True)
(1): Linear(in_features=4096, out_features=512)
(2): ReLU()
(3): BatchNorm1d(512, eps=1e-05, momentum=0.1, affine=True)
(4): Linear(in_features=512, out_features=120)
(5): LogSoftmax()
)

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

learn = ConvLearner.pretrained(arch, data, ps=0., precompute=True,
xtra_fc=[]); learn
Sequential(
(0): BatchNorm1d(1024, eps=1e-05, momentum=0.1, affine=True)
(1): Linear(in_features=1024, out_features=120)
(2): LogSoftmax()
)
learn = ConvLearner.pretrained(arch, data, ps=0., precompute=True,
xtra_fc=[700, 300]); learn
Sequential(
(0): BatchNorm1d(1024, eps=1e-05, momentum=0.1, affine=True)
(1): Linear(in_features=1024, out_features=700)
(2): ReLU()
(3): BatchNorm1d(700, eps=1e-05, momentum=0.1, affine=True)
(4): Linear(in_features=700, out_features=300)
(5): ReLU()
(6): BatchNorm1d(300, eps=1e-05, momentum=0.1, affine=True)
(7): Linear(in_features=300, out_features=120)
(8): LogSoftmax()
)

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

learn = ConvLearner.pretrained(arch, data, ps=[0., 0.2],
precompute=True, xtra_fc=[512]); learn
Sequential(
(0): BatchNorm1d(4096, eps=1e-05, momentum=0.1, affine=True)
(1): Linear(in_features=4096, out_features=512)
(2): ReLU()
(3): BatchNorm1d(512, eps=1e-05, momentum=0.1, affine=True)
(4): Dropout(p=0.2)
(5): Linear(in_features=512, out_features=120)
(6): LogSoftmax()
)

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

有两种类别的列数据:

Categorical 变量 [50:49]


通过embed方式,我们将DayOfWeek由一个number转换为了一个4维向量。
问题:我们怎么去选择embed size?

  1. cat_sz = [(c, len(joined_samp[c].cat.categories)+1)
  2. for c in cat_vars]
  3. cat_sz
  4. [('Store', 1116),
  5. ('DayOfWeek', 8),
  6. ('Year', 4),
  7. ('Month', 13),
  8. ('Day', 32),
  9. ('StateHoliday', 3),
  10. ('CompetitionMonthsOpen', 26),
  11. ('Promo2Weeks', 27),
  12. ('StoreType', 5),
  13. ('Assortment', 4),
  14. ('PromoInterval', 4),
  15. ('CompetitionOpenSinceYear', 24),
  16. ('Promo2SinceYear', 9),
  17. ('State', 13),
  18. ('Week', 53),
  19. ('Events', 22),
  20. ('Promo_fw', 7),
  21. ('Promo_bw', 7),
  22. ('StateHoliday_fw', 4),
  23. ('StateHoliday_bw', 4),
  24. ('SchoolHoliday_fw', 9),
  25. ('SchoolHoliday_bw', 9)]

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类型的数据?

  1. add_datepart(weather, "Date", drop=False)
  2. add_datepart(googletrend, "Date", drop=False)
  3. add_datepart(train, "Date", drop=False)
  4. add_datepart(test, "Date", drop=False)

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

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

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

1.列举出所有 categorical variable 和 continuous variable 的名字,将其放入 Pandas data frame
2.创建 validation set 的 indexes
3.调用如下代码:

  1. md = ColumnarModelData.from_data_frame(PATH, val_idx, df,
  2. yl.astype(np.float32), cat_flds=cat_vars, bs=128,
  3. test_df=df_test)

4.计算出每个 categorical variable 的 Embed size
5.调用 get_learner

  1. m = md.get_learner(emb_szs, len(df.columns)-len(cat_vars), 0.04, 1,
  2. [1000,500], [0.001,0.01], y_range=y_range)

6.调用m.fit


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

fastai正式版本地址
第四课wiki地址

你的鼓励是我继续写下去的动力,期待我们共同进步。
这个时代,每个人都是超级个体!关注我,一起成长!

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注