Nic*_*row 12 python machine-learning neural-network scikit-learn keras
如果耐心达到我设定的数量,我希望分类器运行得更快并提前停止.在下面的代码中,它进行了10次迭代拟合模型.
import numpy
import pandas
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.wrappers.scikit_learn import KerasClassifier
from keras.callbacks import EarlyStopping, ModelCheckpoint
from keras.constraints import maxnorm
from keras.optimizers import SGD
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import StratifiedKFold
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)
# load dataset
dataframe = pandas.read_csv("sonar.csv", header=None)
dataset = dataframe.values
# split into input (X) and output (Y) variables
X = dataset[:,0:60].astype(float)
Y = dataset[:,60]
# encode class values as integers
encoder = LabelEncoder()
encoder.fit(Y)
encoded_Y = encoder.transform(Y)
calls=[EarlyStopping(monitor='acc', patience=10), ModelCheckpoint('C:/Users/Nick/Data Science/model', monitor='acc', save_best_only=True, mode='auto', period=1)]
def create_baseline():
# create model
model = Sequential()
model.add(Dropout(0.2, input_shape=(33,)))
model.add(Dense(33, init='normal', activation='relu', W_constraint=maxnorm(3)))
model.add(Dense(16, init='normal', activation='relu', W_constraint=maxnorm(3)))
model.add(Dense(122, init='normal', activation='softmax'))
# Compile model
sgd = SGD(lr=0.1, momentum=0.8, decay=0.0, nesterov=False)
model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
return model
numpy.random.seed(seed)
estimators = []
estimators.append(('standardize', StandardScaler()))
estimators.append(('mlp', KerasClassifier(build_fn=create_baseline, nb_epoch=300, batch_size=16, verbose=0, callbacks=calls)))
pipeline = Pipeline(estimators)
kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=seed)
results = cross_val_score(pipeline, X, encoded_Y, cv=kfold)
print("Baseline: %.2f%% (%.2f%%)" % (results.mean()*100, results.std()*100))
Run Code Online (Sandbox Code Playgroud)
这是由此产生的错误 -
RuntimeError: Cannot clone object <keras.wrappers.scikit_learn.KerasClassifier object at 0x000000001D691438>, as the constructor does not seem to set parameter callbacks
Run Code Online (Sandbox Code Playgroud)
我改变了以下的cross_val_score-
numpy.random.seed(seed)
estimators = []
estimators.append(('standardize', StandardScaler()))
estimators.append(('mlp', KerasClassifier(build_fn=create_baseline, nb_epoch=300, batch_size=16, verbose=0, callbacks=calls)))
pipeline = Pipeline(estimators)
kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=seed)
results = cross_val_score(pipeline, X, encoded_Y, cv=kfold, fit_params={'callbacks':calls})
print("Baseline: %.2f%% (%.2f%%)" % (results.mean()*100, results.std()*100))
Run Code Online (Sandbox Code Playgroud)
现在我得到这个错误 -
ValueError: need more than 1 value to unpack
Run Code Online (Sandbox Code Playgroud)
这段代码来自这里.到目前为止,代码是迄今为止我使用过的最准确的代码.问题是model.fit()
代码中没有任何定义.它也需要永远适合.该fit()
操作发生在results = cross_val_score(...)
,而且也没有参数扔回调在那里.
我该怎么做呢?另外,如何运行在测试集上训练的模型?
我需要能够保存训练好的模型供以后使用......
从此处读取,它是KerasClassifier的源代码,您可以向其传递fit参数,应使用它们。我没有您的数据集,所以无法测试它,但是您可以告诉我是否可行,否则我将尝试调整解决方案。更改此行:
estimators.append(('mlp', KerasClassifier(build_fn=create_baseline, nb_epoch=300, batch_size=16, verbose=0, callbacks=[...your_callbacks...])))
Run Code Online (Sandbox Code Playgroud)
发生了什么的小的解释:KerasClassifier正在采取所有的候选条件论点fit
,predict
,score
并用它们因此,当每一个方法被调用。他们制作了一个函数,该函数可以过滤应该传递给可以在管道中调用的上述每个函数的参数。我想有几个fit
和predict
调用内部StratifiedKFold
的步骤在不同的拆分每次火车。
之所以需要永久拟合才能拟合10次,是因为您一次要求一次拟合就执行了300个纪元。因此,KFold在不同的折叠位置重复此步骤:
fit
具有指定的所有参数KerasClassifier
(300个纪元,批量大小= 16)。它针对您的9/10数据进行训练,并使用1/10作为验证。编辑:
好的,所以我花时间下载数据集并尝试您的代码...首先,您需要更正网络中的“少量”内容:
您的输入具有60个功能。您可以在数据准备中清楚地显示它:
X = dataset[:,:60].astype(float)
Run Code Online (Sandbox Code Playgroud)
那你为什么要这样:
model.add(Dropout(0.2, input_shape=(33,)))
Run Code Online (Sandbox Code Playgroud)
请更改为:
model.add(Dropout(0.2, input_shape=(60,)))
Run Code Online (Sandbox Code Playgroud)关于您的目标/标签。您已将目标从原始代码(binary_crossentropy
)更改为categorical_crossentropy
。但是您没有更改Y数组。因此,您可以在数据准备中执行以下操作:
from keras.utils.np_utils import to_categorical
encoded_Y = to_categorical(encoder.transform(Y))
Run Code Online (Sandbox Code Playgroud)
或将目标更改为binary_crossentropy
。
现在网络的输出大小:在最后一个密集层上为122?您的数据集显然具有2个类别,那么为什么要输出122个类别?它不会达到目标。请把最后一层改回:
model.add(Dense(2, init='normal', activation='softmax'))
Run Code Online (Sandbox Code Playgroud)
如果您选择使用categorical_crossentropy
,或
model.add(Dense(1, init='normal', activation='sigmoid'))
Run Code Online (Sandbox Code Playgroud)
如果你回到binary_crossentropy
。
因此,既然您的网络可以编译,我就可以开始麻烦了。
这是你的解决方案
所以现在我可以得到真正的错误消息了。事实证明,当您fit_params=whatever
输入cross_val_score()
函数时,就是将这些参数输入到管道中。为了知道要将这些参数发送到管道的哪个部分,必须像这样指定它:
fit_params={'mlp__callbacks':calls}
Run Code Online (Sandbox Code Playgroud)
您的错误是说该流程无法'callbacks'.split('__', 1)
分解为2个值。它实际上是在寻找将其应用到管道的步骤的名称。
它现在应该可以工作了:)
results = cross_val_score(pipeline, X, encoded_Y, cv=kfold, fit_params={'mlp__callbacks':calls})
Run Code Online (Sandbox Code Playgroud)
但是,您应该知道这里发生了什么...交叉验证实际上调用该create_baseline()
函数从头开始创建模型10次,然后在数据集的不同部分上对其进行10次训练。因此,它没有像您所说的那样做时代,而是做10次300个时代。使用此工具还发生了什么:由于模型总是不同的,这意味着该fit()
方法在不同的模型上应用了10次,因此,回调函数也被应用了10次,并且通过ModelCheckpoint()
覆盖保存的文件和您仅使用上次运行的最佳模型找到自己。
这是您使用的工具的内在因素,我看不出有任何解决方法。这是由于使用了不同的通用工具而导致的,这些通用工具并未特别考虑与所有可能的配置一起使用。
归档时间: |
|
查看次数: |
4267 次 |
最近记录: |