We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[BUG] MCDCNNClassifier.fit runs only 1 training epoch
Despite n_epochs being set to 200, only one training epoch will be executed here:

```python
from sktime.classification.deep_learning.mcdcnn import MCDCNNClassifier
from keras.losses import binary_crossentropy

model = MCDCNNClassifier(n_epochs=200, batch_size=64, loss=binary_crossentropy, random_state=42, metrics=['binary_accuracy'])
model.fit(x_train, y_train)
```

The problem is that model.n_epochs is not passed to self.model_.fit in MCDCNNClassifier._fit (mcdcnn.py):

```python
    def _fit(self, X, y):
        ...

        self.history = self.model_.fit(
            X,
            y_onehot,
            epochs=self.n_epochs, **#<<<-----------------THIS LINS IS MISSING #**
            batch_size=self.batch_size,
            verbose=self.verbose,
            callbacks=self.callbacks_,
        )

        return self
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `sktime/classification/deep_learning/mcdcnn.py`
Content:
```
1 """Multi Channel Deep Convolutional Neural Classifier (MCDCNN)."""
2 
3 __author__ = [
4     "JamesLarge",
5 ]
6 
7 from copy import deepcopy
8 
9 import numpy as np
10 from sklearn.utils import check_random_state
11 
12 from sktime.classification.deep_learning.base import BaseDeepClassifier
13 from sktime.networks.mcdcnn import MCDCNNNetwork
14 from sktime.utils.validation._dependencies import _check_dl_dependencies
15 
16 
17 class MCDCNNClassifier(BaseDeepClassifier):
18     """Multi Channel Deep Convolutional Neural Classifier, as described in [1]_.
19 
20     Parameters
21     ----------
22     n_epochs : int, optional (default=120)
23         The number of epochs to train the model.
24     batch_size : int, optional (default=16)
25         The number of samples per gradient update.
26     kernel_size : int, optional (default=5)
27         The size of kernel in Conv1D layer.
28     pool_size : int, optional (default=2)
29         The size of kernel in (Max) Pool layer.
30     filter_sizes : tuple, optional (default=(8, 8))
31         The sizes of filter for Conv1D layer corresponding
32         to each Conv1D in the block.
33     dense_units : int, optional (default=732)
34         The number of output units of the final Dense
35         layer of this Network. This is NOT the final layer
36         but the penultimate layer.
37     conv_padding : str or None, optional (default="same")
38         The type of padding to be applied to convolutional
39         layers.
40     pool_padding : str or None, optional (default="same")
41         The type of padding to be applied to pooling layers.
42     loss : str, optional (default="categorical_crossentropy")
43         The name of the loss function to be used during training,
44         should be supported by keras.
45     activation : str, optional (default="sigmoid")
46         The activation function to apply at the output. It should be
47         "software" if response variable has more than two types.
48     use_bias : bool, optional (default=True)
49         Whether bias should be included in the output layer.
50     metrics : None or string, optional (default=None)
51         The string which will be used during model compilation. If left as None,
52         then "accuracy" is passed to `model.compile()`.
53     optimizer: None or keras.optimizers.Optimizer instance, optional (default=None)
54         The optimizer that is used for model compiltation. If left as None,
55         then `keras.optimizers.SGD` is used with the following parameters -
56         `learning_rate=0.01, momentum=0.9, weight_decay=0.0005`.
57     callbacks : None or list of keras.callbacks.Callback, optinal (default=None)
58         The callback(s) to use during training.
59     random_state : int, optional (default=0)
60         The seed to any random action.
61 
62     Notes
63     -----
64     Adapted from the implementation of Fawaz et. al
65     https://github.com/hfawaz/dl-4-tsc/blob/master/classifiers/mcdcnn.py
66 
67     References
68     ----------
69     .. [1] Zheng et. al, Time series classification using multi-channels deep
70       convolutional neural networks, International Conference on
71       Web-Age Information Management, Pages 298-310, year 2014, organization: Springer.
72 
73     Examples
74     --------
75     >>> from sktime.classification.deep_learning.mcdcnn import MCDCNNClassifier
76     >>> from sktime.datasets import load_unit_test
77     >>> X_train, y_tain = load_unit_test(split="train")
78     >>> mcdcnn = MCDCNNClassifier()     # doctest: +SKIP
79     >>> mcdcnn.fit(X_train, y_train)    # doctest: +SKIP
80     MCDCNNClassifier(...)
81     """
82 
83     _tags = {"python_dependencies": "tensorflow"}
84 
85     def __init__(
86         self,
87         n_epochs=120,
88         batch_size=16,
89         kernel_size=5,
90         pool_size=2,
91         filter_sizes=(8, 8),
92         dense_units=732,
93         conv_padding="same",
94         pool_padding="same",
95         loss="categorical_crossentropy",
96         activation="sigmoid",
97         use_bias=True,
98         callbacks=None,
99         metrics=None,
100         optimizer=None,
101         verbose=False,
102         random_state=0,
103     ):
104         _check_dl_dependencies(severity="error")
105         super().__init__()
106 
107         self.n_epochs = n_epochs
108         self.batch_size = batch_size
109         self.kernel_size = kernel_size
110         self.pool_size = pool_size
111         self.filter_sizes = filter_sizes
112         self.dense_units = dense_units
113         self.conv_padding = conv_padding
114         self.pool_padding = pool_padding
115         self.loss = loss
116         self.activation = activation
117         self.use_bias = use_bias
118         self.callbacks = callbacks
119         self.metrics = metrics
120         self.optimizer = optimizer
121         self.verbose = verbose
122         self.random_state = random_state
123         self.history = None
124         self._network = MCDCNNNetwork(
125             kernel_size=self.kernel_size,
126             pool_size=self.pool_size,
127             filter_sizes=self.filter_sizes,
128             dense_units=self.dense_units,
129             conv_padding=self.conv_padding,
130             pool_padding=self.pool_padding,
131             random_state=self.random_state,
132         )
133 
134     def build_model(self, input_shape, n_classes, **kwargs):
135         """Construct a compiled, un-trained, keras model that is ready for training.
136 
137         In sktime, time series are stored in numpy arrays of shape (d,m), where d
138         is the number of dimensions, m is the series length. Keras/tensorflow assume
139         data is in shape (m,d). This method also assumes (m,d). Transpose should
140         happen in fit.
141 
142         Parameters
143         ----------
144         input_shape : tuple
145             The shape of the data fed into the input layer, should be (m,d)
146         n_classes: int
147             The number of classes, which becomes the size of the output layer
148 
149         Returns
150         -------
151         output : a compiled Keras Model
152         """
153         import tensorflow as tf
154         from tensorflow import keras
155 
156         tf.random.set_seed(self.random_state)
157 
158         metrics = ["accuracy"] if self.metrics is None else self.metrics
159 
160         input_layers, output_layer = self._network.build_network(input_shape, **kwargs)
161 
162         output_layer = keras.layers.Dense(
163             units=n_classes,
164             activation=self.activation,
165             use_bias=self.use_bias,
166         )(output_layer)
167 
168         self.optimizer_ = (
169             keras.optimizers.SGD(
170                 learning_rate=0.01,
171                 momentum=0.9,
172                 weight_decay=0.0005,
173             )
174             if self.optimizer is None
175             else self.optimizer
176         )
177 
178         model = keras.models.Model(inputs=input_layers, outputs=output_layer)
179 
180         model.compile(
181             loss=self.loss,
182             optimizer=self.optimizer_,
183             metrics=metrics,
184         )
185 
186         return model
187 
188     def _fit(self, X, y):
189         """Fit the classifier on the training set (X, y).
190 
191         Parameters
192         ----------
193         X : np.ndarray of shape = (n_instances (n), n_dimensions (d), series_length (m))
194             The training input samples.
195         y : np.ndarray of shape n
196             The training data class labels.
197 
198         Returns
199         -------
200         self : object
201         """
202         y_onehot = self.convert_y_to_keras(y)
203         X = X.transpose(0, 2, 1)
204         self.input_shape = X.shape[1:]
205         X = self._network._prepare_input(X)
206 
207         check_random_state(self.random_state)
208 
209         self.model_ = self.build_model(self.input_shape, self.n_classes_)
210         self.callbacks_ = deepcopy(self.callbacks)
211 
212         if self.verbose:
213             self.model_.summary()
214 
215         self.history = self.model_.fit(
216             X,
217             y_onehot,
218             batch_size=self.batch_size,
219             verbose=self.verbose,
220             callbacks=self.callbacks_,
221         )
222 
223         return self
224 
225     def _predict_proba(self, X, **kwargs):
226         """Find probability estimates for each class for all cases in X.
227 
228         Parameters
229         ----------
230         X : an np.ndarray of shape = (n_instances, n_dimensions, series_length)
231             The training input samples.
232 
233         Returns
234         -------
235         output : array of shape = [n_instances, n_classes] of probabilities
236         """
237         self.check_is_fitted()
238         X = X.transpose([0, 2, 1])
239         X = self._network._prepare_input(X)
240 
241         probs = self.model_.predict(X, self.batch_size, **kwargs)
242 
243         if probs.shape[1] == 1:
244             probs = np.hstack([1 - probs, probs])
245         probs = probs / probs.sum(axis=1, keepdims=1)
246         return probs
247
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/sktime/classification/deep_learning/mcdcnn.py b/sktime/classification/deep_learning/mcdcnn.py
--- a/sktime/classification/deep_learning/mcdcnn.py
+++ b/sktime/classification/deep_learning/mcdcnn.py
@@ -215,6 +215,7 @@
         self.history = self.model_.fit(
             X,
             y_onehot,
+            epochs=self.n_epochs,
             batch_size=self.batch_size,
             verbose=self.verbose,
             callbacks=self.callbacks_,

{"golden_diff": "diff --git a/sktime/classification/deep_learning/mcdcnn.py b/sktime/classification/deep_learning/mcdcnn.py\n--- a/sktime/classification/deep_learning/mcdcnn.py\n+++ b/sktime/classification/deep_learning/mcdcnn.py\n@@ -215,6 +215,7 @@\n         self.history = self.model_.fit(\r\n             X,\r\n             y_onehot,\r\n+            epochs=self.n_epochs,\r\n             batch_size=self.batch_size,\r\n             verbose=self.verbose,\r\n             callbacks=self.callbacks_,\n", "issue": "[BUG] MCDCNNClassifier.fit runs only 1 training epoch\nDespite n_epochs being set to 200, only one training epoch will be executed here:\r\n\r\n```python\r\nfrom sktime.classification.deep_learning.mcdcnn import MCDCNNClassifier\r\nfrom keras.losses import binary_crossentropy\r\n\r\nmodel = MCDCNNClassifier(n_epochs=200, batch_size=64, loss=binary_crossentropy, random_state=42, metrics=['binary_accuracy'])\r\nmodel.fit(x_train, y_train)\r\n```\r\n\r\nThe problem is that model.n_epochs is not passed to self.model_.fit in MCDCNNClassifier._fit (mcdcnn.py):\r\n\r\n```python\r\n    def _fit(self, X, y):\r\n        ...\r\n\r\n        self.history = self.model_.fit(\r\n            X,\r\n            y_onehot,\r\n            epochs=self.n_epochs, **#<<<-----------------THIS LINS IS MISSING #**\r\n            batch_size=self.batch_size,\r\n            verbose=self.verbose,\r\n            callbacks=self.callbacks_,\r\n        )\r\n\r\n        return self\r\n```\n", "before_files": [{"content": "\"\"\"Multi Channel Deep Convolutional Neural Classifier (MCDCNN).\"\"\"\r\n\r\n__author__ = [\r\n    \"JamesLarge\",\r\n]\r\n\r\nfrom copy import deepcopy\r\n\r\nimport numpy as np\r\nfrom sklearn.utils import check_random_state\r\n\r\nfrom sktime.classification.deep_learning.base import BaseDeepClassifier\r\nfrom sktime.networks.mcdcnn import MCDCNNNetwork\r\nfrom sktime.utils.validation._dependencies import _check_dl_dependencies\r\n\r\n\r\nclass MCDCNNClassifier(BaseDeepClassifier):\r\n    \"\"\"Multi Channel Deep Convolutional Neural Classifier, as described in [1]_.\r\n\r\n    Parameters\r\n    ----------\r\n    n_epochs : int, optional (default=120)\r\n        The number of epochs to train the model.\r\n    batch_size : int, optional (default=16)\r\n        The number of samples per gradient update.\r\n    kernel_size : int, optional (default=5)\r\n        The size of kernel in Conv1D layer.\r\n    pool_size : int, optional (default=2)\r\n        The size of kernel in (Max) Pool layer.\r\n    filter_sizes : tuple, optional (default=(8, 8))\r\n        The sizes of filter for Conv1D layer corresponding\r\n        to each Conv1D in the block.\r\n    dense_units : int, optional (default=732)\r\n        The number of output units of the final Dense\r\n        layer of this Network. This is NOT the final layer\r\n        but the penultimate layer.\r\n    conv_padding : str or None, optional (default=\"same\")\r\n        The type of padding to be applied to convolutional\r\n        layers.\r\n    pool_padding : str or None, optional (default=\"same\")\r\n        The type of padding to be applied to pooling layers.\r\n    loss : str, optional (default=\"categorical_crossentropy\")\r\n        The name of the loss function to be used during training,\r\n        should be supported by keras.\r\n    activation : str, optional (default=\"sigmoid\")\r\n        The activation function to apply at the output. It should be\r\n        \"software\" if response variable has more than two types.\r\n    use_bias : bool, optional (default=True)\r\n        Whether bias should be included in the output layer.\r\n    metrics : None or string, optional (default=None)\r\n        The string which will be used during model compilation. If left as None,\r\n        then \"accuracy\" is passed to `model.compile()`.\r\n    optimizer: None or keras.optimizers.Optimizer instance, optional (default=None)\r\n        The optimizer that is used for model compiltation. If left as None,\r\n        then `keras.optimizers.SGD` is used with the following parameters -\r\n        `learning_rate=0.01, momentum=0.9, weight_decay=0.0005`.\r\n    callbacks : None or list of keras.callbacks.Callback, optinal (default=None)\r\n        The callback(s) to use during training.\r\n    random_state : int, optional (default=0)\r\n        The seed to any random action.\r\n\r\n    Notes\r\n    -----\r\n    Adapted from the implementation of Fawaz et. al\r\n    https://github.com/hfawaz/dl-4-tsc/blob/master/classifiers/mcdcnn.py\r\n\r\n    References\r\n    ----------\r\n    .. [1] Zheng et. al, Time series classification using multi-channels deep\r\n      convolutional neural networks, International Conference on\r\n      Web-Age Information Management, Pages 298-310, year 2014, organization: Springer.\r\n\r\n    Examples\r\n    --------\r\n    >>> from sktime.classification.deep_learning.mcdcnn import MCDCNNClassifier\r\n    >>> from sktime.datasets import load_unit_test\r\n    >>> X_train, y_tain = load_unit_test(split=\"train\")\r\n    >>> mcdcnn = MCDCNNClassifier()     # doctest: +SKIP\r\n    >>> mcdcnn.fit(X_train, y_train)    # doctest: +SKIP\r\n    MCDCNNClassifier(...)\r\n    \"\"\"\r\n\r\n    _tags = {\"python_dependencies\": \"tensorflow\"}\r\n\r\n    def __init__(\r\n        self,\r\n        n_epochs=120,\r\n        batch_size=16,\r\n        kernel_size=5,\r\n        pool_size=2,\r\n        filter_sizes=(8, 8),\r\n        dense_units=732,\r\n        conv_padding=\"same\",\r\n        pool_padding=\"same\",\r\n        loss=\"categorical_crossentropy\",\r\n        activation=\"sigmoid\",\r\n        use_bias=True,\r\n        callbacks=None,\r\n        metrics=None,\r\n        optimizer=None,\r\n        verbose=False,\r\n        random_state=0,\r\n    ):\r\n        _check_dl_dependencies(severity=\"error\")\r\n        super().__init__()\r\n\r\n        self.n_epochs = n_epochs\r\n        self.batch_size = batch_size\r\n        self.kernel_size = kernel_size\r\n        self.pool_size = pool_size\r\n        self.filter_sizes = filter_sizes\r\n        self.dense_units = dense_units\r\n        self.conv_padding = conv_padding\r\n        self.pool_padding = pool_padding\r\n        self.loss = loss\r\n        self.activation = activation\r\n        self.use_bias = use_bias\r\n        self.callbacks = callbacks\r\n        self.metrics = metrics\r\n        self.optimizer = optimizer\r\n        self.verbose = verbose\r\n        self.random_state = random_state\r\n        self.history = None\r\n        self._network = MCDCNNNetwork(\r\n            kernel_size=self.kernel_size,\r\n            pool_size=self.pool_size,\r\n            filter_sizes=self.filter_sizes,\r\n            dense_units=self.dense_units,\r\n            conv_padding=self.conv_padding,\r\n            pool_padding=self.pool_padding,\r\n            random_state=self.random_state,\r\n        )\r\n\r\n    def build_model(self, input_shape, n_classes, **kwargs):\r\n        \"\"\"Construct a compiled, un-trained, keras model that is ready for training.\r\n\r\n        In sktime, time series are stored in numpy arrays of shape (d,m), where d\r\n        is the number of dimensions, m is the series length. Keras/tensorflow assume\r\n        data is in shape (m,d). This method also assumes (m,d). Transpose should\r\n        happen in fit.\r\n\r\n        Parameters\r\n        ----------\r\n        input_shape : tuple\r\n            The shape of the data fed into the input layer, should be (m,d)\r\n        n_classes: int\r\n            The number of classes, which becomes the size of the output layer\r\n\r\n        Returns\r\n        -------\r\n        output : a compiled Keras Model\r\n        \"\"\"\r\n        import tensorflow as tf\r\n        from tensorflow import keras\r\n\r\n        tf.random.set_seed(self.random_state)\r\n\r\n        metrics = [\"accuracy\"] if self.metrics is None else self.metrics\r\n\r\n        input_layers, output_layer = self._network.build_network(input_shape, **kwargs)\r\n\r\n        output_layer = keras.layers.Dense(\r\n            units=n_classes,\r\n            activation=self.activation,\r\n            use_bias=self.use_bias,\r\n        )(output_layer)\r\n\r\n        self.optimizer_ = (\r\n            keras.optimizers.SGD(\r\n                learning_rate=0.01,\r\n                momentum=0.9,\r\n                weight_decay=0.0005,\r\n            )\r\n            if self.optimizer is None\r\n            else self.optimizer\r\n        )\r\n\r\n        model = keras.models.Model(inputs=input_layers, outputs=output_layer)\r\n\r\n        model.compile(\r\n            loss=self.loss,\r\n            optimizer=self.optimizer_,\r\n            metrics=metrics,\r\n        )\r\n\r\n        return model\r\n\r\n    def _fit(self, X, y):\r\n        \"\"\"Fit the classifier on the training set (X, y).\r\n\r\n        Parameters\r\n        ----------\r\n        X : np.ndarray of shape = (n_instances (n), n_dimensions (d), series_length (m))\r\n            The training input samples.\r\n        y : np.ndarray of shape n\r\n            The training data class labels.\r\n\r\n        Returns\r\n        -------\r\n        self : object\r\n        \"\"\"\r\n        y_onehot = self.convert_y_to_keras(y)\r\n        X = X.transpose(0, 2, 1)\r\n        self.input_shape = X.shape[1:]\r\n        X = self._network._prepare_input(X)\r\n\r\n        check_random_state(self.random_state)\r\n\r\n        self.model_ = self.build_model(self.input_shape, self.n_classes_)\r\n        self.callbacks_ = deepcopy(self.callbacks)\r\n\r\n        if self.verbose:\r\n            self.model_.summary()\r\n\r\n        self.history = self.model_.fit(\r\n            X,\r\n            y_onehot,\r\n            batch_size=self.batch_size,\r\n            verbose=self.verbose,\r\n            callbacks=self.callbacks_,\r\n        )\r\n\r\n        return self\r\n\r\n    def _predict_proba(self, X, **kwargs):\r\n        \"\"\"Find probability estimates for each class for all cases in X.\r\n\r\n        Parameters\r\n        ----------\r\n        X : an np.ndarray of shape = (n_instances, n_dimensions, series_length)\r\n            The training input samples.\r\n\r\n        Returns\r\n        -------\r\n        output : array of shape = [n_instances, n_classes] of probabilities\r\n        \"\"\"\r\n        self.check_is_fitted()\r\n        X = X.transpose([0, 2, 1])\r\n        X = self._network._prepare_input(X)\r\n\r\n        probs = self.model_.predict(X, self.batch_size, **kwargs)\r\n\r\n        if probs.shape[1] == 1:\r\n            probs = np.hstack([1 - probs, probs])\r\n        probs = probs / probs.sum(axis=1, keepdims=1)\r\n        return probs\r\n", "path": "sktime/classification/deep_learning/mcdcnn.py"}], "after_files": [{"content": "\"\"\"Multi Channel Deep Convolutional Neural Classifier (MCDCNN).\"\"\"\r\n\r\n__author__ = [\r\n    \"JamesLarge\",\r\n]\r\n\r\nfrom copy import deepcopy\r\n\r\nimport numpy as np\r\nfrom sklearn.utils import check_random_state\r\n\r\nfrom sktime.classification.deep_learning.base import BaseDeepClassifier\r\nfrom sktime.networks.mcdcnn import MCDCNNNetwork\r\nfrom sktime.utils.validation._dependencies import _check_dl_dependencies\r\n\r\n\r\nclass MCDCNNClassifier(BaseDeepClassifier):\r\n    \"\"\"Multi Channel Deep Convolutional Neural Classifier, as described in [1]_.\r\n\r\n    Parameters\r\n    ----------\r\n    n_epochs : int, optional (default=120)\r\n        The number of epochs to train the model.\r\n    batch_size : int, optional (default=16)\r\n        The number of samples per gradient update.\r\n    kernel_size : int, optional (default=5)\r\n        The size of kernel in Conv1D layer.\r\n    pool_size : int, optional (default=2)\r\n        The size of kernel in (Max) Pool layer.\r\n    filter_sizes : tuple, optional (default=(8, 8))\r\n        The sizes of filter for Conv1D layer corresponding\r\n        to each Conv1D in the block.\r\n    dense_units : int, optional (default=732)\r\n        The number of output units of the final Dense\r\n        layer of this Network. This is NOT the final layer\r\n        but the penultimate layer.\r\n    conv_padding : str or None, optional (default=\"same\")\r\n        The type of padding to be applied to convolutional\r\n        layers.\r\n    pool_padding : str or None, optional (default=\"same\")\r\n        The type of padding to be applied to pooling layers.\r\n    loss : str, optional (default=\"categorical_crossentropy\")\r\n        The name of the loss function to be used during training,\r\n        should be supported by keras.\r\n    activation : str, optional (default=\"sigmoid\")\r\n        The activation function to apply at the output. It should be\r\n        \"software\" if response variable has more than two types.\r\n    use_bias : bool, optional (default=True)\r\n        Whether bias should be included in the output layer.\r\n    metrics : None or string, optional (default=None)\r\n        The string which will be used during model compilation. If left as None,\r\n        then \"accuracy\" is passed to `model.compile()`.\r\n    optimizer: None or keras.optimizers.Optimizer instance, optional (default=None)\r\n        The optimizer that is used for model compiltation. If left as None,\r\n        then `keras.optimizers.SGD` is used with the following parameters -\r\n        `learning_rate=0.01, momentum=0.9, weight_decay=0.0005`.\r\n    callbacks : None or list of keras.callbacks.Callback, optinal (default=None)\r\n        The callback(s) to use during training.\r\n    random_state : int, optional (default=0)\r\n        The seed to any random action.\r\n\r\n    Notes\r\n    -----\r\n    Adapted from the implementation of Fawaz et. al\r\n    https://github.com/hfawaz/dl-4-tsc/blob/master/classifiers/mcdcnn.py\r\n\r\n    References\r\n    ----------\r\n    .. [1] Zheng et. al, Time series classification using multi-channels deep\r\n      convolutional neural networks, International Conference on\r\n      Web-Age Information Management, Pages 298-310, year 2014, organization: Springer.\r\n\r\n    Examples\r\n    --------\r\n    >>> from sktime.classification.deep_learning.mcdcnn import MCDCNNClassifier\r\n    >>> from sktime.datasets import load_unit_test\r\n    >>> X_train, y_tain = load_unit_test(split=\"train\")\r\n    >>> mcdcnn = MCDCNNClassifier()     # doctest: +SKIP\r\n    >>> mcdcnn.fit(X_train, y_train)    # doctest: +SKIP\r\n    MCDCNNClassifier(...)\r\n    \"\"\"\r\n\r\n    _tags = {\"python_dependencies\": \"tensorflow\"}\r\n\r\n    def __init__(\r\n        self,\r\n        n_epochs=120,\r\n        batch_size=16,\r\n        kernel_size=5,\r\n        pool_size=2,\r\n        filter_sizes=(8, 8),\r\n        dense_units=732,\r\n        conv_padding=\"same\",\r\n        pool_padding=\"same\",\r\n        loss=\"categorical_crossentropy\",\r\n        activation=\"sigmoid\",\r\n        use_bias=True,\r\n        callbacks=None,\r\n        metrics=None,\r\n        optimizer=None,\r\n        verbose=False,\r\n        random_state=0,\r\n    ):\r\n        _check_dl_dependencies(severity=\"error\")\r\n        super().__init__()\r\n\r\n        self.n_epochs = n_epochs\r\n        self.batch_size = batch_size\r\n        self.kernel_size = kernel_size\r\n        self.pool_size = pool_size\r\n        self.filter_sizes = filter_sizes\r\n        self.dense_units = dense_units\r\n        self.conv_padding = conv_padding\r\n        self.pool_padding = pool_padding\r\n        self.loss = loss\r\n        self.activation = activation\r\n        self.use_bias = use_bias\r\n        self.callbacks = callbacks\r\n        self.metrics = metrics\r\n        self.optimizer = optimizer\r\n        self.verbose = verbose\r\n        self.random_state = random_state\r\n        self.history = None\r\n        self._network = MCDCNNNetwork(\r\n            kernel_size=self.kernel_size,\r\n            pool_size=self.pool_size,\r\n            filter_sizes=self.filter_sizes,\r\n            dense_units=self.dense_units,\r\n            conv_padding=self.conv_padding,\r\n            pool_padding=self.pool_padding,\r\n            random_state=self.random_state,\r\n        )\r\n\r\n    def build_model(self, input_shape, n_classes, **kwargs):\r\n        \"\"\"Construct a compiled, un-trained, keras model that is ready for training.\r\n\r\n        In sktime, time series are stored in numpy arrays of shape (d,m), where d\r\n        is the number of dimensions, m is the series length. Keras/tensorflow assume\r\n        data is in shape (m,d). This method also assumes (m,d). Transpose should\r\n        happen in fit.\r\n\r\n        Parameters\r\n        ----------\r\n        input_shape : tuple\r\n            The shape of the data fed into the input layer, should be (m,d)\r\n        n_classes: int\r\n            The number of classes, which becomes the size of the output layer\r\n\r\n        Returns\r\n        -------\r\n        output : a compiled Keras Model\r\n        \"\"\"\r\n        import tensorflow as tf\r\n        from tensorflow import keras\r\n\r\n        tf.random.set_seed(self.random_state)\r\n\r\n        metrics = [\"accuracy\"] if self.metrics is None else self.metrics\r\n\r\n        input_layers, output_layer = self._network.build_network(input_shape, **kwargs)\r\n\r\n        output_layer = keras.layers.Dense(\r\n            units=n_classes,\r\n            activation=self.activation,\r\n            use_bias=self.use_bias,\r\n        )(output_layer)\r\n\r\n        self.optimizer_ = (\r\n            keras.optimizers.SGD(\r\n                learning_rate=0.01,\r\n                momentum=0.9,\r\n                weight_decay=0.0005,\r\n            )\r\n            if self.optimizer is None\r\n            else self.optimizer\r\n        )\r\n\r\n        model = keras.models.Model(inputs=input_layers, outputs=output_layer)\r\n\r\n        model.compile(\r\n            loss=self.loss,\r\n            optimizer=self.optimizer_,\r\n            metrics=metrics,\r\n        )\r\n\r\n        return model\r\n\r\n    def _fit(self, X, y):\r\n        \"\"\"Fit the classifier on the training set (X, y).\r\n\r\n        Parameters\r\n        ----------\r\n        X : np.ndarray of shape = (n_instances (n), n_dimensions (d), series_length (m))\r\n            The training input samples.\r\n        y : np.ndarray of shape n\r\n            The training data class labels.\r\n\r\n        Returns\r\n        -------\r\n        self : object\r\n        \"\"\"\r\n        y_onehot = self.convert_y_to_keras(y)\r\n        X = X.transpose(0, 2, 1)\r\n        self.input_shape = X.shape[1:]\r\n        X = self._network._prepare_input(X)\r\n\r\n        check_random_state(self.random_state)\r\n\r\n        self.model_ = self.build_model(self.input_shape, self.n_classes_)\r\n        self.callbacks_ = deepcopy(self.callbacks)\r\n\r\n        if self.verbose:\r\n            self.model_.summary()\r\n\r\n        self.history = self.model_.fit(\r\n            X,\r\n            y_onehot,\r\n            epochs=self.n_epochs,\r\n            batch_size=self.batch_size,\r\n            verbose=self.verbose,\r\n            callbacks=self.callbacks_,\r\n        )\r\n\r\n        return self\r\n\r\n    def _predict_proba(self, X, **kwargs):\r\n        \"\"\"Find probability estimates for each class for all cases in X.\r\n\r\n        Parameters\r\n        ----------\r\n        X : an np.ndarray of shape = (n_instances, n_dimensions, series_length)\r\n            The training input samples.\r\n\r\n        Returns\r\n        -------\r\n        output : array of shape = [n_instances, n_classes] of probabilities\r\n        \"\"\"\r\n        self.check_is_fitted()\r\n        X = X.transpose([0, 2, 1])\r\n        X = self._network._prepare_input(X)\r\n\r\n        probs = self.model_.predict(X, self.batch_size, **kwargs)\r\n\r\n        if probs.shape[1] == 1:\r\n            probs = np.hstack([1 - probs, probs])\r\n        probs = probs / probs.sum(axis=1, keepdims=1)\r\n        return probs\r\n", "path": "sktime/classification/deep_learning/mcdcnn.py"}]}