Keras MLP 分类器不学习

Posted

技术标签:

【中文标题】Keras MLP 分类器不学习【英文标题】:Keras MLP classifier not learning 【发布时间】:2019-10-24 16:49:12 【问题描述】:

我有这样的数据

有 29 列,其中我必须预测 winPlacePerc(数据帧的极端端)介于 1(高 perc ) 到 0(低 perc)

29 列中 25数字 数据 3 是 ID(object) 1 是 分类

我删除了所有 Id 列(因为它们都是唯一的)并将 categorical(matchType) 数据编码为一个热编码

做完这一切后,我剩下 41 列(在一个热门之后)

这就是我创建数据的方式

X = df.drop(columns=['winPlacePerc'])
#creating a dataframe with only the target column
y = df[['winPlacePerc']]

现在我的 X 有 40 列,这是我的标签数据的样子

> y.head()

winPlacePerc
0   0.4444
1   0.6400
2   0.7755
3   0.1667
4   0.1875

我也碰巧有非常大量的数据,比如 400k 数据,所以为了测试目的,我正在训练其中的一小部分,使用 sckit 进行训练

X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.997, random_state=32)

它提供了近 13k 的训练数据

对于模型,我使用的是 Keras 顺序模型

from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dense, Dropout, Activation
from keras.layers.normalization import BatchNormalization
from keras import optimizers

n_cols = X_train.shape[1]

model = Sequential()

model.add(Dense(40, activation='relu', input_shape=(n_cols,)))
model.add(Dense(1, activation='sigmoid'))

model.compile(loss='mean_squared_error',
              optimizer='Adam',
              metrics=['accuracy'])

model.fit(X_train, y_train,
          epochs=50,
          validation_split=0.2,
          batch_size=20)

由于我的 y-label 数据介于 0 和 1 之间,我使用 sigmoid 层作为我的 输出层

这是训练和验证损失和准确度图

我还尝试使用 step 函数和 binary cross entropy 损失函数将标签转换为 binary

之后 y-label 数据看起来像

> y.head()

winPlacePerc
0   0
1   1
2   1
3   0
4   0

改变损失函数

model.compile(loss='binary_crossentropy',
              optimizer='Adam',
              metrics=['accuracy'])

这种方法比以前更糟糕

正如您所见,它在某个时期后没有学习,即使我获取所有数据而不是其中的一部分,也会发生这种情况

在这不起作用之后,我还使用了 dropout 并尝试添加更多层,但这里没有任何效果

现在我的问题是,我在这里做错了什么是错误的层还是在数据中我该如何改进?

【问题讨论】:

我相信你的损失函数可能是问题所在。以均方误差损失为例。 感谢您指出这一点,实际上我使用阶跃函数将我的整个标签数据转换为二进制 0 和 1,因为我使用的是二进制交叉熵,现在我将尝试均方损失原始标签数据 尝试添加更多层,将数值列标准化为-1、1,尝试使用学习率。 【参考方案1】:
from sklearn.preprocessing import StandardScaler

n_cols = X_train.shape[1]
ss = StandardScaler()
X_train = ss.fit_transform(X_train)

model = Sequential()    
model.add(Dense(128, activation='relu', input_shape=(n_cols,)))
model.add(Dense(64, activation='relu'))
model.add(Dense(16, activation='relu'))
model.add(Dense(1))

model.compile(loss='mean_squared_error',
              optimizer='Adam',
              metrics=['mean_squared_error'])

model.fit(X_train, y_train,
          epochs=50,
          validation_split=0.2,
          batch_size=20)
规范化数据 为您的网络增加更多深度 使最后一层线性

准确度不是回归的好指标。我们来看一个例子

predictions: [0.9999999, 2.0000001, 3.000001]
ground Truth: [1, 2, 3]

Accuracy = No:of Correct / Total => 0 /3 = 0

准确度为0,但预测与基本事实非常接近。另一方面,MSE 将非常低,表明预测与基本事实的偏差非常小。

【讨论】:

第二次添加 MSE(作为一个指标)虽然没有错,但实际上是多余的,并没有提供任何东西。解释一下为什么准确性在这里毫无意义会很有用。【参考方案2】:

澄清一下 - 这是一个回归问题,因此使用准确度实际上没有意义,因为您永远无法预测 0.23124 的确切值。

首先,您肯定希望在将值传递到网络之前对其进行规范化(不是热编码的值)。尝试使用StandardScaler 作为开始。

其次,我建议更改输出层中的激活函数 - 尝试使用 linear 并作为损失 mean_squared_error 应该没问题。

为了验证您的模型 “准确性” 将预测值与实际值一起绘制 - 这应该让您有机会直观地验证结果。不过,话虽如此,你的损失看起来已经相当不错了。

检查this post,应该可以让您很好地掌握什么(激活和损失函数)以及何时使用。

【讨论】:

以上是关于Keras MLP 分类器不学习的主要内容,如果未能解决你的问题,请参考以下文章

Halcon学习笔记-分类器mlp的解读

小白学习keras教程一基于波士顿住房数据集训练简单的MLP回归模型

使用多层感知器(MLP)对图像及其性能进行分类

基于Halcon的MLP(多层感知神经网络)分类器分类操作实例

MLP 分类器:“ValueError:未知标签类型”

MLP,GCN,GAT,GraphSAGE, GAE, Pooling,DiffPool