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

我在R中使用Keras训练了一个全连接神经网络,用于时间序列预测(二元分类)。为了使用标准的多层感知器来完成这项任务,我使用了滑动窗口方法对时间序列数据进行转换(添加滞后输入特征到数据中)。因此,假设有一个二元标签,两个输入时间序列,查看回溯期为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
...

在接下来的步骤中,我为数据划分创建了两个阈值,用于将数据划分为训练集、验证集和测试集,并基于这些阈值进行实际的划分:

## 阈值
train_valid_split = 1700
valid_test_split = 1800
## 特征数量(数据矩阵的列数减去第一个标签列)
features = ncol(data_mlp) - 1 
## 用于存放训练集、验证集和测试集的容器(包括输入x和标签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)))
## 使用数据填充容器
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模型:

## 验证步骤
valid_steps = valid_test_split - train_valid_split
## Keras顺序模型
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  
...

我不明白为什么概率会相同。我尝试了不同的输入数据、不同的回溯期(更多或更少的滞后)、更多的epoch、更多的steps_per_epoch、不同的优化器、不同的单位数量等。预测的概率确实发生了变化,但它们始终对所有输入都是相同的。

有趣的是,在相同的数据上使用相同的验证和测试划分以及相同的回溯期的LSTM模型不会产生相同的概率。LSTM的结果要合理得多。但我也想尝试MLP + 滑动窗口方法,因为我读到它在某些任务上可能会带来更好的预测性能。所以我猜测我的数据准备(滑动窗口)或模型架构中可能存在错误,但我无法找出问题所在…

如果你有任何关于结果为何如此以及我如何能改变它的建议,我将非常感激。

非常感谢。

最好的祝愿,hokage

附注:如果你需要更多信息,请告诉我需要什么,我会尽力回答。


回答:

代码中有一个拼写错误,导致输入向量只有零。现在已修复,代码正常工作。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注