具有不同时间步长的 RNN 的 Keras 掩蔽
Keras Masking for RNN with Varying Time Steps
我正在尝试使用具有不同时间长度的序列在 Keras 中拟合 RNN。我的数据位于格式为 (sample, time, feature) = (20631, max_time, 24)
的 Numpy 数组中,其中 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))
为了完整起见,这里是损失函数的代码:
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)
这里是自定义激活函数的代码:
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)
当我拟合模型并做出一些测试预测时,测试集中的每个样本都得到完全相同的预测,这看起来很可疑。
如果我移除遮蔽层,情况会好转,这让我觉得遮蔽层有问题,但据我所知,我完全按照文档进行操作。
掩蔽层是否有错误指定?我还漏掉了什么吗?
没有实际数据我无法验证,但我对 RNN 有类似的经历。在我的例子中,规范化解决了这个问题。为您的模型添加规范化层。
您实现屏蔽的方式应该是正确的。如果您有形状为 (samples, timesteps, features) 的数据,并且您想要使用与 features 参数大小相同的零掩码来掩盖缺少数据的时间步,那么您添加 Masking(mask_value=0., input_shape=(timesteps, features))
。看这里:keras.io/layers/core/#masking
您的模型可能过于简单,and/or 您的迭代次数可能不足以让模型区分所有 类。试试这个模型:
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))
如果这不起作用,请尝试将历元数加倍几次(例如 200、400),看看是否能改善结果。
我正在尝试使用具有不同时间长度的序列在 Keras 中拟合 RNN。我的数据位于格式为 (sample, time, feature) = (20631, max_time, 24)
的 Numpy 数组中,其中 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))
为了完整起见,这里是损失函数的代码:
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)
这里是自定义激活函数的代码:
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)
当我拟合模型并做出一些测试预测时,测试集中的每个样本都得到完全相同的预测,这看起来很可疑。
如果我移除遮蔽层,情况会好转,这让我觉得遮蔽层有问题,但据我所知,我完全按照文档进行操作。
掩蔽层是否有错误指定?我还漏掉了什么吗?
没有实际数据我无法验证,但我对 RNN 有类似的经历。在我的例子中,规范化解决了这个问题。为您的模型添加规范化层。
您实现屏蔽的方式应该是正确的。如果您有形状为 (samples, timesteps, features) 的数据,并且您想要使用与 features 参数大小相同的零掩码来掩盖缺少数据的时间步,那么您添加 Masking(mask_value=0., input_shape=(timesteps, features))
。看这里:keras.io/layers/core/#masking
您的模型可能过于简单,and/or 您的迭代次数可能不足以让模型区分所有 类。试试这个模型:
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))
如果这不起作用,请尝试将历元数加倍几次(例如 200、400),看看是否能改善结果。