Keras(R) - 为什么所有输入的预测概率(二进制分类)都相同?

时间:2018-04-06 11:15:15

标签: r machine-learning keras time-series sliding-window

我在R中使用Keras训练一个完全连接的神经网络进行时间序列预测(二进制分类)。为了使用标准多层感知器执行此任务,我使用滑动窗口方法(将滞后输入功能添加到数据)转换我的时间序列数据。因此,使用1个二进制标签,2个输入时间序列和2个回溯(用于说明),转换后的数据具有以下结构:

    label     a     b     a.1     b.1     a.2     b.2
1    1       0.1   0.3     NA      NA      NA      NA
2    1       0.2   0.2     0.1    0.3      NA      NA
3    0       0.4   0.4     0.2    0.2      0.1    0.3
4    1       0.1   0.6     0.4    0.4      0.2    0.2
5    0       0.15  0.25    0.1    0.6      0.4    0.4
...

省略NA行并删​​除a和b列后,使用的数据矩阵如下所示:

    label    a.1     b.1     a.2     b.2
3    0       0.2     0.2     0.1     0.3
4    1       0.4     0.4     0.2     0.2
5    0       0.1     0.6     0.4     0.4
...

在接下来的步骤中,我创建了两个阈值,用于在列车,验证和测试集中拆分数据,并根据这些阈值进行实际拆分:

## Thresholds
train_valid_split = 1700
valid_test_split = 1800

## amount of features (columns of data matrix minus first label column)
features = ncol(data_mlp) - 1 

## Container for train, validation and test set (both input x and label y)
train_x = array(0, dim = c(train_valid_split, features))
train_y = array(0, dim = c(train_valid_split))
valid_x = array(0, dim = c((valid_test_split-train_valid_split), features))
valid_y = array(0, dim = c((valid_test_split-train_valid_split)))
test_x = array(0, dim = c((nrow(data_mlp)-valid_test_split), features))
test_y = array(0, dim = c((nrow(data_mlp)-valid_test_split)))

## Fill container with the data
train_x = data_mlp[1:train_valid_split, 2:ncol(data_mlp)]
train_y = data_mlp[1:train_valid_split, 1, drop=F]
valid_x = data_mlp[(train_valid_split+1):valid_test_split, 2:ncol(data_mlp)]
valid_y = data_mlp[(train_valid_split+1):valid_test_split, 1, drop=F]
test_x = data_mlp[(valid_test_split+1):nrow(data_mlp), 2:ncol(data_mlp)]
test_y = data_mlp[(valid_test_split+1):nrow(data_mlp), 1, drop=F]

在计算验证步骤的数量后,我训练并拟合以下Keras模型:

## Validation steps
valid_steps = valid_test_split - train_valid_split

## Keras sequential model
model = keras_model_sequential() %>%
  layer_dense(units = 32, input_shape = c(features),
              activation = "relu") %>%
  layer_dense(units = 1, activation = "sigmoid")

model %>% compile(
  optimizer = "adam", # rmsprop
  loss = "binary_crossentropy",
  metrics = c("accuracy")
)

history = model %>% fit(
  x = train_x,
  y = train_y,
  steps_per_epoch = 90,
  epochs = 10,
  validation_data = list(valid_x, valid_y),
  validation_steps = valid_steps,
  shuffle=FALSE
)

然而,当通过预测所有测试输入的类概率来评估测试集上的模型时,所有概率都完全相同。因此,每个输入都会预测相同的类。

> results = model %>% predict(test_x)
> results
           [,1]
 [1,] 0.5740806
 [2,] 0.5740806
 [3,] 0.5740806
 [4,] 0.5740806
 [5,] 0.5740806
 [6,] 0.5740806
 [7,] 0.5740806
  ...

我不明白为什么概率是相同的。我尝试使用不同的输入数据,不同的回顾(或多或少滞后),更多的纪元,更多的步骤_Pep,不同的优化器,不同的单位数量等等。预测的概率发生了变化,但它们对于所有输入始终是相同的。

有趣的是,对相同数据的lstm模型,具有相同的验证和测试分裂以及相同的回顾并不会产生相同的概率。 lstm结果更合理。但我也想尝试MLP +滑动窗口方法,因为我读到它可能会在某些任务上产生更好的预测性能。所以我的猜测是我的数据准备(滑动窗口)或模型架构存在错误,但我无法弄清楚它是什么......

如果您对结果原因以及如何更改结果有任何建议,我将非常感激。

非常感谢。

Best,hokage

PS:如果您需要更多信息,请告诉我它是什么,我会尽力回答。

1 个答案:

答案 0 :(得分:0)

代码中存在拼写错误,导致输入向量仅为零。现在它已修复并且代码正常工作。