Scikit-learn GridSearchCV - 为啥我在执行 grid.fit() 时会收到数据类型错误?
Posted
技术标签:
【中文标题】Scikit-learn GridSearchCV - 为啥我在执行 grid.fit() 时会收到数据类型错误?【英文标题】:Scikit-learn GridSearchCV - Why am I receiving a data type error when I execute grid.fit()?Scikit-learn GridSearchCV - 为什么我在执行 grid.fit() 时会收到数据类型错误? 【发布时间】:2020-10-17 15:09:38 【问题描述】:我一直在用 python 进行机器学习项目。在使基本的神经网络运行良好后,我尝试使用来自sklearn
的GridSearchCV
函数来设置网格搜索以优化参数。 grid.fit(X,Y)
函数抛出此错误:TypeError: only size-1 arrays can be converted to Python scalars
。我的解释是 fit 函数不喜欢我给它的X
和Y
的格式。这让我感到困惑,因为没有网格搜索,网络运行良好,而且我根本没有弄乱网络或数据。谁能解释这里发生了什么以及我该如何解决?
这段代码创建了网络和网格搜索:
#Creating the neural network
def create_model():
model=Sequential()
model.add(Dense(512, activation='relu',input_shape=(2606,)))
model.add(Dense(256, activation='relu'))
model.add(Dense(128, activation='relu'))
model.add(Dense(64, activation='relu'))
model.add(Dense(32, activation='relu'))
model.add(Dense(16, activation='relu'))
model.add(Dense(1, activation='relu'))
opt=optimizers.Adam(lr=learn_rate)
model.compile(optimizer=opt, loss='mean_squared_error', metrics=['accuracy'])
#I commented this out because I believe it is delegated to the grid.fit() fn later on.
#model.fit(X_train, Y_train, batch_size=30, epochs=6000, verbose=1)
return model
#Now setting up the grid search
model=KerasClassifier(build_fn=create_model())
learn_rate=np.arange(.00001,.001,.00002).tolist()
batch_size=np.arange(10,2606,2).tolist()
epochs=np.arange(1000,10000,100).tolist()
param_grid=dict(learn_rate=learn_rate, batch_size=batch_size, epochs=epochs)
grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1, cv=3)
grid_results=grid.fit(X_train,Y_train) #This is the line referenced in the error message.
print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))
任何建议将不胜感激!
编辑:
X_train
数据的形状为 (167,2606)
。 167 个元素中的每一个都是一个长度为 2606 的数组。这就是为什么网络的input_shape
是(2606,)
。 Y_train
的形状为 (167,)
。
【问题讨论】:
X_train
和 Y_train
输入的形状是什么?您收到的错误是因为在 fit()
的引擎盖下,在某些时候,它需要一个标量值,而不是接收一个数组。
我将形状添加为问题的编辑。我想知道它在哪里期望但没有收到标量。我认为问题在于fit()
只是接收数据。正如你所建议的,我没有考虑在执行过程中更进一步的地方。
【参考方案1】:
所以,问题在于GridSearchCV
为每个组合创建了一个带有新参数的新模型。您正在传递一个已经创建的模型和一个参数列表。我相信这是数组与标量误差的来源。下面,我修改了你的代码(带有一些垃圾样本数据),它将运行。
需要注意的主要更改是我更改了您的create_model
的签名以接受您传递给GridSearch 的参数值。我还删除了您将 KerasClassifier
实例分配给变量 model
的分配,而是将该调用作为估计器放在 GridSearchCV
中。
import numpy as np
from tensorflow.keras.wrappers.scikit_learn import KerasClassifier
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras import optimizers
from sklearn.model_selection import GridSearchCV
#Creating the neural network
def create_model(learn_rate, batch_size, epochs):
model=Sequential()
model.add(Dense(512, activation='relu',input_shape=(2606,)))
model.add(Dense(256, activation='relu'))
model.add(Dense(128, activation='relu'))
model.add(Dense(64, activation='relu'))
model.add(Dense(32, activation='relu'))
model.add(Dense(16, activation='relu'))
model.add(Dense(1, activation='relu'))
opt=optimizers.Adam(lr=learn_rate)
model.compile(optimizer=opt, loss='mean_squared_error', metrics=['accuracy'])
#I commented this out because I believe it is delegated to the grid.fit() fn later on.
#model.fit(X_train, Y_train, batch_size=30, epochs=6000, verbose=1)
return model
#Now setting up the grid search
X_train = np.empty((167,2606), dtype=float, order='C')
Y_train = np.empty((167,), dtype=float, order='C')
learn_rate=np.arange(.00001,.001,.00002).tolist()
batch_size=np.arange(10,2606,2).tolist()
epochs=np.arange(1000,10000,100).tolist()
param_grid=dict(learn_rate=learn_rate, batch_size=batch_size, epochs=epochs)
grid = GridSearchCV(estimator=KerasClassifier(build_fn=create_model),
param_grid=param_grid, n_jobs=-1, cv=3)
grid_results=grid.fit(X_train,Y_train) #This is the line referenced in the error message.
print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))
【讨论】:
谢谢你!我确实错过了我忘记为create_model()
提供参数来接受的事实。它现在似乎已经启动并运行。我预计它需要很长时间,所以我也会在它完成时尝试提供更新。再次感谢!
几周后,我已经能够让 GridSearch 完全运行。最大的教训是,如果您对参数网格过于雄心勃勃,可能需要非常非常长的时间。我使用的是 Google Colab GPU,但前 10 次左右的尝试过于雄心勃勃,无法在合理的时间内执行。
这当然是值得学习的宝贵一课!谢谢你的更新。我很高兴你能够让它运行起来。不要忘记将答案标记为已接受,以便将来的用户知道它是可靠的。
我之前试图弄清楚如何做到这一点(菜鸟,你能告诉我吗?)我刚刚找到了按钮!谢谢!以上是关于Scikit-learn GridSearchCV - 为啥我在执行 grid.fit() 时会收到数据类型错误?的主要内容,如果未能解决你的问题,请参考以下文章
Scikit-learn 中的 GridSearchCV 输出问题
Scikit-Learn:GridSearchCV 的自定义损失函数
Scikit-learn 多输出分类器使用:GridSearchCV、Pipeline、OneVsRestClassifier、SGDClassifier
scikit-learn GridSearchCV 弃用警告