Skip to content

Commit

Permalink
Merge branch 'main' into release-roles
Browse files Browse the repository at this point in the history
  • Loading branch information
fkiraly committed May 23, 2023
2 parents 9753752 + 460f10d commit aba27ec
Show file tree
Hide file tree
Showing 17 changed files with 945 additions and 72 deletions.
9 changes: 9 additions & 0 deletions .all-contributorsrc
Original file line number Diff line number Diff line change
Expand Up @@ -2175,6 +2175,15 @@
"contributions": [
"doc"
]
},
{
"login": "Taise228",
"name": "Taisei Yamamoto",
"avatar_url": "https://avatars.githubusercontent.com/u/95762401?s=400&v=4",
"profile": "https://github.com/Taise228",
"contributions": [
"code"
]
}
]
}
15 changes: 10 additions & 5 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,18 @@ Please go through the checklist below. Please feel free to remove points if they
-->

##### For all contributions
- [ ] I've added myself to the [list of contributors](https://github.com/sktime/sktime/blob/main/.all-contributorsrc).
- [ ] Optionally, I've updated sktime's [CODEOWNERS](https://github.com/sktime/sktime/blob/main/CODEOWNERS) to receive notifications about future changes to these files.
- [ ] The PR title starts with either [ENH], [MNT], [DOC], or [BUG] indicating whether the PR topic is related to enhancement, maintenance, documentation, or bug.
- [ ] I've added myself to the [list of contributors](https://github.com/sktime/sktime/blob/main/CONTRIBUTORS.md) with any new badges I've earned :-)
How to: add yourself to the [all-contributors file](https://github.com/sktime/sktime/blob/main/.all-contributorsrc) in the `sktime` root directory (not the `CONTRIBUTORS.md`). Common badges: `code` - fixing a bug, or adding code logic. `doc` - writing or improving documentation or docstrings. `bug` - reporting or diagnosing a bug (get this plus `code` if you also fixed the bug in the PR).`maintenance` - CI, test framework, release.
See here for [full badge reference](https://allcontributors.org/docs/en/emoji-key)
- [ ] Optionally, I've added myself and possibly others to the [CODEOWNERS](https://github.com/sktime/sktime/blob/main/CODEOWNERS) file - do this if you want to become the owner or maintainer of an estimator you added.
See here for further details on the [algorithm maintainer role](https://www.sktime.net/en/latest/get_involved/governance.html#algorithm-maintainers).
- [ ] The PR title starts with either [ENH], [MNT], [DOC], or [BUG]. [BUG] - bugfix, [MNT] - CI, test framework, [ENH] - adding or improving code, [DOC] - writing or improving documentation or docstrings.

##### For new estimators
- [ ] I've added the estimator to the online documentation.
- [ ] I've updated the existing example notebooks or provided a new one to showcase how my estimator works.
- [ ] I've added the estimator to the API reference - in `docs/source/api_reference/taskname.rst`, follow the pattern.
- [ ] I've added one or more illustrative usage examples to the docstring, in a pydocstyle compliant `Examples` section.
- [ ] If the estimator relies on a soft dependency, I've set the `python_dependencies` tag and ensured
dependency isolation, see the [estimator dependencies guide](https://www.sktime.net/en/latest/developer_guide/dependencies.html#adding-a-soft-dependency).


<!--
Expand Down
27 changes: 14 additions & 13 deletions CONTRIBUTORS.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/source/api_reference/classification.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Deep learning
FCNClassifier
LSTMFCNClassifier
InceptionTimeClassifier
MACNNClassifier
MLPClassifier
TapNetClassifier

Expand Down
2 changes: 1 addition & 1 deletion docs/source/api_reference/dists_kernels.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ Composition

DistFromAligner

.. currentmodule:: sktime.dists_to_kern
.. currentmodule:: sktime.dists_kernels.dist_to_kern

.. autosummary::
:toctree: auto_generated/
Expand Down
257 changes: 257 additions & 0 deletions sktime/classification/deep_learning/macnn.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
# -*- coding: utf-8 -*-
"""Mutli-scale Attention Convolutional Neural Classifier."""

__author__ = ["jnrusson1"]

from copy import deepcopy

from sklearn.utils import check_random_state

from sktime.classification.deep_learning.base import BaseDeepClassifier
from sktime.networks.macnn import MACNNNetwork
from sktime.utils.validation._dependencies import _check_dl_dependencies


class MACNNClassifier(BaseDeepClassifier):
"""Multi-Scale Attention Convolutional Neural Classifier, as described in [1]_.
Parameters
----------
n_epochs : int, optional (default=1500)
The number of epochs to train the model.
batch_size : int, optional (default=4)
The number of sample per gradient update.
padding : str, optional (default="same")
The type of padding to be provided in MACNN Blocks. Accepts
all the string values that keras.layers supports.
pool_size : int, optional (default=3)
A single value representing pooling windows which are applied
between two MACNN Blocks.
strides : int, optional (default=2)
A single value representing strides to be taken during the
pooling operation.
repeats : int, optional (default=2)
The number of MACNN Blocks to be stacked.
filter_sizes : tuple, optional (default=(64, 128, 256))
The input size of Conv1D layers within each MACNN Block.
kernel_size : tuple, optional (default=(3, 6, 12))
The output size of Conv1D layers within each MACNN Block.
reduction : int, optional (default = 16)
The factor by which the first dense layer of a MACNN Block will be divided by.
loss : str, optional (default="categorical_crossentropy")
The name of the loss function to be used during training,
should be supported by keras.
activation : str, optional (default="sigmoid")
The activation function to apply at the output. It should be
"software" if response variable has more than two types.
use_bias : bool, optional (default=True)
Whether bias should be included in the output layer.
metrics : None or string, optional (default=None)
The string which will be used during model compilation. If left as None,
then "accuracy" is passed to `model.compile()`.
optimizer: None or keras.optimizers.Optimizer instance, optional (default=None)
The optimizer that is used for model compiltation. If left as None,
then `keras.optimizers.Adam(learning_rate=0.0001)` is used.
callbacks : None or list of keras.callbacks.Callback, optinal (default=None)
The callback(s) to use during training.
random_state : int, optional (default=0)
The seed to any random action.
verbose : bool, optional (default=False)
Verbosity during model training, making it `True` will
print model summary, training information etc.
References
----------
.. [1] Wei Chen et. al, Multi-scale Attention Convolutional
Neural Network for time series classification,
Neural Networks, Volume 136, 2021, Pages 126-140, ISSN 0893-6080,
https://doi.org/10.1016/j.neunet.2021.01.001.
Examples
--------
>>> from sktime.classification.deep_learning.macnn import MACNNClassifier
>>> from sktime.datasets import load_unit_test
>>> X_train, y_train = load_unit_test(split="train")
>>> X_test, y_test = load_unit_test(split="test")
>>> macnn = MACNNClassifier(n_epochs=3) # doctest: +SKIP
>>> macnn.fit(X_train, y_train) # doctest: +SKIP
MACNNClassifier(...)
"""

_tags = {"python_dependencies": "tensorflow"}

def __init__(
self,
n_epochs=1500,
batch_size=4,
padding="same",
pool_size=3,
strides=2,
repeats=2,
filter_sizes=(64, 128, 256),
kernel_size=(3, 6, 12),
reduction=16,
loss="categorical_crossentropy",
activation="sigmoid",
use_bias=True,
metrics=None,
optimizer=None,
callbacks=None,
random_state=0,
verbose=False,
):
_check_dl_dependencies(severity="error")
super(MACNNClassifier, self).__init__()

self.n_epochs = n_epochs
self.batch_size = batch_size
self.padding = padding
self.pool_size = pool_size
self.strides = strides
self.repeats = repeats
self.filter_sizes = filter_sizes
self.kernel_size = kernel_size
self.reduction = reduction
self.loss = loss
self.activation = activation
self.use_bias = use_bias
self.metrics = metrics
self.optimizer = optimizer
self.callbacks = callbacks
self.random_state = random_state
self.verbose = verbose
self.history = None
self._network = MACNNNetwork(
padding=self.padding,
pool_size=self.pool_size,
strides=self.strides,
repeats=self.repeats,
filter_sizes=self.filter_sizes,
kernel_size=self.kernel_size,
reduction=self.reduction,
random_state=self.random_state,
)

def build_model(self, input_shape, n_classes, **kwargs):
"""
Construct a compiled, un-trained, keras model that is ready for training.
In sktime, time series are stored in numpy arrays of shape (d,m), where d
is the number of dimensions, m is the series length. Keras/tensorflow assume
data is in shape (m,d). This method also assumes (m,d). Transpose should
happen in fit.
Parameters
----------
input_shape : tuple
The shape of the data fed into the input layer, should be (m,d)
n_classes: int
The number of classes, which becomes the size of the output layer
Returns
-------
output : a compiled Keras Model
"""
import tensorflow as tf
from tensorflow import keras

tf.random.set_seed(self.random_state)

metrics = ["accuracy"] if self.metrics is None else self.metrics

input_layer, output_layer = self._network.build_network(input_shape, **kwargs)

output_layer = keras.layers.Dense(
units=n_classes, activation=self.activation, use_bias=self.use_bias
)(output_layer)

self.optimizer_ = (
keras.optimizers.Adam(learning_rate=0.0001)
if self.optimizer is None
else self.optimizer
)

model = keras.models.Model(inputs=input_layer, outputs=output_layer)
model.compile(
loss=self.loss,
optimizer=self.optimizer_,
metrics=metrics,
)

return model

def _fit(self, X, y):
"""
Fit the classifier on the training set (X, y).
Parameters
----------
X : np.ndarray of shape = (n_instances (n), n_dimensions (d), series_length (m))
The training input samples.
y : np.ndarray of shape n
The training data class labels.
Returns
-------
self : object
"""
y_onehot = self.convert_y_to_keras(y)
X = X.transpose(0, 2, 1)

check_random_state(self.random_state)
self.input_shape = X.shape[1:]
self.model_ = self.build_model(self.input_shape, self.n_classes_)
self.callbacks_ = deepcopy(self.callbacks)

if self.verbose:
self.model_.summary()

self.history = self.model_.fit(
X,
y_onehot,
batch_size=self.batch_size,
epochs=self.n_epochs,
verbose=self.verbose,
callbacks=self.callbacks_,
)

return self

@classmethod
def get_test_params(cls, parameter_set="default"):
"""Return testing parameter settings for the estimator.
Parameters
----------
parameter_set : str, optional (default="default")
Name of the set of test parameters to return, for use in tests. If no
special parameters are defined for a value, will return `"default"` set.
For classifiers, a "default" set of parameters should be provided for
general testing, and a "results_comparison" set for comparing against
previously recorded results if the general set does not produce suitable
probabilities to compare against.
Returns
-------
params : dict or list of dict
Parameters to create testing instances of the class.
Each dict are parameters to construct an "interesting" test instance, i.e.,
`MyClass(**params)` or `MyClass(**params[i])` creates a valid test instance.
`create_test_instance` uses the first (or only) dictionary in `params`.
"""
params1 = {
"n_epochs": 5,
"batch_size": 3,
"filter_sizes": (2, 4, 8),
"repeats": 1,
}

params2 = {
"n_epochs": 1,
"filter_sizes": (1, 2, 4),
"reduction": 8,
"repeats": 1,
"random_state": 1,
}

return [params1, params2]
27 changes: 27 additions & 0 deletions sktime/classification/deep_learning/rnn.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,33 @@
class SimpleRNNClassifier(BaseDeepClassifier):
"""Simple recurrent neural network.
Parameters
----------
n_epochs : int, default = 100
the number of epochs to train the model
batch_size : int, default = 1
the number of samples per gradient update.
units : int, default = 6
number of units in the network
callbacks : list of tf.keras.callbacks.Callback objects, default = None
add_default_callback : bool, default = True
whether to add default callback
random_state : int or None, default=0
Seed for random number generation.
verbose : boolean, default = False
whether to output extra information
loss : string, default="mean_squared_error"
fit parameter for the keras model
metrics : list of strings, default=["accuracy"]
metrics to use in fitting the neural network
activation : string or a tf callable, default="sigmoid"
Activation function used in the output layer.
List of available activation functions: https://keras.io/api/layers/activations/
use_bias : boolean, default = True
whether the layer uses a bias vector.
optimizer : keras.optimizers object, default = RMSprop(lr=0.001)
specify the optimizer and the learning rate to be used.
References
----------
..[1] benchmark forecaster in M4 forecasting competition:
Expand Down
Loading

0 comments on commit aba27ec

Please sign in to comment.