@zhuanxu
2018-02-23T17:42:56.000000Z
字数 4768
阅读 2280
fast-ai
上来先是前3课学生做的一些优秀笔记:
课程覆盖内容概览,当前在第4课。
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=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()
)
有两种类别的列数据:
通过embed方式,我们将DayOfWeek由一个number转换为了一个4维向量。
问题:我们怎么去选择embed size?
cat_sz = [(c, len(joined_samp[c].cat.categories)+1)
for c in cat_vars]
cat_sz
[('Store', 1116),
('DayOfWeek', 8),
('Year', 4),
('Month', 13),
('Day', 32),
('StateHoliday', 3),
('CompetitionMonthsOpen', 26),
('Promo2Weeks', 27),
('StoreType', 5),
('Assortment', 4),
('PromoInterval', 4),
('CompetitionOpenSinceYear', 24),
('Promo2SinceYear', 9),
('State', 13),
('Week', 53),
('Events', 22),
('Promo_fw', 7),
('Promo_bw', 7),
('StateHoliday_fw', 4),
('StateHoliday_bw', 4),
('SchoolHoliday_fw', 9),
('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类型的数据?
add_datepart(weather, "Date", drop=False)
add_datepart(googletrend, "Date", drop=False)
add_datepart(train, "Date", drop=False)
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.调用如下代码:
md = ColumnarModelData.from_data_frame(PATH, val_idx, df,
yl.astype(np.float32), cat_flds=cat_vars, bs=128,
test_df=df_test)
4.计算出每个 categorical variable 的 Embed size
5.调用 get_learner
m = md.get_learner(emb_szs, len(df.columns)-len(cat_vars), 0.04, 1,
[1000,500], [0.001,0.01], y_range=y_range)
6.调用m.fit
本文是 fastai 课程的第四课结构化处理部分,欢迎持续关注。
你的鼓励是我继续写下去的动力,期待我们共同进步。