Keras:具有类权重的LSTM



我的问题与这个问题密切相关,但又超越了这个问题。

我试图在Keras中实现以下LSTM

  • 时间步数为nb_tsteps=10
  • 输入特征数为nb_feat=40
  • 每个时间步长LSTM细胞数为120
  • LSTM层之后是timedidistributeddense层

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

nb_samples, 10, 40

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

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)。如果我将其重塑为二维数组(nb_samples, 1),我会得到异常Error when checking model target: expected timedistributed_5 to have 3 dimensions, but got array with shape (5932720, 1)

非常感谢您的帮助!

我认为你应该使用sample_weightsample_weight_mode='temporal'

来自Keras文档:

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

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

如果这仍然是一个问题…我认为timedidistributedlayer期望并返回一个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)

使用temporal是一种变通方法。看看这个堆栈。这个问题也记录在github上。

相关内容

  • 没有找到相关文章

最新更新