586. Child Mind Institute - Detect Sleep States | child-mind-institute-detect-sleep-states
首先,感谢我的队友 @robikscube。这是一次有趣的旅程。我们注意到公共排行榜(Public LB)不太可靠,因此重点关注了交叉验证(CV)。最终我们的交叉验证得分约为 0.826。
我们的主要模型是一个经过修改的 wavenet。 它处理的是按分钟聚合的 3 天时间序列数据。
class SleepModel(nn.Module):
def __init__(self, inch, kernel_size):
super(SleepModel, self).__init__()
emb_size = 4
self.minute_emb = nn.Embedding(15, embedding_dim=emb_size)
self.bn = nn.BatchNorm1d(inch-1)
self.wave_block1 = Wave_Block(inch-1+emb_size, 32, 8, kernel_size)
self.wave_block2 = Wave_Block(32, 32, 7, kernel_size, base=2.25)
self.wave_block3 = Wave_Block(32, 64, 4, kernel_size)
self.wave_block4 = nn.Sequential(nn.Conv1d(128, 64, kernel_size=5, dilation=DAY_LEN//6),
nn.BatchNorm1d(64), nn.LeakyReLU(),
nn.Conv1d(64, 64, kernel_size=5, dilation=DAY_LEN//3),
nn.BatchNorm1d(64), nn.LeakyReLU()
)
self.top = nn.Conv1d(64, 3, kernel_size=1)
self.top2 = nn.Conv1d(64, 2, kernel_size=1)
self.gn1 = nn.GroupNorm(4, 32)
self.gn2 = nn.GroupNorm(4, 32)
self.avgpool = nn.AvgPool1d(kernel_size=DAY_LEN+1, padding=DAY_LEN//2, stride=1)
self.maxpool = nn.MaxPool1d(kernel_size=DAY_LEN+1, padding=DAY_LEN//2, stride=1)
def forward(self, x):
x = torch.cat([x[:, -DAY_LEN:]*0, x, x[:, :DAY_LEN]*0], axis=1)
x = x.permute(0, 2, 1)
minute, x = x[:, -1, :], x[:, :-1, :]
x[:, -1, :] += minute / 60 # hour + minute/60
x = self.bn(x)
minute_emb = self.minute_emb(torch.fmod(minute, 15).long()) # minute % 15 is an important feature
x = torch.cat([x, minute_emb.permute(0, 2, 1)], axis=1)
x = self.wave_block1(x)
x = self.gn1(x)
x = self.wave_block2(x)
x = self.gn2(x)
x = self.wave_block3(x)
x = torch.cat([x, self.avgpool(x[:, :32]), self.maxpool(x[:, 32:])], axis=1)
x = self.wave_block4(x)
x, x2 = self.top(x), self.top2(x)
return x, x2
使用的特征包括:
["target", "idx", "anglez_mean", "anglez_std",
"enmo_mean", "enmo_std",
"same_anglez_prev_min", "same_anglez_next_min"] +
volatility_cols + ["hour", "minute"]
波动率特征(Volatility columns)是在三个不同时间窗口(5、30、480步)上对 anglez 绝对差值取中位数得到的。
Same anglez 前后特征是 anglez 与前一天同一分钟的差值。