簡體   English   中英

sklearn中的GridSearchCV和管道是否適合?

[英]Is there a diffrence of fit on GridSearchCV and Pipeline in sklearn?

也許這只是一個錯誤,或者我真的很愚蠢,我使用一些Keras轉換包裝了Keras模型(最好是說一個同事包裝了一個Keras模型),所以我們可以在sklearn庫中使用Keras模型。

現在,當我在管道上使用fit時,它可以正常工作。 它運行並返回一個工作模型實例。 但是,當我出於某種原因使用GridSearchCV時,它無法執行轉換(或者看起來如此),並且給了我以下錯誤:

InvalidArgumentError (see above for traceback): indices[11,2] = 26048 is not in [0, 10001)
     [[Node: embedding_4/Gather = Gather[Tindices=DT_INT32, Tparams=DT_FLOAT, validate_indices=true, _device="/job:localhost/replica:0/task:0/cpu:0"](embedding_4/embeddings/read, embedding_4/Cast)]]

代碼看起來像這樣:

vocab_size = 10001

class TextsToSequences(Tokenizer, BaseEstimator, TransformerMixin):
    def __init__(self,  **kwargs):
        super().__init__(**kwargs)

    def fit(self, X, y=None):
        print('fitting the text')
        print(self.document_count)
        self.fit_on_texts(X)
        return self

    def transform(self, X, y=None):
        print('transforming the text')
        r = np.array(self.texts_to_sequences(X))
        print(r)
        print(self.document_count)
        return r

class Padder(BaseEstimator, TransformerMixin):
    def __init__(self, maxlen=500):
        self.maxlen = maxlen
        self.max_index = None

    def fit(self, X, y=None):
        #self.max_index = pad_sequences(X, maxlen=self.maxlen).max()
        return self

    def transform(self, X, y=None):
        print('pad the text')
        X = pad_sequences(X, maxlen=self.maxlen, padding='post')
        #X[X > self.max_index] = 0

        print(X)

        return X

maxlen = 15

def makeLstmModel():
    model = Sequential()
    model.add(Embedding(10001, 100, input_length=15))
    model.add(LSTM(35, dropout=0.2, recurrent_dropout=0.2))
    model.add(Dense(16, activation='sigmoid'))
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    model.summary()
    return model

lstmmodel = KerasClassifier(build_fn=makeLstmModel, epochs=5, batch_size=1000, verbose=42)

pipeline =  [
        ('seq', TextsToSequences(num_words=vocab_size)),
        ('pad', Padder(maxlen)),
        ('clf', lstmmodel)
    ]

textClassifier = Pipeline(pipeline)

#Setup parameters
parameters = {} #Some params to use in gridsearch

skf = StratifiedKFold(n_splits=numberOfFolds, shuffle=True, random_state=1)
gscv = GridSearchCV(textClassifier, parameters, cv=skf, iid=False, n_jobs=1, verbose=50)

gscv.fit(x_train, y_train)

現在,上面的代碼失敗InvalidArgumentError,但是當我運行fitPipeline它的工作原理:

在此處輸入圖片說明

GridSearchCV fit()Pipeline之間有區別嗎? 我真的很愚蠢嗎,或者這只是一個錯誤?

順便說一句,我目前被迫使用Sklearn 0.19.1。

經過數小時的思考和調試,我得出以下結論:

Pipeline.fit()能夠自動填充**kwargs參數。

GridSearchCV.fit()無法自動填充**kwargs參數。

我在sklearn 0.19.1上測試過

我的問題是使用num_words參數創建了用num_words Tokenizer創建的單詞袋,該參數將單詞袋限制為最大單詞數。 我的同事在這方面做得不好,因此單詞的數量與LSTM模型中輸入維的數量相匹配。 由於從未設置num_words ,因此bag始終大於輸入維度。

num_words作為**kwargs參數傳遞給Tokenizer

class TextsToSequences(Tokenizer, BaseEstimator, TransformerMixin):
    def __init__(self,  **kwargs):
        super().__init__(**kwargs)

由於某種原因, GridSearchCV.fit()無法自動填充此內容。 解決方案是使用固定參數。

class TextsToSequences(Tokenizer, BaseEstimator, TransformerMixin):
    def __init__(self, num_words=8000, **kwargs):
        super().__init__(num_words, **kwargs)

更改之后, GridSearchCV.fit()起作用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM