为什么我在Iris数据集上的Keras模型表现如此差?

我正在学习这个Keras教程,发现了有趣的事情。

我使用sklearn训练了我的逻辑回归模型,表现相当不错:

import seaborn as snsimport numpy as npfrom sklearn.cross_validation import train_test_splitfrom sklearn.linear_model import LogisticRegressionCVfrom keras.models import Sequentialfrom keras.layers.core import Dense, Activationfrom keras.utils import np_utils# 从seaborn加载iris数据集。iris = sns.load_dataset("iris")# 使用前四个变量来预测物种。X, y = iris.values[:, 0:4], iris.values[:, 4]# 将自变量和因变量分成两半# 用于交叉验证train_X, test_X, train_y, test_y = train_test_split(X, y, train_size=0.5, random_state=0)# 训练一个scikit-learn逻辑回归模型lr = LogisticRegressionCV()lr.fit(train_X, train_y)# 测试模型。在测试数据上打印准确率pred_y = lr.predict(test_X)print("准确率是 {:.2f}".format(lr.score(test_X, test_y))) # 准确率是 0.83

83%已经相当不错了,但使用深度学习我们应该能做得更好。我训练了一个Keras模型…

# 定义一个对数组中的变量进行独热编码的函数def one_hot_encode_object_array(arr):    '''对numpy对象数组(例如字符串)进行独热编码'''    uniques, ids = np.unique(arr, return_inverse=True)    return np_utils.to_categorical(ids, len(uniques))# 对训练和测试的y值进行独热编码train_y_ohe = one_hot_encode_object_array(train_y)test_y_ohe = one_hot_encode_object_array(test_y)# 构建keras模型model = Sequential()# 输入层有4个特征(四种花的测量值)# 16个隐藏单元model.add(Dense(16, input_shape=(4,)))model.add(Activation('sigmoid'))# 输出层有3个类别(对应于3个物种)model.add(Dense(3))model.add(Activation('softmax'))model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])# 训练keras模型model.fit(train_X, train_y_ohe, verbose=0, batch_size=1)# 测试模型。在测试数据上打印准确率loss, accuracy = model.evaluate(test_X, test_y_ohe, verbose=0)print("准确率是 {:.2f}".format(accuracy)) # 准确率是 0.60????

当我训练Keras模型时,我的准确率实际上比我的逻辑回归模型还要差。

虽然这对某些数据来说是有道理的,但对于像iris这样极其线性可分的数据,Keras顺序模型应该很容易学习。我尝试增加隐藏层的数量到32、64和128,但准确率没有改善。

下图显示了Iris数据(具体来说是自变量)作为物种(因变量)的函数:

Iris数据

为什么我的模型表现如此差?


回答:

我已经替换了独热编码,直接使用了keras的sparse_categorical_crossentropy

尝试的显而易见的方法是:增加学习的epoch数量(默认10,我们试试100)。

代码

from sklearn.datasets import load_irisfrom sklearn.cross_validation import train_test_splitfrom sklearn.linear_model import LogisticRegressionCVimport numpy as npfrom keras.models import Sequentialfrom keras.layers import Dense, Activation# 从seaborn加载iris数据集。iris = load_iris()# 使用前四个变量来预测物种。X, y = iris.data[:, :4], iris.target# 将自变量和因变量分成两半# 用于交叉验证train_X, test_X, train_y, test_y = train_test_split(X, y, train_size=0.5, random_state=0)# 训练一个scikit-learn逻辑回归模型lr = LogisticRegressionCV()lr.fit(train_X, train_y)# 测试模型。在测试数据上打印准确率pred_y = lr.predict(test_X)print("准确率是 {:.2f}".format(lr.score(test_X, test_y))) # 准确率是 0.83# 构建keras模型model = Sequential()# 输入层有4个特征(四种花的测量值)# 16个隐藏单元model.add(Dense(16, input_shape=(4,)))model.add(Activation('sigmoid'))# 输出层有3个类别(对应于3个物种)model.add(Dense(3))model.add(Activation('softmax'))model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])# 训练keras模型model.fit(train_X, train_y, verbose=1, batch_size=1, nb_epoch=100)# 测试模型。在测试数据上打印准确率loss, accuracy = model.evaluate(test_X, test_y, verbose=0)print("准确率是 {:.2f}".format(accuracy)) 

输出

准确率是 0.83准确率是 0.99

Related Posts

L1-L2正则化的不同系数

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

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

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

f1_score metric in lightgbm

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

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

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

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

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

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

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

发表回复

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