Estimator should be an estimator implementing 'fit' method,

I used Pytorch to create 3DCNN
I used the gridsearch function to choose the parameters of the model.
I found this error !
can you help me ?
thank you in advance!

batch_size = [5, 10]
epochs = [50, 100, 500]
learn_rate = [0.01, 0.001, 0.0001, 0.00001, 0.000001]
param_grid = dict(batch_size=batch_size, epochs=epochs, learn_rate=learn_rate)
grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=1,cv=3)
grid_result = grid.fit(data,targets)
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))

Result

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-1-ccbe836e4806> in <module>
    147 param_grid = dict(batch_size=batch_size, epochs=epochs, learn_rate=learn_rate)
    148 grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=1,cv=3)
--> 149 grid_result = grid.fit(data,targets)
    150 print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))
    151 means = grid_result.cv_results_['mean_test_score']

/opt/tljh/user/envs/fethi_env/lib/python3.6/site-packages/sklearn/utils/validation.py in inner_f(*args, **kwargs)
     70                           FutureWarning)
     71         kwargs.update({k: arg for k, arg in zip(sig.parameters, args)})
---> 72         return f(**kwargs)
     73     return inner_f
     74 

/opt/tljh/user/envs/fethi_env/lib/python3.6/site-packages/sklearn/model_selection/_search.py in fit(self, X, y, groups, **fit_params)
    653 
    654         scorers, self.multimetric_ = _check_multimetric_scoring(
--> 655             self.estimator, scoring=self.scoring)
    656 
    657         if self.multimetric_:

/opt/tljh/user/envs/fethi_env/lib/python3.6/site-packages/sklearn/metrics/_scorer.py in _check_multimetric_scoring(estimator, scoring)
    473     if callable(scoring) or scoring is None or isinstance(scoring,
    474                                                           str):
--> 475         scorers = {"score": check_scoring(estimator, scoring=scoring)}
    476         return scorers, False
    477     else:

/opt/tljh/user/envs/fethi_env/lib/python3.6/site-packages/sklearn/utils/validation.py in inner_f(*args, **kwargs)
     70                           FutureWarning)
     71         kwargs.update({k: arg for k, arg in zip(sig.parameters, args)})
---> 72         return f(**kwargs)
     73     return inner_f
     74 

/opt/tljh/user/envs/fethi_env/lib/python3.6/site-packages/sklearn/metrics/_scorer.py in check_scoring(estimator, scoring, allow_none)
    401     if not hasattr(estimator, 'fit'):
    402         raise TypeError("estimator should be an estimator implementing "
--> 403                         "'fit' method, %r was passed" % estimator)
    404     if isinstance(scoring, str):
    405         return get_scorer(scoring)

TypeError: estimator should be an estimator implementing 'fit' method, CNNModel(
  (conv_layer1): Sequential(
    (0): Conv3d(3, 32, kernel_size=(3, 3, 3), stride=(1, 1, 1))
    (1): LeakyReLU(negative_slope=0.01)
    (2): MaxPool3d(kernel_size=(2, 2, 2), stride=(2, 2, 2), padding=0, dilation=1, ceil_mode=False)
  )
  (conv_layer2): Sequential(
    (0): Conv3d(32, 64, kernel_size=(3, 3, 3), stride=(1, 1, 1))
    (1): LeakyReLU(negative_slope=0.01)
    (2): MaxPool3d(kernel_size=(2, 2, 2), stride=(2, 2, 2), padding=0, dilation=1, ceil_mode=False)
  )
  (fc1): Linear(in_features=1404928, out_features=2, bias=True)
  (fc2): Linear(in_features=1404928, out_features=2, bias=True)
  (relu): LeakyReLU(negative_slope=0.01)
  (batch): BatchNorm1d(2, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (drop): Dropout(p=0.15, inplace=True)
) was passed

Instead of using GridSearchCV, give hyperearch a try. You can also try GridSearchCV with skorch.

Thank you @Abhilash_Srivastava for your response.
I tried with skroch but i found an error here

net = NeuralNet(
    model,    
    max_epochs=50,
    lr=0.1,
    criterion = torch.nn.CrossEntropyLoss(),
    # Shuffle training data on each epoch
    iterator_train__shuffle=True,
    verbose=False,
)
net.fit(data, targets)
TypeError                                 Traceback (most recent call last)
<ipython-input-1-b062d1acaff3> in <module>
    166     verbose=False,
    167 )
--> 168 net.fit(data, targets)
    169 y_proba = net.predict_proba(X)
    170 #score(X, y[, sample_weight])

/opt/tljh/user/envs/fethi_env/lib/python3.6/site-packages/skorch/net.py in fit(self, X, y, **fit_params)
    899         """
    900         if not self.warm_start or not self.initialized_:
--> 901             self.initialize()
    902 
    903         self.partial_fit(X, y, **fit_params)

/opt/tljh/user/envs/fethi_env/lib/python3.6/site-packages/skorch/net.py in initialize(self)
    583         self.initialize_virtual_params()
    584         self.initialize_callbacks()
--> 585         self.initialize_criterion()
    586         self.initialize_module()
    587         self.initialize_optimizer()

/opt/tljh/user/envs/fethi_env/lib/python3.6/site-packages/skorch/net.py in initialize_criterion(self)
    471         """Initializes the criterion."""
    472         criterion_params = self.get_params_for('criterion')
--> 473         self.criterion_ = self.criterion(**criterion_params)
    474         if isinstance(self.criterion_, torch.nn.Module):
    475             self.criterion_ = to_device(self.criterion_, self.device)

/opt/tljh/user/envs/fethi_env/lib/python3.6/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
    530             result = self._slow_forward(*input, **kwargs)
    531         else:
--> 532             result = self.forward(*input, **kwargs)
    533         for hook in self._forward_hooks.values():
    534             hook_result = hook(self, input, result)

TypeError: forward() missing 2 required positional arguments: 'input' and 'target'
​

Rq: 3DCNN:

class CNNModel(nn.Module):
    def __init__(self): 
        super(CNNModel, self).__init__() # héritage
        
        self.conv_layer1 = self._conv_layer_set(3, 32)
        self.conv_layer2 = self._conv_layer_set(32, 64) 
        self.fc1 = nn.Linear(64*28*28*28, 2) 
        self.fc2 = nn.Linear(1404928, num_classes) 
        self.relu = nn.LeakyReLU()
        self.batch=nn.BatchNorm1d(2)
        self.drop=nn.Dropout(p=0.15, inplace = True)   
        
    def _conv_layer_set(self, in_c, out_c):
        conv_layer = nn.Sequential(
        nn.Conv3d(in_c, out_c, kernel_size=(3, 3, 3), padding=0),
        nn.LeakyReLU(),
        nn.MaxPool3d((2, 2, 2)),
        )
        return conv_layer
    

    def forward(self, x):
        # Set 1
        out = self.conv_layer1(x)
        out = self.conv_layer2(out)
        out = out.view(out.size(0), -1) 
        out = self.fc1(out)
        out = self.relu(out)
        out = self.batch(out)
        out = self.drop(out)
        out = F.softmax(out, dim=1) 
        return out

I think there’s something wrong with your forward pass. If you’re using torch.nn.CrossEntropyLoss(), you wouldn’t need F.softmax.
Try running your model first without GridSearchCV. Just pick any set of hyperparams and make it train correctly. You might encounter more errors, correct those and then try skorch.

I modified the model by:

lass CNNModel(nn.Module):
    def __init__(self):
        super(CNNModel, self).__init__() 
        
        self.conv_layer1 = self._conv_layer_set(3, 32) 
        self.conv_layer2 = self._conv_layer_set(32, 64) 
        self.conv_layer3 = self._conv_layer_set(64, 128)
        self.conv_layer4 = self._conv_layer_set(128, 256)
        self.conv_layer5 = self._conv_layer_set(256, 512)
        #self.conv_layer6 = self._conv_layer_set(512, 1024)

        self.fc1 = nn.Linear(512, 128) 
        self.fc2 = nn.Linear(128, num_classes)
        self.relu = nn.LeakyReLU()
        self.batch=nn.BatchNorm1d(128)
        self.drop=nn.Dropout(p=0.15, inplace = True)   
        
    def _conv_layer_set(self, in_c, out_c):
        conv_layer = nn.Sequential(
        nn.Conv3d(in_c, out_c, kernel_size=(3, 3, 3), padding=0),
        nn.LeakyReLU(),
        nn.MaxPool3d((2, 2, 2)),
        )
        return conv_layer
    

    def forward(self, x):
        # Set 1
        out = self.conv_layer1(x)
        out = self.conv_layer2(out)
        out = self.conv_layer3(out)
        out = self.conv_layer4(out)
        out = self.conv_layer5(out)
        out = out.view(out.size(0), -1)
        #print('conv shape', out.shape)
        out = self.fc1(out)
        out = self.relu(out)
        out = self.batch(out) 
        out = self.drop(out)
        out = self.fc2(out)
        return out

it works fine without Grid Search but with Grid Search it still shows me the same error message (TypeError: forward() missing 2 required positional arguments: 'input' and 'target')

Change to criterion = torch.nn.CrossEntropyLoss,
Similar issue here.