针对RNN的Keras屏蔽具有不同的时间步长

Joh*_*tom 21 python numpy neural-network keras recurrent-neural-network

我正在尝试使用具有不同时间长度的序列在Keras中安装RNN.我的数据是在一个numpy的阵列格式(sample, time, feature) = (20631, max_time, 24),其中max_time在运行时被确定为可用于与最时间戳采样时间的步数.我已经填写了每个时间序列的开头0,除了最长的一个,显然.

我最初定义了我的模型......

model = Sequential()
model.add(Masking(mask_value=0., input_shape=(max_time, 24)))
model.add(LSTM(100, input_dim=24))
model.add(Dense(2))
model.add(Activation(activate))
model.compile(loss=weibull_loglik_discrete, optimizer=RMSprop(lr=.01))
model.fit(train_x, train_y, nb_epoch=100, batch_size=1000, verbose=2, validation_data=(test_x, test_y))
Run Code Online (Sandbox Code Playgroud)

为了完整性,这里是损失函数的代码:

def weibull_loglik_discrete(y_true, ab_pred, name=None):
    y_ = y_true[:, 0]
    u_ = y_true[:, 1]
    a_ = ab_pred[:, 0]
    b_ = ab_pred[:, 1]

    hazard0 = k.pow((y_ + 1e-35) / a_, b_)
    hazard1 = k.pow((y_ + 1) / a_, b_)

    return -1 * k.mean(u_ * k.log(k.exp(hazard1 - hazard0) - 1.0) - hazard1)
Run Code Online (Sandbox Code Playgroud)

这是自定义激活功能的代码:

def activate(ab):
    a = k.exp(ab[:, 0])
    b = k.softplus(ab[:, 1])

    a = k.reshape(a, (k.shape(a)[0], 1))
    b = k.reshape(b, (k.shape(b)[0], 1))

    return k.concatenate((a, b), axis=1)
Run Code Online (Sandbox Code Playgroud)

当我拟合模型并进行一些测试预测时,测试集中的每个样本都会获得完全相同的预测,这看起来很可疑.

如果我删除屏蔽层会让事情变得更好,这让我觉得屏蔽层有问题,但据我所知,我已完全按照文档进行操作.

是否有掩盖层错误指定的内容?我错过了别的什么吗?

vag*_*ton 6

没有实际数据我无法验证,但我对 RNN 有类似的经验。在我的情况下,规范化解决了这个问题。向模型添加规范化层。


Rob*_*cia 5

您实施屏蔽的方法应该是正确的。如果您拥有形状(样本,时间步长,要素)形状的数据,并且想用零距掩码(与features参数相同来掩盖缺少数据的时间步长,则添加Masking(mask_value=0., input_shape=(timesteps, features))。参见此处:keras.io/layers/core/#masking

您的模型可能太简单,和/或时期数量可能不足以使模型区分所有类。试试这个模型:

model = Sequential()
model.add(Masking(mask_value=0., input_shape=(max_time, 24)))
model.add(LSTM(256, input_dim=24))
model.add(Dense(1024))
model.add(Dense(2))
model.add(Activation(activate))
model.compile(loss=weibull_loglik_discrete, optimizer=RMSprop(lr=.01))
model.fit(train_x, train_y, nb_epoch=100, batch_size=1000, verbose=2, validation_data=(test_x, test_y)) 
Run Code Online (Sandbox Code Playgroud)

如果这样不起作用,请尝试将历元加倍几次(例如200、400),看看是否可以改善结果。