【问题标题】:Keras multiclass classification predicts always the same labelKeras 多类分类预测总是相同的标签
【发布时间】:2019-09-09 13:03:21
【问题描述】:

我想训练一个模型来根据物理信号预测一个人的情绪。我有三个物理信号并将其用作输入特征;

ecg(心电图)、gsr(皮肤电反应)、temp(温度)

在我的数据集中,共有 312 条记录属于参与者,每条记录中有 18000 行数据。因此,当我将它们组合成一个数据框时,总共有 5616000 行。

这是我的x_train 数据框;

           ecg     gsr   temp
0        0.1912  0.0000  40.10
1        0.3597  0.0000  40.26
2        0.3597  0.0000  40.20
3        0.3597  0.0000  40.20
4        0.3597  0.0000  40.33
5        0.3597  0.0000  40.03
6        0.2739  0.0039  40.13
7        0.1641  0.0031  40.20
8        0.0776  0.0025  40.20
9        0.0005  0.0020  40.26
10      -0.0375  0.0016  40.03
11      -0.0676  0.0013  40.16
12      -0.1071  0.0010  40.20
13      -0.1197  0.0047  40.20
..      .......  ......  .....
..      .......  ......  .....
..      .......  ......  .....
5616000 0.0226  0.1803  38.43

我有 6 个与情绪相对应的课程。我已经用数字对这些标签进行了编码;

愤怒 = 0,平静 = 1,厌恶 = 2,恐惧 = 3,快乐 = 4,悲伤 = 5

这是我的 y_train;

         emotion
0              0
1              0
2              0
3              0
4              0
.              .
.              .
.              .
18001          1
18002          1
18003          1
.              .
.              .
.              .
360001         2
360002         2
360003         2
.              .
.              .
.              .
.              .
5616000        5

为了给我的 CNN 提供数据,我正在重塑 train_x 和一个热编码 train_y 数据。

train_x = train_x.values.reshape(312,18000,3) #because I have 18000 rows in each record and 3 input features
train_y = train_y.values.reshape(312,18000)

trunc_train_y = train_y[:,:1] # to get 1 label for every 18000 column vector of signal
train_y_enc = pd.DataFrame(trunc_train_y) 
train_y_enc = pd.get_dummies(train_y_enc[0]) # one hot encoded labels

重塑后,我创建了我的 CNN 模型;

model = Sequential()
model.add(Conv1D(2,700,activation='relu',input_shape=(18000,3)))
model.add(Conv1D(2,700,activation='relu'))
model.add(MaxPooling1D(4))
model.add(Conv1D(2,700,activation='relu'))
model.add(Conv1D(2,700,activation='relu'))
model.add(GlobalAveragePooling1D())
model.add(Dropout(0.5))
model.add(Dense(6,activation='softmax'))

model.compile(optimizer = sgd, loss = 'categorical_crossentropy', metrics = ['acc'])
model.fit(train_x,train_y_enc,epochs = 300, batch_size = 32, validation_split=0.33, shuffle=False)

问题是,准确率不会超过 0.2,当我检查预测时,它总是预测同一个类别。我尝试过增加层数调整学习率改变损失函数改变优化器但是没有什么能帮助我解决这个问题。

这是混淆矩阵;

我该如何解决这个问题?提前致谢。

【问题讨论】:

  • 您对数据的处理看起来很奇怪。我认为应该是(train_sample_length, num_features)。另外,为什么你的train_y 的形状是(312,18000)?应该是 (train_sample_length, num_classes). 在你的情况下我可以看到 num_features=3num_classes=5
  • @Anakin,因为我总共有 312 条不同的记录。我正在转置信号,以便每个信号序列对应于一行。因此,在每一行中,有 18006 列(信号长度 + 一个热编码标签)。我正在做转置操作,因为我不想标记信号的每一毫秒,最好转置它并只标记一次。
  • 得到了 312 部分。也许您应该考虑整个 5616000 行并将数据打乱并拆分为训练和验证
  • @Anakin,如果我要以 5616000 行的形式对其进行洗牌,那么所有的信号结构都会被破坏。
  • 也许我把你的问题弄错了。好的,告诉我:对于预测,您要输入一个 3d 向量 [ecg gsr temp] 并预测 emotion 吗?

标签: python tensorflow keras


【解决方案1】:

定义conv1D层有错误。从代码中,很明显您已经定义了 2 个过滤器和大小为 700 的内核,但是通常使用大约 3 个过滤器并且没有使用大量过滤器。尝试使用它并在没有验证拆分的情况下进行训练。

`model = Sequential() 
 model.add(Conv1D(64, 3, activation='relu', input_shape=(18000, 3))) 
 model.add(Conv1D(64, 3, activation='relu')) 
 model.add(MaxPooling1D(3)) 
 model.add(Conv1D(128, 3, activation='relu')) 
 model.add(Conv1D(128, 3, activation='relu')) 
 model.add(GlobalAveragePooling1D()) 
 model.add(Dropout(0.5)) 
 model.add(Dense(6, activation='softmax')) `

【讨论】:

  • 这更像是一个评论而不是一个答案。
  • 如果我删除 GlobalAvaragePoolling1D(),它会产生一个错误。 Error when checking target: expected dense_9 to have 3 dimensions, but got array with shape (312, 6)
猜你喜欢
  • 1970-01-01
  • 2020-10-28
  • 2014-06-20
  • 2019-05-29
  • 1970-01-01
  • 1970-01-01
  • 2018-08-04
  • 2017-06-12
  • 2017-08-23
相关资源
最近更新 更多