网格搜索交叉验证:神经元数量

4

我正在尝试自学如何在基本的多层神经网络中使用网格搜索来确定神经元数量。我使用Python的GridSearchCV和KerasClasifier以及Keras。下面的代码在其他数据集上运行良好,但我无法使其在鸢尾花数据集上正常工作,并且我找不到原因,我在这里缺少了什么。我得到的结果是:

最佳结果: 0.000000,使用{'n_neurons': 3} 与 {'n_neurons': 3} 一起使用:0.000000(0.000000) 与 {'n_neurons': 5} 一起使用:0.000000(0.000000)

from pandas import read_csv

import numpy
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import StandardScaler

from keras.wrappers.scikit_learn import KerasClassifier
from keras.models import Sequential
from keras.layers import Dense
from keras.utils import np_utils
from sklearn.model_selection import GridSearchCV

dataframe=read_csv("iris.csv", header=None)
dataset=dataframe.values
X=dataset[:,0:4].astype(float)
Y=dataset[:,4]

seed=7
numpy.random.seed(seed)

#encode class values as integers
encoder = LabelEncoder()
encoder.fit(Y)
encoded_Y = encoder.transform(Y)

#one-hot encoding
dummy_y = np_utils.to_categorical(encoded_Y)

#scale the data
scaler = StandardScaler()
X = scaler.fit_transform(X)

def create_model(n_neurons=1):
    #create model
    model = Sequential()
    model.add(Dense(n_neurons, input_dim=X.shape[1], activation='relu')) # hidden layer
    model.add(Dense(3, activation='softmax')) # output layer
    # Compile model
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    return model

model = KerasClassifier(build_fn=create_model, epochs=100, batch_size=10, initial_epoch=0, verbose=0)
# define the grid search parameters
neurons=[3, 5]

#this does 3-fold classification. One can change k. 
param_grid = dict(n_neurons=neurons)
grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1)
grid_result = grid.fit(X, dummy_y)
# summarize results
print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))
means = grid_result.cv_results_['mean_test_score']
stds = grid_result.cv_results_['std_test_score']
params = grid_result.cv_results_['params']
for mean, stdev, param in zip(means, stds, params):
    print("%f (%f) with: %r" % (mean, stdev, param))

为了举例说明和提高计算效率,我只搜索两个值。非常抱歉我提出了这样一个简单的问题。我是Python的新手,顺便说一下,我从R转到Python,因为我意识到深度学习社区正在使用Python。


1
没有仔细看你的代码,不过针对DL使用GridSearch,真的吗?在我看来这是个坏主意。你放入的神经元越多(直到遇到瓶颈),理论上模型就会变得更好,但这并不意味着你的架构也是好的。 - enterML
我完全理解你。我已经使用8个神经元的模型运行,并获得了很好的准确性。由于我刚开始学Python,我只想尽可能地进行一些人工分析。 - ARAT
(1)我不同意第一个评论。对于训练损失(和良好的拟合参数)来说可能是正确的,但使用交叉验证是可行的方法(更简单的方案可能更好)!(2)代码无法复现,至少缺少数据。(3)还有哪些数据集可以使用?你是如何推断它们有效的?这个数据集与其他数据集有什么区别?鸢尾花数据集实际上是最简单的数据集之一,完美得分是可能的。(4)确保检查评分是否按照预期进行(评分与损失比较;也许使用一些明确的评分函数)。(5)检查最佳结果的预测。 - sascha
1个回答

4
哈哈,这可能是我在Stack Overflow上经历过的最有趣的事情 :) 请看:
grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1, cv=5)

您应该看到不同的行为。您的模型之所以得分完美(以cross_entropy具有0等于最佳模型),是因为您没有对数据进行混洗,而因为Iris由三个平衡类组成,每个喂食都有一个单一的类似目标。

[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 (first fold ends here) 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 (second fold ends here)2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2]

这些问题每个模型都很容易解决,这就是为什么你找到了完美的匹配。在此之前,尝试对数据进行混洗,这应该会产生预期的结果。

1
哦,哈哈,是的,你说得对!天啊,我现在讨厌自己。你绝对是对的。我错过了那个点,完全只关注于方法本身。我想我被默认的model.fit洗牌搞混了。谢谢你!我很抱歉! - ARAT
1
你搞定了,伙计! - ARAT

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接