Keras:具有类权重的LSTM

时间:2016-08-11 08:41:11

标签: keras lstm

我的问题与this question密切相关,但也超越了它。

我正在尝试在Keras中实现以下LSTM

  • 时间步长为nb_tsteps=10
  • 输入要素的数量为nb_feat=40
  • 每个时间步的LSTM单元格数为120
  • LSTM图层后跟TimeDistributedDense图层

从上面提到的问题我明白我必须将输入数据显示为

nb_samples, 10, 40

我通过在形状nb_samples的原始时间序列中滚动长度为nb_tsteps=10的窗口来获取(5932720, 40)。因此代码是

model = Sequential()
model.add(LSTM(120, input_shape=(X_train.shape[1], X_train.shape[2]), 
  return_sequences=True, consume_less='gpu'))
model.add(TimeDistributed(Dense(50, activation='relu')))
model.add(Dropout(0.2))
model.add(TimeDistributed(Dense(20, activation='relu')))
model.add(Dropout(0.2))
model.add(TimeDistributed(Dense(10, activation='relu')))
model.add(Dropout(0.2))
model.add(TimeDistributed(Dense(3, activation='relu')))
model.add(TimeDistributed(Dense(1, activation='sigmoid')))

现在回答我的问题(假设到目前为止上述内容是正确的): 二进制响应(0/1)严重失衡,我需要将class_weight字典cw = {0: 1, 1: 25}传递给model.fit()。但是我得到了例外class_weight not supported for 3+ dimensional targets。这是因为我将响应数据显示为(nb_samples, 1, 1)。如果我将其重塑为2D数组(nb_samples, 1),我会得到异常Error when checking model target: expected timedistributed_5 to have 3 dimensions, but got array with shape (5932720, 1)

非常感谢您的帮助!

3 个答案:

答案 0 :(得分:5)

我认为您应该将sample_weightsample_weight_mode='temporal'一起使用。

来自Keras文档:

  

sample_weight:使用的训练样本的Numpy权重数组   用于缩放损失函数(仅在训练期间)。你也可以   传递一个平坦的(1D)Numpy数组,其长度与输入样本相同   (权重和样本之间的1:1映射),或者在时间的情况下   数据,你可以传递一个形状为2D的数组(samples,sequence_length),   对每个样本的每个时间步应用不同的权重。在这   你应该确保指定sample_weight_mode =" temporal"在   编译()。

在您的情况下,您需要提供与标签形状相同的2D阵列。

答案 1 :(得分:0)

如果这仍然是一个问题。.我认为TimeDistributed Layer期望并返回3D数组(类似于常规LSTM层中的return_sequences = True)。尝试在预测层之前的末尾添加Flatten()层或另一个LSTM层。

d = TimeDistributed(Dense(10))(input_from_previous_layer)
lstm_out = Bidirectional(LSTM(10))(d)
output = Dense(1, activation='sigmoid')(lstm_out)

答案 2 :(得分:0)

使用temporal是一种解决方法。看看这个stack。该问题也记录在github上。