Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python keras/scikit学习:使用fit_生成器()进行交叉验证_Python_Scikit Learn_Keras_Cross Validation_Hyperparameters - Fatal编程技术网

Python keras/scikit学习:使用fit_生成器()进行交叉验证

Python keras/scikit学习:使用fit_生成器()进行交叉验证,python,scikit-learn,keras,cross-validation,hyperparameters,Python,Scikit Learn,Keras,Cross Validation,Hyperparameters,是否可以与fit\u generator()方法一起使用?还是使用另一种方法来批量生产培训?我使用的是SciPy的稀疏矩阵,在输入到Keras之前必须将其转换为NumPy数组,但由于内存消耗高,我无法同时转换它们。以下是我的生成批次的函数: def batch_generator(X, y, batch_size): n_splits = len(X) // (batch_size - 1) X = np.array_split(X, n_splits) y = np.a

是否可以与
fit\u generator()
方法一起使用?还是使用另一种方法来批量生产培训?我使用的是SciPy的稀疏矩阵,在输入到Keras之前必须将其转换为NumPy数组,但由于内存消耗高,我无法同时转换它们。以下是我的生成批次的函数:

def batch_generator(X, y, batch_size):
    n_splits = len(X) // (batch_size - 1)
    X = np.array_split(X, n_splits)
    y = np.array_split(y, n_splits)

    while True:
        for i in range(len(X)):
            X_batch = []
            y_batch = []
            for ii in range(len(X[i])):
                X_batch.append(X[i][ii].toarray().astype(np.int8)) # conversion sparse matrix -> np.array
                y_batch.append(y[i][ii])
            yield (np.array(X_batch), np.array(y_batch))
以及交叉验证的示例代码:

from sklearn.model_selection import StratifiedKFold, GridSearchCV
from sklearn import datasets

from keras.models import Sequential
from keras.layers import Activation, Dense
from keras.wrappers.scikit_learn import KerasClassifier

import numpy as np


def build_model(n_hidden=32):
    model = Sequential([
        Dense(n_hidden, input_dim=4),
        Activation("relu"),
        Dense(n_hidden),
        Activation("relu"),
        Dense(3),
        Activation("sigmoid")
    ])
    model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
    return model


iris = datasets.load_iris()
X = iris["data"]
y = iris["target"].flatten()

param_grid = {
    "n_hidden": np.array([4, 8, 16]),
    "nb_epoch": np.array(range(50, 61, 5))
}

model = KerasClassifier(build_fn=build_model, verbose=0)
skf = StratifiedKFold(n_splits=5).split(X, y) # this yields (train_indices, test_indices)

grid = GridSearchCV(model, param_grid, cv=skf, verbose=2, n_jobs=4)
grid.fit(X, y)

print(grid.best_score_)
print(grid.cv_results_["params"][grid.best_index_])
为了进一步解释,它使用了
param_grid
中所有可能的超参数组合来构建模型。然后在
StratifiedKFold
提供的列车测试数据分割(fold)上对每个模型逐一进行训练和测试。然后,给定模型的最终分数是所有折叠的平均分数

那么,在实际拟合之前,是否可以在上面的代码中插入一些预处理子步骤来转换数据(稀疏矩阵)?


我知道我可以编写自己的交叉验证生成器,但它必须生成索引,而不是真正的数据

实际上,您可以使用稀疏矩阵作为带有生成器的Keras的输入。以下是我在上一个项目中使用的版本:

> class KerasClassifier(KerasClassifier):
>     """ adds sparse matrix handling using batch generator
>     """
>     
>     def fit(self, x, y, **kwargs):
>         """ adds sparse matrix handling """
>         if not issparse(x):
>             return super().fit(x, y, **kwargs)
>         
>         ############ adapted from KerasClassifier.fit   ######################   
>         if self.build_fn is None:
>             self.model = self.__call__(**self.filter_sk_params(self.__call__))
>         elif not isinstance(self.build_fn, types.FunctionType):
>             self.model = self.build_fn(
>                 **self.filter_sk_params(self.build_fn.__call__))
>         else:
>             self.model = self.build_fn(**self.filter_sk_params(self.build_fn))
> 
>         loss_name = self.model.loss
>         if hasattr(loss_name, '__name__'):
>             loss_name = loss_name.__name__
>         if loss_name == 'categorical_crossentropy' and len(y.shape) != 2:
>             y = to_categorical(y)
>         ### fit => fit_generator
>         fit_args = copy.deepcopy(self.filter_sk_params(Sequential.fit_generator))
>         fit_args.update(kwargs)
>         ############################################################
>         self.model.fit_generator(
>                     self.get_batch(x, y, self.sk_params["batch_size"]),
>                                         samples_per_epoch=x.shape[0],
>                                         **fit_args)                      
>         return self                               
> 
>     def get_batch(self, x, y=None, batch_size=32):
>         """ batch generator to enable sparse input """
>         index = np.arange(x.shape[0])
>         start = 0
>         while True:
>             if start == 0 and y is not None:
>                 np.random.shuffle(index)
>             batch = index[start:start+batch_size]
>             if y is not None:
>                 yield x[batch].toarray(), y[batch]
>             else:
>                 yield x[batch].toarray()
>             start += batch_size
>             if start >= x.shape[0]:
>                 start = 0
>   
>     def predict_proba(self, x):
>         """ adds sparse matrix handling """
>         if not issparse(x):
>             return super().predict_proba(x)
>             
>         preds = self.model.predict_generator(
>                     self.get_batch(x, None, self.sk_params["batch_size"]), 
>                                                val_samples=x.shape[0])
>         return preds
这看起来不错——我也想到了修改Keras的源代码,但我想避免这样做。谢谢,我会试试的:)