Iris Data 上的 MLP 不起作用,但在 MNIST 上运行良好 - Keras

数据挖掘 Python 神经网络 喀拉斯
2022-02-15 09:43:55

所以我有点困惑。我刚刚开始使用 Python 的 Keras 框架(顺便说一句,这太棒了!)。

然而,仅仅尝试一些简单的神经网络测试让我有点困惑。我最初尝试对 Iris 数据进行分类,因为它是一个小型、快速且简单的数据集。然而,当我为它构建一个神经网络时(4 个输入维度,8 个节点隐藏层,3 个节点输出层用于 3 个类的二进制分类)。然而,这根本没有产生任何预测能力(训练集中有 100 个样本,测试集中有 50 个样本。两者都被打乱,以便在每个样本中包含良好的类分布)。

现在我认为我做错了什么,但我想我会在 MNIST 数据集上对网络进行快速测试以防万一。所以我使用了基本完全相同的网络(除了将输入维度更改为 784、隐藏节点更改为 30、输出节点更改为 10 以用于二进制编码的 0-9 输出)。这非常有效!准确率 97%,损失 5%。

所以现在我不确定为什么 Iris 数据集没有发挥作用,有人有任何线索吗?我试过改变隐藏层节点的数量,也标准化了 X 输入。

这是我通过训练后的 Iris 模型手动运行一些测试集时产生的输出。正如你所看到的,它基本上产生了一个统一的随机猜测。

Target: [ 1.  0.  0.]  | Predicted: [[ 0.44635904  0.43874186  0.45729554]]
Target: [ 0.  0.  1.]  | Predicted: [[ 0.44618103  0.43869928  0.45735642]]
Target: [ 0.  1.  0.]  | Predicted: [[ 0.44612524  0.43863046  0.45729461]]
Target: [ 0.  0.  1.]  | Predicted: [[ 0.44617626  0.43870446  0.45736298]]
Target: [ 0.  0.  1.]  | Predicted: [[ 0.44613886  0.43865535  0.45731983]]

这是我的 Iris MLP 的完整代码(MNIST 基本相同)

import numpy as np
import random
from keras.models import Sequential
from keras.layers import Dense, Activation
from sklearn.datasets import load_iris
from sklearn import preprocessing

# Model Layers Defnition
# Input layer (12 neurons), Output layer (1 neuron)
model = Sequential()
model.add(Dense(8, input_dim=4, init='uniform', activation='sigmoid'))
model.add(Dense(3, init='uniform', activation='sigmoid'))


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

# Iris has 150 samples, each sample has 4 dimensions
iris = load_iris()
iris_xy = zip(iris.data, iris.target)
random.shuffle(iris_xy) # Iris data is sequential in it's labels
iris_x, iris_y = zip(*iris_xy)
iris_x = preprocessing.normalize(np.array(iris_x))
iris_y = np.array(iris_y)

# Encode decimal numbers to array
iris_y_enc = np.zeros(shape=(len(iris_y),3))
for i, y in enumerate(iris_y):
    iris_y_enc[i][y] = 1

train_data = np.array(iris_x[:100]) # 100 samples for training
test_data  = np.array(iris_x[100:]) # 50 samples for testing
train_targets = np.array(iris_y_enc[:100])
test_targets  = np.array(iris_y_enc[100:])

model.fit(train_data, train_targets, nb_epoch=10)

#score = model.evaluate(test_data, test_targets)

for test in zip(test_data, test_targets):
    prediction = model.predict(np.array(test[0:1]))
    print "Target:", test[1], " | Predicted:", prediction
1个回答

默认情况下sklearn.preprocessing.normalize标准化样本,而不是特征。将 sklearn.preprocessing.normalize 替换为sklearn.preprocessing.scale这将使每个特征居中并缩放(到单位方差)。

还要给它超过 10 个 epoch。以下是 5000 个 epoch 的学习曲线(log loss):

学习曲线

这应该以大约 96% 的准确度结束。