如何使 Keras 神经网络在 Iris 数据上的表现优于 Logistic 回归
Posted
技术标签:
【中文标题】如何使 Keras 神经网络在 Iris 数据上的表现优于 Logistic 回归【英文标题】:How to make Keras Neural Net outperforming Logistic Regression on Iris data 【发布时间】:2016-08-24 11:44:34 【问题描述】:我在 IRIS 数据上将 Keras 神经网络与简单的 Logistic Regression from Scikit-learn 进行比较。正如this post 所建议的那样,我希望 Keras-NN 的性能会更好。
但是为什么通过模仿那里的代码,Keras-NN 的结果低于 逻辑回归?
import seaborn as sns
import numpy as np
from sklearn.cross_validation import train_test_split
from sklearn.linear_model import LogisticRegressionCV
from keras.models import Sequential
from keras.layers.core import Dense, Activation
from keras.utils import np_utils
# Prepare data
iris = sns.load_dataset("iris")
X = iris.values[:, 0:4]
y = iris.values[:, 4]
# Make test and train set
train_X, test_X, train_y, test_y = train_test_split(X, y, train_size=0.5, random_state=0)
################################
# Evaluate Logistic Regression
################################
lr = LogisticRegressionCV()
lr.fit(train_X, train_y)
pred_y = lr.predict(test_X)
print("Test fraction correct (LR-Accuracy) = :.2f".format(lr.score(test_X, test_y)))
################################
# Evaluate Keras Neural Network
################################
# Make ONE-HOT
def one_hot_encode_object_array(arr):
'''One hot encode a numpy array of objects (e.g. strings)'''
uniques, ids = np.unique(arr, return_inverse=True)
return np_utils.to_categorical(ids, len(uniques))
train_y_ohe = one_hot_encode_object_array(train_y)
test_y_ohe = one_hot_encode_object_array(test_y)
model = Sequential()
model.add(Dense(16, input_shape=(4,)))
model.add(Activation('sigmoid'))
model.add(Dense(3))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer='adam')
# Actual modelling
model.fit(train_X, train_y_ohe, verbose=0, batch_size=1)
score, accuracy = model.evaluate(test_X, test_y_ohe, batch_size=16, verbose=0)
print("Test fraction correct (NN-Score) = :.2f".format(score))
print("Test fraction correct (NN-Accuracy) = :.2f".format(accuracy))
我正在使用这个版本的 Keras
In [2]: keras.__version__
Out[2]: '1.0.1'
结果显示:
Test fraction correct (LR-Accuracy) = 0.83
Test fraction correct (NN-Score) = 0.75
Test fraction correct (NN-Accuracy) = 0.60
根据that post,Keras 的准确率应该是 0.99。出了什么问题?
【问题讨论】:
【参考方案1】:您的神经网络非常简单。尝试通过向其中添加更多神经元和层来创建深度神经网络。此外,扩展功能也很重要。尝试glorot_uniform
初始化程序。最后但同样重要的是,增加 epoch 并查看 loss 是否随着每个 epoch 减少。
所以你去:
model = Sequential()
model.add(Dense(input_dim=4, output_dim=512, init='glorot_uniform'))
model.add(PReLU(input_shape=(512,)))
model.add(BatchNormalization((512,)))
model.add(Dropout(0.5))
model.add(Dense(input_dim=512, output_dim=512, init='glorot_uniform'))
model.add(PReLU(input_shape=(512,)))
model.add(BatchNormalization((512,)))
model.add(Dropout(0.5))
model.add(Dense(input_dim=512, output_dim=512, init='glorot_uniform'))
model.add(PReLU(input_shape=(512,)))
model.add(BatchNormalization((512,)))
model.add(Dropout(0.5))
model.add(Dense(input_dim=512, output_dim=512, init='glorot_uniform'))
model.add(PReLU(input_shape=(512,)))
model.add(BatchNormalization((512,)))
model.add(Dropout(0.5))
model.add(Dense(input_dim=512, output_dim=512, init='glorot_uniform'))
model.add(PReLU(input_shape=(512,)))
model.add(BatchNormalization((512,)))
model.add(Dropout(0.5))
model.add(Dense(input_dim=512, output_dim=3, init='glorot_uniform'))
model.add(Activation('softmax'))
在第 120 个 epoch 达到 0.97 左右
【讨论】:
【参考方案2】:本月(2016 年 4 月)刚刚发布的 Keras 版本 0 中的默认 epoch 数从 100 减少到 Keras 版本 1 中的 10。试试:
model.fit(train_X, train_y_ohe, verbose=0, batch_size=1, nb_epoch=100)
【讨论】:
以上是关于如何使 Keras 神经网络在 Iris 数据上的表现优于 Logistic 回归的主要内容,如果未能解决你的问题,请参考以下文章
用tensorflow搭建简单神经网络测试iris 数据集和MNIST 数据集