nnodely 1.3.0__tar.gz → 1.3.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. {nnodely-1.3.0/nnodely.egg-info → nnodely-1.3.1}/PKG-INFO +17 -15
  2. {nnodely-1.3.0 → nnodely-1.3.1}/README.md +17 -15
  3. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/__init__.py +1 -1
  4. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/activation.py +21 -20
  5. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/arithmetic.py +2 -2
  6. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/initializer.py +22 -22
  7. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/input.py +9 -11
  8. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/nnodely.py +1 -3
  9. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/relation.py +3 -0
  10. {nnodely-1.3.0 → nnodely-1.3.1/nnodely.egg-info}/PKG-INFO +17 -15
  11. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely.egg-info/SOURCES.txt +1 -0
  12. {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_dataset.py +1 -5
  13. nnodely-1.3.1/tests/test_documentation.py +25 -0
  14. {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_export.py +1 -6
  15. {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_export_recurrent.py +0 -3
  16. {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_input_dimensions.py +0 -2
  17. {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_json.py +0 -2
  18. {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_losses.py +1 -4
  19. {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_model_predict.py +35 -22
  20. {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_model_predict_recurrent.py +0 -4
  21. {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_network_element.py +0 -4
  22. {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_parameters_of_train.py +0 -9
  23. {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_results.py +0 -18
  24. {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_train.py +0 -12
  25. {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_train_recurrent.py +1 -4
  26. {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_utils.py +0 -3
  27. {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_visualizer.py +1 -4
  28. {nnodely-1.3.0 → nnodely-1.3.1}/LICENSE +0 -0
  29. {nnodely-1.3.0 → nnodely-1.3.1}/mplplots/__init__.py +0 -0
  30. {nnodely-1.3.0 → nnodely-1.3.1}/mplplots/plots.py +0 -0
  31. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/earlystopping.py +0 -0
  32. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/equationlearner.py +0 -0
  33. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/exporter/__init__.py +0 -0
  34. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/exporter/export.py +0 -0
  35. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/exporter/exporter.py +0 -0
  36. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/exporter/reporter.py +0 -0
  37. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/exporter/standardexporter.py +0 -0
  38. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/fir.py +0 -0
  39. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/fuzzify.py +0 -0
  40. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/interpolation.py +0 -0
  41. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/linear.py +0 -0
  42. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/localmodel.py +0 -0
  43. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/logger.py +0 -0
  44. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/loss.py +0 -0
  45. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/model.py +0 -0
  46. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/modeldef.py +0 -0
  47. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/optimizer.py +0 -0
  48. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/output.py +0 -0
  49. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/parameter.py +0 -0
  50. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/parametricfunction.py +0 -0
  51. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/part.py +0 -0
  52. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/timeoperation.py +0 -0
  53. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/trigonometric.py +0 -0
  54. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/utils.py +0 -0
  55. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/visualizer/__init__.py +0 -0
  56. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/visualizer/dynamicmpl/functionplot.py +0 -0
  57. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/visualizer/dynamicmpl/fuzzyplot.py +0 -0
  58. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/visualizer/dynamicmpl/resultsplot.py +0 -0
  59. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/visualizer/dynamicmpl/trainingplot.py +0 -0
  60. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/visualizer/mplnotebookvisualizer.py +0 -0
  61. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/visualizer/mplvisualizer.py +0 -0
  62. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/visualizer/textvisualizer.py +0 -0
  63. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/visualizer/visualizer.py +0 -0
  64. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely.egg-info/dependency_links.txt +0 -0
  65. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely.egg-info/requires.txt +0 -0
  66. {nnodely-1.3.0 → nnodely-1.3.1}/nnodely.egg-info/top_level.txt +0 -0
  67. {nnodely-1.3.0 → nnodely-1.3.1}/pyproject.toml +0 -0
  68. {nnodely-1.3.0 → nnodely-1.3.1}/setup.cfg +0 -0
  69. {nnodely-1.3.0 → nnodely-1.3.1}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: nnodely
3
- Version: 1.3.0
3
+ Version: 1.3.1
4
4
  Summary: Model-structured neural network framework for the modeling and control of physical systems
5
5
  Author-email: Gastone Pietro Rosati Papini <tonegas@gmail.com>
6
6
  License: MIT License
@@ -51,7 +51,7 @@ Requires-Dist: onnxruntime
51
51
  [![Coverage Status](https://readthedocs.org/projects/nnodely/badge/?version=latest&style=default)](https://nnodely.readthedocs.io/en/latest/)
52
52
 
53
53
  <a name="readme-top"></a>
54
- ## Model-structured neural network framework for the modeling and control of physical systems
54
+ # Model-structured neural network framework for the modeling and control of physical systems
55
55
 
56
56
  Modeling, control, and estimation of physical systems are fundamental to a wide range of engineering applications.
57
57
  However, integrating data-driven methods like neural networks into these domains presents significant challenges,
@@ -62,7 +62,7 @@ MSNNs merge the flexibility of neural networks with structures grounded in physi
62
62
  providing a powerful tool for representing and managing complex physical systems. Moreover, a MSNN thanks to the reduced
63
63
  number of parameters needs fewer data for training and can be used in real-time applications.
64
64
 
65
- ### Why use nnodely
65
+ ## Why use nnodely
66
66
 
67
67
  The framework's goal is to allow the users fast modeling and control of a any mechanical systems using
68
68
  a hybrind approach between neural networks and physical models.
@@ -92,13 +92,13 @@ a Pytorch (nnodely independent) and ONNX export.
92
92
  <a href="#settingstarted">Getting Started</a>
93
93
  </li>
94
94
  <li>
95
- <a href="#basicfunctionalities">Basic Functionalities</a>
95
+ <a href="#basicfunctionalities">Basic Example</a>
96
96
  <ul>
97
- <li><a href="#structuredneuralmodel">Build the structured neural model</a></li>
98
- <li><a href="#neuralizemodel">Neuralize the structured neural model</a></li>
97
+ <li><a href="#structuredneuralmodel">Build the neural model</a></li>
98
+ <li><a href="#neuralizemodel">Neuralize the neural model</a></li>
99
99
  <li><a href="#loaddataset">Load the dataset</a></li>
100
- <li><a href="#trainmodel">Train the structured neural network</a></li>
101
- <li><a href="#testmodel">Test the structured neural model</a></li>
100
+ <li><a href="#trainmodel">Train the neural model</a></li>
101
+ <li><a href="#testmodel">Test the neural model</a></li>
102
102
  </ul>
103
103
  </li>
104
104
  <li>
@@ -109,15 +109,14 @@ a Pytorch (nnodely independent) and ONNX export.
109
109
  <li><a href="#examplesfolder">examples folder</a></li>
110
110
  </ul>
111
111
  </li>
112
- <li>
113
- <a href="#license">License</a>
114
- </li>
112
+ <li><a href="#license">License</a></li>
113
+ <li><a href="#references">References</a></li>
115
114
  </ol>
116
115
  </details>
117
116
 
118
117
  <!-- GETTING STARTED -->
119
118
  <a name="settingstarted"></a>
120
- ### Getting Started
119
+ ## Getting Started
121
120
  You can install the nnodely framework from PyPI via:
122
121
  ```sh
123
122
  pip install nnodely
@@ -191,7 +190,7 @@ Our formulation is more general and can take into account the noise of the measu
191
190
  The estimator can also be seen as the composition of the force contributions due to the position and velocity of the mass plus the contribution of external forces.
192
191
 
193
192
  <a name="neuralizemodel"></a>
194
- ### Neuralize the structured neural model
193
+ ### Neuralize the neural model
195
194
  Let's now try to train our observer using the data we have.
196
195
  We perform:
197
196
  ```python
@@ -233,7 +232,7 @@ mass_spring_damper.loadData(name='mass_spring_dataset', source=data_folder, form
233
232
  Finally, the dataset is loaded. **nnodely** loads all the files that are in a source folder.
234
233
 
235
234
  <a name="trainmodel"></a>
236
- ### Train the structured neural network
235
+ ### Train the neural network
237
236
  Using the dataset created the training is performed on the model.
238
237
 
239
238
  ```python
@@ -241,7 +240,7 @@ mass_spring_damper.trainModel()
241
240
  ```
242
241
 
243
242
  <a name="testmodel"></a>
244
- ### Test the structured neural model
243
+ ### Test the neural model
245
244
  In order to test the results we need to create a input, in this case is defined by:
246
245
  1. `x` with 5 sample because the sample time is 0.2 and the window of `x`is 1 second.
247
246
  2. `F` is one sample because only the last sample is needed.
@@ -329,6 +328,7 @@ This project is released under the license [License: MIT](https://opensource.org
329
328
 
330
329
  <p align="right">(<a href="#readme-top">back to top</a>)</p>
331
330
 
331
+ <a name="references"></a>
332
332
  ## References
333
333
  <a id="1">[1]</a>
334
334
  Mauro Da Lio, Daniele Bortoluzzi, Gastone Pietro Rosati Papini. (2019).
@@ -360,3 +360,5 @@ and [[code extended]](https://github.com/tonegas/nnodely-applications/blob/main/
360
360
  Hector Perez-Villeda, Justus Piater, Matteo Saveriano. (2023).
361
361
  Learning and extrapolation of robotic skills using task-parameterized equation learner networks.
362
362
  Robotics and Autonomous Systems. https://doi.org/10.1016/j.robot.2022.104309
363
+
364
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
@@ -7,7 +7,7 @@
7
7
  [![Coverage Status](https://readthedocs.org/projects/nnodely/badge/?version=latest&style=default)](https://nnodely.readthedocs.io/en/latest/)
8
8
 
9
9
  <a name="readme-top"></a>
10
- ## Model-structured neural network framework for the modeling and control of physical systems
10
+ # Model-structured neural network framework for the modeling and control of physical systems
11
11
 
12
12
  Modeling, control, and estimation of physical systems are fundamental to a wide range of engineering applications.
13
13
  However, integrating data-driven methods like neural networks into these domains presents significant challenges,
@@ -18,7 +18,7 @@ MSNNs merge the flexibility of neural networks with structures grounded in physi
18
18
  providing a powerful tool for representing and managing complex physical systems. Moreover, a MSNN thanks to the reduced
19
19
  number of parameters needs fewer data for training and can be used in real-time applications.
20
20
 
21
- ### Why use nnodely
21
+ ## Why use nnodely
22
22
 
23
23
  The framework's goal is to allow the users fast modeling and control of a any mechanical systems using
24
24
  a hybrind approach between neural networks and physical models.
@@ -48,13 +48,13 @@ a Pytorch (nnodely independent) and ONNX export.
48
48
  <a href="#settingstarted">Getting Started</a>
49
49
  </li>
50
50
  <li>
51
- <a href="#basicfunctionalities">Basic Functionalities</a>
51
+ <a href="#basicfunctionalities">Basic Example</a>
52
52
  <ul>
53
- <li><a href="#structuredneuralmodel">Build the structured neural model</a></li>
54
- <li><a href="#neuralizemodel">Neuralize the structured neural model</a></li>
53
+ <li><a href="#structuredneuralmodel">Build the neural model</a></li>
54
+ <li><a href="#neuralizemodel">Neuralize the neural model</a></li>
55
55
  <li><a href="#loaddataset">Load the dataset</a></li>
56
- <li><a href="#trainmodel">Train the structured neural network</a></li>
57
- <li><a href="#testmodel">Test the structured neural model</a></li>
56
+ <li><a href="#trainmodel">Train the neural model</a></li>
57
+ <li><a href="#testmodel">Test the neural model</a></li>
58
58
  </ul>
59
59
  </li>
60
60
  <li>
@@ -65,15 +65,14 @@ a Pytorch (nnodely independent) and ONNX export.
65
65
  <li><a href="#examplesfolder">examples folder</a></li>
66
66
  </ul>
67
67
  </li>
68
- <li>
69
- <a href="#license">License</a>
70
- </li>
68
+ <li><a href="#license">License</a></li>
69
+ <li><a href="#references">References</a></li>
71
70
  </ol>
72
71
  </details>
73
72
 
74
73
  <!-- GETTING STARTED -->
75
74
  <a name="settingstarted"></a>
76
- ### Getting Started
75
+ ## Getting Started
77
76
  You can install the nnodely framework from PyPI via:
78
77
  ```sh
79
78
  pip install nnodely
@@ -147,7 +146,7 @@ Our formulation is more general and can take into account the noise of the measu
147
146
  The estimator can also be seen as the composition of the force contributions due to the position and velocity of the mass plus the contribution of external forces.
148
147
 
149
148
  <a name="neuralizemodel"></a>
150
- ### Neuralize the structured neural model
149
+ ### Neuralize the neural model
151
150
  Let's now try to train our observer using the data we have.
152
151
  We perform:
153
152
  ```python
@@ -189,7 +188,7 @@ mass_spring_damper.loadData(name='mass_spring_dataset', source=data_folder, form
189
188
  Finally, the dataset is loaded. **nnodely** loads all the files that are in a source folder.
190
189
 
191
190
  <a name="trainmodel"></a>
192
- ### Train the structured neural network
191
+ ### Train the neural network
193
192
  Using the dataset created the training is performed on the model.
194
193
 
195
194
  ```python
@@ -197,7 +196,7 @@ mass_spring_damper.trainModel()
197
196
  ```
198
197
 
199
198
  <a name="testmodel"></a>
200
- ### Test the structured neural model
199
+ ### Test the neural model
201
200
  In order to test the results we need to create a input, in this case is defined by:
202
201
  1. `x` with 5 sample because the sample time is 0.2 and the window of `x`is 1 second.
203
202
  2. `F` is one sample because only the last sample is needed.
@@ -285,6 +284,7 @@ This project is released under the license [License: MIT](https://opensource.org
285
284
 
286
285
  <p align="right">(<a href="#readme-top">back to top</a>)</p>
287
286
 
287
+ <a name="references"></a>
288
288
  ## References
289
289
  <a id="1">[1]</a>
290
290
  Mauro Da Lio, Daniele Bortoluzzi, Gastone Pietro Rosati Papini. (2019).
@@ -315,4 +315,6 @@ and [[code extended]](https://github.com/tonegas/nnodely-applications/blob/main/
315
315
  <a id="6">[6]</a>
316
316
  Hector Perez-Villeda, Justus Piater, Matteo Saveriano. (2023).
317
317
  Learning and extrapolation of robotic skills using task-parameterized equation learner networks.
318
- Robotics and Autonomous Systems. https://doi.org/10.1016/j.robot.2022.104309
318
+ Robotics and Autonomous Systems. https://doi.org/10.1016/j.robot.2022.104309
319
+
320
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
@@ -1,5 +1,5 @@
1
1
 
2
- __version__ = '1.3.0'
2
+ __version__ = '1.3.1'
3
3
 
4
4
  import sys
5
5
  major, minor = sys.version_info.major, sys.version_info.minor
@@ -85,17 +85,17 @@ class Identity(Stream, ToStream):
85
85
 
86
86
  class Softmax(Stream, ToStream):
87
87
  """
88
- Implement the Softmax relation function.
88
+ Implement the Softmax relation function.
89
89
 
90
- See also:
91
- Official PyTorch Softmax documentation:
92
- `torch.nn.Softmax <https://pytorch.org/docs/stable/generated/torch.nn.Softmax.html>`_
90
+ See also:
91
+ Official PyTorch Softmax documentation:
92
+ `torch.nn.Softmax <https://pytorch.org/docs/stable/generated/torch.nn.Softmax.html>`_
93
93
 
94
- :param obj: The relation stream.
95
- :type obj: Stream
94
+ :param obj: The relation stream.
95
+ :type obj: Stream
96
96
 
97
- Example:
98
- >>> x = Softmax(x)
97
+ Example:
98
+ >>> x = Softmax(x)
99
99
  """
100
100
  @enforce_types
101
101
  def __init__(self, obj:Stream|Parameter|Constant|float|int) -> Stream:
@@ -106,22 +106,23 @@ class Softmax(Stream, ToStream):
106
106
  self.json['Relations'][self.name] = [softmax_relation_name, [obj.name]]
107
107
 
108
108
  class Sigmoid(Stream, ToStream):
109
- """
110
- Implement the Sigmoid relation function.
111
- The Sigmoid function is defined as:
109
+ r"""
110
+ Implement the Sigmoid relation function.
111
+ The Sigmoid function is defined as:
112
112
 
113
- see also:
114
- Official PyTorch Softmax documentation:
115
- `Sigmoid function <https://pytorch.org/docs/stable/generated/torch.nn.Sigmoid.html#torch.nn.Sigmoid>`_
113
+ see also:
114
+ Official PyTorch Softmax documentation:
115
+ `Sigmoid function <https://pytorch.org/docs/stable/generated/torch.nn.Sigmoid.html#torch.nn.Sigmoid>`_
116
116
 
117
- :math:
118
- \sigma(x) = \frac{1}{1 + e^{-x}}
117
+ .. math::
119
118
 
120
- :param obj: The relation stream.
121
- :type obj: Stream
119
+ \sigma(x) = \frac{1}{1 + e^{-x}}
122
120
 
123
- Example:
124
- >>> x = Sigmoid(x)
121
+ :param obj: The relation stream.
122
+ :type obj: Stream
123
+
124
+ Example:
125
+ >>> x = Sigmoid(x)
125
126
  """
126
127
  @enforce_types
127
128
  def __init__(self, obj:Stream|Parameter|Constant|float|int) -> Stream:
@@ -131,8 +131,8 @@ class Pow(Stream, ToStream):
131
131
  (it is also possible to use the classical math operator '**')
132
132
 
133
133
  See also:
134
- Official PyTorch Add documentation:
135
- `torch.add <https://pytorch.org/docs/stable/generated/torch.pow.html>`_
134
+ Official PyTorch pow documentation:
135
+ `torch.pow <https://pytorch.org/docs/stable/generated/torch.pow.html>`_
136
136
 
137
137
  :param input: the base of the power function
138
138
  :type obj: Tensor
@@ -7,8 +7,8 @@ def init_constant(indexes, params_size, dict_param = {'value':1}):
7
7
  ----------
8
8
  dict_param : dict, optional
9
9
  Dictionary containing the initialization parameters. Default is {'value': 1}.
10
- - value : int or float
11
- The constant value to initialize the parameters with.
10
+ value : int or float
11
+ The constant value to initialize the parameters with.
12
12
  """
13
13
  return dict_param['value']
14
14
 
@@ -24,12 +24,12 @@ def init_negexp(indexes, params_size, dict_param = {'size_index':0, 'first_value
24
24
  List of sizes for each dimension of the parameters.
25
25
  dict_param : dict, optional
26
26
  Dictionary containing the initialization parameters. Default is {'size_index': 0, 'first_value': 1, 'lambda': 3}.
27
- - size_index : int
28
- The index of the dimension to apply the exponential function.
29
- - first_value : int or float
30
- The value at the start of the range.
31
- - lambda : int or float
32
- The decay rate parameter of the exponential function.
27
+ size_index : int
28
+ The index of the dimension to apply the exponential function.
29
+ first_value : int or float
30
+ The value at the start of the range.
31
+ lambda : int or float
32
+ The decay rate parameter of the exponential function.
33
33
  """
34
34
  import numpy as np
35
35
  size_index = dict_param['size_index']
@@ -49,14 +49,14 @@ def init_exp(indexes, params_size, dict_param = {'size_index':0, 'max_value':1,
49
49
  List of sizes for each dimension of the parameters.
50
50
  dict_param : dict, optional
51
51
  Dictionary containing the initialization parameters. Default is {'size_index': 0, 'max_value': 1, 'lambda': 3, 'monotonicity': 'decreasing'}.
52
- - size_index : int
53
- The index of the dimension to apply the exponential function.
54
- - max_value : int or float
55
- The maximum value of the exponential function.
56
- - lambda : int or float
57
- The rate parameter of the exponential function.
58
- - monotonicity : str
59
- The monotonicity of the exponential function. Can be 'increasing' or 'decreasing'.
52
+ size_index : int
53
+ The index of the dimension to apply the exponential function.
54
+ max_value : int or float
55
+ The maximum value of the exponential function.
56
+ lambda : int or float
57
+ The rate parameter of the exponential function.
58
+ monotonicity : str
59
+ The monotonicity of the exponential function. Can be 'increasing' or 'decreasing'.
60
60
 
61
61
  Raises
62
62
  ------
@@ -90,12 +90,12 @@ def init_lin(indexes, params_size, dict_param = {'size_index':0, 'first_value':1
90
90
  List of sizes for each dimension of the parameters.
91
91
  dict_param : dict, optional
92
92
  Dictionary containing the initialization parameters. Default is {'size_index': 0, 'first_value': 1, 'last_value': 0}.
93
- - size_index : int
94
- The index of the dimension to apply the linear function.
95
- - first_value : int or float
96
- The value at the start of the range.
97
- - last_value : int or float
98
- The value at the end of the range.
93
+ size_index : int
94
+ The index of the dimension to apply the linear function.
95
+ first_value : int or float
96
+ The value at the start of the range.
97
+ last_value : int or float
98
+ The value at the end of the range.
99
99
  """
100
100
  size_index = dict_param['size_index']
101
101
  x = 0 if params_size[size_index]-1 == 0 else indexes[size_index]/(params_size[size_index]-1)
@@ -112,19 +112,17 @@ class InputState(NeuObj):
112
112
 
113
113
  Examples
114
114
  --------
115
- Select a sample window considering a signal T = [-3,-2,-1,0,1,2] where the time vector 0 represent the last passed instant
116
- If sw is an integer #1 represent the number of step in the past
117
- T.s(2) = [-1, 0] # represents two sample step in the past
115
+ Select a sample window considering a signal T = [-3,-2,-1,0,1,2] where the time vector 0 represent the last passed instant. If sw is an integer #1 represent the number of step in the past
116
+ >>> T.s(2) #= [-1, 0] represents two sample step in the past
118
117
 
119
118
  If sw is a list [#1,#2] the numbers represent the sample indexes in the vector with the second element excluded
120
- T.s([-2,0]) = [-1, 0] # represents two time step in the past zero in the future
121
- T.s([0,1]) = [1] # the first time in the future
122
- T.s([-4,-2]) = [-3,-2]
123
-
124
- The total number of samples can be computed #2-#1
125
- The offset represent the index of the vector that need to be used to offset the window
126
- T.s(2,offset=-2) = [0, 1] # the value of the window is [-1,0]
127
- T.s([-2,2],offset=-1) = [-1,0,1,2] # the value of the window is [-1,0,1,2]
119
+ >>> T.s([-2,0]) #= [-1, 0] represents two time step in the past zero in the future
120
+ >>> T.s([0,1]) #= [1] the first time in the future
121
+ >>> T.s([-4,-2]) #= [-3,-2]
122
+
123
+ The total number of samples can be computed #2-#1. The offset represent the index of the vector that need to be used to offset the window
124
+ >>> T.s(2,offset=-2) #= [0, 1] the value of the window is [-1,0]
125
+ >>> T.s([-2,2],offset=-1) #= [-1,0,1,2] the value of the window is [-1,0,1,2]
128
126
  """
129
127
  dim = copy.deepcopy(self.dim)
130
128
  json = copy.deepcopy(self.json)
@@ -1875,9 +1875,8 @@ class Modely:
1875
1875
  """
1876
1876
  Exports the neural network model to an ONNX file.
1877
1877
 
1878
- -----
1879
1878
  .. note::
1880
- The input_order must contain all the inputs and states of the model in the order that you want to export them.
1879
+ The input_order may contain all the inputs and states of the model in the order that you want to export them.
1881
1880
 
1882
1881
  Parameters
1883
1882
  ----------
@@ -1932,7 +1931,6 @@ class Modely:
1932
1931
  """
1933
1932
  Run an inference session using an onnx model previously exported using the nnodely framework.
1934
1933
 
1935
- -----
1936
1934
  .. note:: Feed-Forward ONNX model
1937
1935
  For feed-forward models, the onnx model expect all the inputs and states to have 3 dimensions. The first dimension is the batch size, the second is the time window and the third is the feature dimension.
1938
1936
  .. note:: Recurrent ONNX model
@@ -109,6 +109,9 @@ class Relation():
109
109
  return Neg(self)
110
110
 
111
111
  class Stream(Relation):
112
+ """
113
+ Represents a stream of data inside the neural network. A Stream is automatically create when you operate over a Input, State, Parameter, or Constant object.
114
+ """
112
115
  count = 0
113
116
  @classmethod
114
117
  def resetCount(self):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: nnodely
3
- Version: 1.3.0
3
+ Version: 1.3.1
4
4
  Summary: Model-structured neural network framework for the modeling and control of physical systems
5
5
  Author-email: Gastone Pietro Rosati Papini <tonegas@gmail.com>
6
6
  License: MIT License
@@ -51,7 +51,7 @@ Requires-Dist: onnxruntime
51
51
  [![Coverage Status](https://readthedocs.org/projects/nnodely/badge/?version=latest&style=default)](https://nnodely.readthedocs.io/en/latest/)
52
52
 
53
53
  <a name="readme-top"></a>
54
- ## Model-structured neural network framework for the modeling and control of physical systems
54
+ # Model-structured neural network framework for the modeling and control of physical systems
55
55
 
56
56
  Modeling, control, and estimation of physical systems are fundamental to a wide range of engineering applications.
57
57
  However, integrating data-driven methods like neural networks into these domains presents significant challenges,
@@ -62,7 +62,7 @@ MSNNs merge the flexibility of neural networks with structures grounded in physi
62
62
  providing a powerful tool for representing and managing complex physical systems. Moreover, a MSNN thanks to the reduced
63
63
  number of parameters needs fewer data for training and can be used in real-time applications.
64
64
 
65
- ### Why use nnodely
65
+ ## Why use nnodely
66
66
 
67
67
  The framework's goal is to allow the users fast modeling and control of a any mechanical systems using
68
68
  a hybrind approach between neural networks and physical models.
@@ -92,13 +92,13 @@ a Pytorch (nnodely independent) and ONNX export.
92
92
  <a href="#settingstarted">Getting Started</a>
93
93
  </li>
94
94
  <li>
95
- <a href="#basicfunctionalities">Basic Functionalities</a>
95
+ <a href="#basicfunctionalities">Basic Example</a>
96
96
  <ul>
97
- <li><a href="#structuredneuralmodel">Build the structured neural model</a></li>
98
- <li><a href="#neuralizemodel">Neuralize the structured neural model</a></li>
97
+ <li><a href="#structuredneuralmodel">Build the neural model</a></li>
98
+ <li><a href="#neuralizemodel">Neuralize the neural model</a></li>
99
99
  <li><a href="#loaddataset">Load the dataset</a></li>
100
- <li><a href="#trainmodel">Train the structured neural network</a></li>
101
- <li><a href="#testmodel">Test the structured neural model</a></li>
100
+ <li><a href="#trainmodel">Train the neural model</a></li>
101
+ <li><a href="#testmodel">Test the neural model</a></li>
102
102
  </ul>
103
103
  </li>
104
104
  <li>
@@ -109,15 +109,14 @@ a Pytorch (nnodely independent) and ONNX export.
109
109
  <li><a href="#examplesfolder">examples folder</a></li>
110
110
  </ul>
111
111
  </li>
112
- <li>
113
- <a href="#license">License</a>
114
- </li>
112
+ <li><a href="#license">License</a></li>
113
+ <li><a href="#references">References</a></li>
115
114
  </ol>
116
115
  </details>
117
116
 
118
117
  <!-- GETTING STARTED -->
119
118
  <a name="settingstarted"></a>
120
- ### Getting Started
119
+ ## Getting Started
121
120
  You can install the nnodely framework from PyPI via:
122
121
  ```sh
123
122
  pip install nnodely
@@ -191,7 +190,7 @@ Our formulation is more general and can take into account the noise of the measu
191
190
  The estimator can also be seen as the composition of the force contributions due to the position and velocity of the mass plus the contribution of external forces.
192
191
 
193
192
  <a name="neuralizemodel"></a>
194
- ### Neuralize the structured neural model
193
+ ### Neuralize the neural model
195
194
  Let's now try to train our observer using the data we have.
196
195
  We perform:
197
196
  ```python
@@ -233,7 +232,7 @@ mass_spring_damper.loadData(name='mass_spring_dataset', source=data_folder, form
233
232
  Finally, the dataset is loaded. **nnodely** loads all the files that are in a source folder.
234
233
 
235
234
  <a name="trainmodel"></a>
236
- ### Train the structured neural network
235
+ ### Train the neural network
237
236
  Using the dataset created the training is performed on the model.
238
237
 
239
238
  ```python
@@ -241,7 +240,7 @@ mass_spring_damper.trainModel()
241
240
  ```
242
241
 
243
242
  <a name="testmodel"></a>
244
- ### Test the structured neural model
243
+ ### Test the neural model
245
244
  In order to test the results we need to create a input, in this case is defined by:
246
245
  1. `x` with 5 sample because the sample time is 0.2 and the window of `x`is 1 second.
247
246
  2. `F` is one sample because only the last sample is needed.
@@ -329,6 +328,7 @@ This project is released under the license [License: MIT](https://opensource.org
329
328
 
330
329
  <p align="right">(<a href="#readme-top">back to top</a>)</p>
331
330
 
331
+ <a name="references"></a>
332
332
  ## References
333
333
  <a id="1">[1]</a>
334
334
  Mauro Da Lio, Daniele Bortoluzzi, Gastone Pietro Rosati Papini. (2019).
@@ -360,3 +360,5 @@ and [[code extended]](https://github.com/tonegas/nnodely-applications/blob/main/
360
360
  Hector Perez-Villeda, Justus Piater, Matteo Saveriano. (2023).
361
361
  Learning and extrapolation of robotic skills using task-parameterized equation learner networks.
362
362
  Robotics and Autonomous Systems. https://doi.org/10.1016/j.robot.2022.104309
363
+
364
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
@@ -50,6 +50,7 @@ nnodely/visualizer/dynamicmpl/fuzzyplot.py
50
50
  nnodely/visualizer/dynamicmpl/resultsplot.py
51
51
  nnodely/visualizer/dynamicmpl/trainingplot.py
52
52
  tests/test_dataset.py
53
+ tests/test_documentation.py
53
54
  tests/test_export.py
54
55
  tests/test_export_recurrent.py
55
56
  tests/test_input_dimensions.py
@@ -598,8 +598,4 @@ class ModelyCreateDatasetTest(unittest.TestCase):
598
598
  test.loadData(name='dataset', source=data_folder, format=data_struct, skiplines=1, delimiter=' ')
599
599
  self.assertListEqual(list(test.data['dataset']['x'].shape), [42, 6, 1])
600
600
  self.assertListEqual(list(test.data['dataset']['y'].shape), [42, 4, 1])
601
- self.assertListEqual(test.multifile['dataset'], [4, 18, 42])
602
-
603
-
604
- if __name__ == '__main__':
605
- unittest.main()
601
+ self.assertListEqual(test.multifile['dataset'], [4, 18, 42])
@@ -0,0 +1,25 @@
1
+ import unittest
2
+ import subprocess
3
+ import os
4
+
5
+ class TestDocumentation(unittest.TestCase):
6
+ def test_generate_docs(self):
7
+ # Path to the Sphinx documentation source directory
8
+ docs_source_dir = os.path.join(os.path.dirname(__file__), '..', 'docs')
9
+
10
+ # Path to the output directory for the generated documentation
11
+ docs_output_dir = os.path.join(docs_source_dir, '_build', 'html')
12
+
13
+ # Command to generate the documentation
14
+ command = ['sphinx-build', '--fail-on-warning', '-b', 'html', docs_source_dir, docs_output_dir]
15
+
16
+ # Run the command and capture the output
17
+ result = subprocess.run(command, capture_output=True, text=True)
18
+
19
+ # Check if the command was successful
20
+ self.assertEqual(result.returncode, 0, f"Documentation generation failed: {result.stderr}")
21
+
22
+ # Optionally, check if the output directory contains the expected files
23
+ self.assertTrue(os.path.exists(docs_output_dir), "Output directory does not exist")
24
+ self.assertTrue(os.path.isfile(os.path.join(docs_output_dir, 'index.html')),
25
+ "index.html not found in output directory")
@@ -328,9 +328,4 @@ class ModelyExportTest(unittest.TestCase):
328
328
  self.test.exportReport()
329
329
 
330
330
  if os.path.exists(self.test.getWorkspace()):
331
- shutil.rmtree(self.test.getWorkspace())
332
-
333
- if __name__ == '__main__':
334
- unittest.main()
335
-
336
-
331
+ shutil.rmtree(self.test.getWorkspace())
@@ -567,7 +567,4 @@ class ModelyExportTest(unittest.TestCase):
567
567
  if os.path.exists(test.getWorkspace()):
568
568
  shutil.rmtree(test.getWorkspace())
569
569
 
570
- if __name__ == '__main__':
571
- unittest.main()
572
-
573
570
 
@@ -436,5 +436,3 @@ class ModelyNetworkBuildingTest(unittest.TestCase):
436
436
  ## Clip the step to 0
437
437
  test.trainModel(train_dataset='dataset', num_of_epochs=1, train_batch_size=10, step=-4, prediction_samples=20, shuffle_data=True)
438
438
  self.assertEqual(8 * 21, len(test.internals.keys()))
439
- if __name__ == '__main__':
440
- unittest.main()
@@ -626,5 +626,3 @@ class ModelyJsonTest(unittest.TestCase):
626
626
  self.assertEqual((1, 1, 3), np.array(results['out51']).shape)
627
627
 
628
628
 
629
- if __name__ == '__main__':
630
- unittest.main()
@@ -168,7 +168,4 @@ class ModelyTrainingTest(unittest.TestCase):
168
168
  # pass
169
169
 
170
170
  # def test_analysis_results_connect_state(self):
171
- # pass
172
-
173
- if __name__ == '__main__':
174
- unittest.main()
171
+ # pass
@@ -299,7 +299,7 @@ class ModelyPredictTest(unittest.TestCase):
299
299
  #[[0, 5], [1, 2], [2, 7], [3, 3]] * [[-1, -3], [0, 0], [1, -3], [2, 2]]
300
300
  self.assertEqual((2,4,2), np.array(results['mul2']).shape)
301
301
  self.TestAlmostEqual([[[1, 2], [0, 0], [1, 6], [4, 0]],[[0, -15], [0, 0], [2, -21], [6, 6]]], results['mul2'])
302
-
302
+
303
303
  def test_single_in_window_offset_fir(self):
304
304
  NeuObj.clearNames()
305
305
  # The input must be scalar and the time dimension is compress to 1,
@@ -865,36 +865,37 @@ class ModelyPredictTest(unittest.TestCase):
865
865
  def test_initialization(self):
866
866
  NeuObj.clearNames()
867
867
  input = Input('in1')
868
- W = Parameter('W', dimensions=(1,1), init=init_constant)
869
- b = Parameter('b', dimensions=1, init=init_constant)
868
+ W = Parameter('W', dimensions=(1,1), init='init_constant')
869
+ b = Parameter('b', dimensions=1, init='init_constant')
870
870
  o = Output('out', Linear(W=W,b=b)(input.last()))
871
871
 
872
- W5 = Parameter('W5', dimensions=(1,1), init=init_constant, init_params={'value':5})
873
- b2 = Parameter('b2', dimensions=1, init=init_constant, init_params={'value':2})
872
+ W5 = Parameter('W5', dimensions=(1,1), init='init_constant', init_params={'value':5})
873
+ b2 = Parameter('b2', dimensions=1, init='init_constant', init_params={'value':2})
874
874
  o52 = Output('out52', Linear(W=W5,b=b2)(input.last()))
875
875
 
876
- par = Parameter('par', dimensions=3, sw=2, init=init_constant)
876
+ par = Parameter('par', dimensions=3, sw=2, init='init_constant')
877
877
  opar = Output('outpar', Fir(W=par)(input.sw(2)))
878
878
 
879
- par2 = Parameter('par2', dimensions=3, sw=2, init=init_constant, init_params={'value':2})
879
+ par2 = Parameter('par2', dimensions=3, sw=2, init='init_constant', init_params={'value':2})
880
880
  opar2 = Output('outpar2', Fir(W=par2)(input.sw(2)))
881
881
 
882
- ol = Output('outl', Linear(output_dimension=1,b=True,W_init=init_constant,b_init=init_constant)(input.last()))
883
- ol52 = Output('outl52', Linear(output_dimension=1,b=True,W_init=init_constant,b_init=init_constant,W_init_params={'value':5},b_init_params={'value':2})(input.last()))
884
- ofpar = Output('outfpar', Fir(output_dimension=3,W_init=init_constant)(input.sw(2)))
885
- ofpar2 = Output('outfpar2', Fir(output_dimension=3,W_init=init_constant,W_init_params={'value':2})(input.sw(2)))
882
+ ol = Output('outl', Linear(output_dimension=1,b=True,W_init='init_constant',b_init='init_constant')(input.last()))
883
+ ol52 = Output('outl52', Linear(output_dimension=1,b=True,W_init='init_constant',b_init='init_constant',W_init_params={'value':5},b_init_params={'value':2})(input.last()))
884
+ ofpar = Output('outfpar', Fir(output_dimension=3,W_init='init_constant')(input.sw(2)))
885
+ ofpar2 = Output('outfpar2', Fir(output_dimension=3,W_init='init_constant',W_init_params={'value':2})(input.sw(2)))
886
886
 
887
- outnegexp = Output('outnegexp', Fir(output_dimension=3,W_init=init_negexp)(input.sw(2)))
888
- outnegexp2 = Output('outnegexp2', Fir(output_dimension=3,W_init=init_negexp,W_init_params={'size_index':1, 'first_value':3, 'lambda':1})(input.sw(2)))
887
+ outnegexp = Output('outnegexp', Fir(output_dimension=3,W_init='init_negexp')(input.sw(2)))
888
+ outnegexp2 = Output('outnegexp2', Fir(output_dimension=3,W_init='init_negexp',W_init_params={'size_index':1, 'first_value':3, 'lambda':1})(input.sw(2)))
889
889
 
890
- outexp = Output('outexp', Fir(output_dimension=3,W_init=init_exp)(input.sw(2)))
891
- outexp2 = Output('outexp2', Fir(output_dimension=3,W_init=init_exp,W_init_params={'size_index':1, 'max_value':2, 'lambda':2, 'monotonicity':'increasing'})(input.sw(2)))
890
+ outexp = Output('outexp', Fir(output_dimension=3,W_init='init_exp')(input.sw(2)))
891
+ outexp2 = Output('outexp2', Fir(output_dimension=3,W_init='init_exp',W_init_params={'size_index':1, 'max_value':2, 'lambda':2, 'monotonicity':'increasing'})(input.sw(2)))
892
+ outexp2D = Output('outexp2D', Fir(output_dimension=3,W_init='init_exp',W_init_params={'size_index':1, 'max_value':2, 'lambda':2, 'monotonicity':'decreasing'})(input.sw(2)))
892
893
 
893
- outlin = Output('outlin', Fir(output_dimension=3,W_init=init_lin)(input.sw(2)))
894
- outlin2 = Output('outlin2', Fir(output_dimension=3,W_init=init_lin,W_init_params={'size_index':1, 'first_value':4, 'last_value':5})(input.sw(2)))
894
+ outlin = Output('outlin', Fir(output_dimension=3,W_init='init_lin')(input.sw(2)))
895
+ outlin2 = Output('outlin2', Fir(output_dimension=3,W_init='init_lin',W_init_params={'size_index':1, 'first_value':4, 'last_value':5})(input.sw(2)))
895
896
 
896
897
  n = Modely(visualizer=None,seed=1)
897
- n.addModel('model',[o,o52,opar,opar2,ol,ol52,ofpar,ofpar2,outnegexp,outnegexp2,outexp,outexp2,outlin,outlin2])
898
+ n.addModel('model',[o,o52,opar,opar2,ol,ol52,ofpar,ofpar2,outnegexp,outnegexp2,outexp,outexp2,outexp2D,outlin,outlin2])
898
899
  n.neuralizeModel()
899
900
  results = n({'in1': [1, 1, 2]})
900
901
  self.assertEqual((2,), np.array(results['out']).shape)
@@ -926,6 +927,8 @@ class ModelyPredictTest(unittest.TestCase):
926
927
  self.TestAlmostEqual([[[1.0497870445251465,1.0497870445251465,1.0497870445251465]],[[1.099574089050293,1.099574089050293,1.099574089050293]]], results['outexp'])
927
928
  self.assertEqual((2,1,3), np.array(results['outexp2']).shape)
928
929
  self.TestAlmostEqual([[[0.5413411259651184,1.47151780128479,4]],[[0.81201171875,2.2072768211364746,6]]], results['outexp2'])
930
+ self.assertEqual((2,1,3), np.array(results['outexp2D']).shape)
931
+ self.TestAlmostEqual([[[4.0,1.47151780128479,0.5413411259651184]],[[6,2.2072768211364746,0.81201171875]]], results['outexp2D'])
929
932
 
930
933
  self.assertEqual((2,1,3), np.array(results['outlin']).shape)
931
934
  self.TestAlmostEqual([[[1,1,1]],[[1,1,1]]], results['outlin'])
@@ -1370,6 +1373,20 @@ class ModelyPredictTest(unittest.TestCase):
1370
1373
  self.assertEqual((3, 1, 6), np.array(results['out']).shape)
1371
1374
  self.assertEqual([[[1.0, 0.0, 0.0, 0.0, 0.0, 0.0]],[[0.0, 1.0, 0.0, 0.0, 0.0, 0.0]],[[0.0, 0.0, 1.0, 0.0, 0.0, 0.0]]], results['out'])
1372
1375
 
1376
+ def fun(x):
1377
+ import torch
1378
+ return torch.sign(x)
1379
+
1380
+ fuz = Fuzzify(output_dimension=11, range=[-5, 5], functions=[fun,fun])(input.last())
1381
+ out = Output('out2', fuz)
1382
+ test.addModel('out2',[out])
1383
+ test.neuralizeModel()
1384
+ results = test({'in1': [0, 1, 2]})
1385
+ self.assertEqual((3, 1, 11), np.array(results['out2']).shape)
1386
+ self.assertEqual([[[1.0, 1.0, 1.0, 1.0, 1.0, 0.0, -1.0, -1.0, -1.0, -1.0, -1.0]],
1387
+ [[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, -1.0, -1.0, -1.0, -1.0]],
1388
+ [[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, -1.0, -1.0, -1.0]]], results['out2'])
1389
+
1373
1390
  def test_sw_on_stream_sw_by_heand(self):
1374
1391
  NeuObj.clearNames()
1375
1392
  input = Input('in1')
@@ -1818,7 +1835,3 @@ class ModelyPredictTest(unittest.TestCase):
1818
1835
  self.TestAlmostEqual(results['in1_sm2'], inin_sm2)
1819
1836
  self.TestAlmostEqual(results['in1_sm2_2'], inin_sm2)
1820
1837
  self.TestAlmostEqual(results['in1_sm2_3'], inin_sm2)
1821
-
1822
- if __name__ == '__main__':
1823
- unittest.main()
1824
-
@@ -1239,7 +1239,3 @@ class ModelyRecurrentPredictTest(unittest.TestCase):
1239
1239
  self.assertEqual((5,), np.array(result['out']).shape)
1240
1240
  self.assertEqual([14.0,3*14+2*3+2*1,50*3+14*2+3*1,181*3+50*2+14*1,0*3+0*2+5*1], result['out'])
1241
1241
 
1242
-
1243
- if __name__ == '__main__':
1244
- unittest.main()
1245
-
@@ -443,7 +443,3 @@ class ModelyNetworkBuildingTest(unittest.TestCase):
443
443
  # The output is 2 samples
444
444
  self.assertEqual({'out': [1.7170718908309937, 1.9410502910614014]}, example({'x': [-1, 0, 1, 2, 0]}))
445
445
  self.assertEqual({'out': [1.7170718908309937, 1.9410502910614014]}, example({'x': [[-1, 0, 1, 2], [0, 1, 2, 0]]}, sampled=True))
446
-
447
-
448
- if __name__ == '__main__':
449
- unittest.main()
@@ -25,15 +25,6 @@ def linear_fun(x,a,b):
25
25
  return x*a+b
26
26
 
27
27
  class ModelyTrainingTestParameter(unittest.TestCase):
28
- def TestAlmostEqual(self, data1, data2, precision=4):
29
- assert np.asarray(data1, dtype=np.float32).ndim == np.asarray(data2, dtype=np.float32).ndim, f'Inputs must have the same dimension! Received {type(data1)} and {type(data2)}'
30
- if type(data1) == type(data2) == list:
31
- self.assertEqual(len(data1), len(data2))
32
- for pred, label in zip(data1, data2):
33
- self.TestAlmostEqual(pred, label, precision=precision)
34
- else:
35
- self.assertAlmostEqual(data1, data2, places=precision)
36
-
37
28
  def test_network_mass_spring_damper(self):
38
29
  NeuObj.clearNames()
39
30
  x = Input('x') # Position
@@ -18,15 +18,6 @@ sys.path.append(os.getcwd())
18
18
  data_folder = os.path.join(os.path.dirname(__file__), 'data/')
19
19
 
20
20
  class ModelyTrainingTest(unittest.TestCase):
21
- def TestAlmostEqual(self, data1, data2, precision=4):
22
- assert np.asarray(data1, dtype=np.float32).ndim == np.asarray(data2, dtype=np.float32).ndim, f'Inputs must have the same dimension! Received {type(data1)} and {type(data2)}'
23
- if type(data1) == type(data2) == list:
24
- self.assertEqual(len(data1), len(data2))
25
- for pred, label in zip(data1, data2):
26
- self.TestAlmostEqual(pred, label, precision=precision)
27
- else:
28
- self.assertAlmostEqual(data1, data2, places=precision)
29
-
30
21
  def test_analysis_results(self):
31
22
  NeuObj.clearNames()
32
23
  input1 = Input('in1')
@@ -308,12 +299,3 @@ class ModelyTrainingTest(unittest.TestCase):
308
299
  self.assertAlmostEqual((np.sum((np.array(A).flatten() - np.array(B).flatten()) ** 2) / 30.0 + np.sum(
309
300
  (np.array(C).flatten() - np.array(B).flatten()) ** 2) / 30.0) / 2.0,
310
301
  test.performance['dataset']['total']['mean_error'], places=3)
311
-
312
- # def test_analysis_results_connect(self):
313
- # pass
314
-
315
- # def test_analysis_results_connect_state(self):
316
- # pass
317
-
318
- if __name__ == '__main__':
319
- unittest.main()
@@ -16,15 +16,6 @@ sys.path.append(os.getcwd())
16
16
  data_folder = os.path.join(os.path.dirname(__file__), 'data/')
17
17
 
18
18
  class ModelyTrainingTest(unittest.TestCase):
19
- def TestAlmostEqual(self, data1, data2, precision=4):
20
- assert np.asarray(data1, dtype=np.float32).ndim == np.asarray(data2, dtype=np.float32).ndim, f'Inputs must have the same dimension! Received {type(data1)} and {type(data2)}'
21
- if type(data1) == type(data2) == list:
22
- self.assertEqual(len(data1), len(data2))
23
- for pred, label in zip(data1, data2):
24
- self.TestAlmostEqual(pred, label, precision=precision)
25
- else:
26
- self.assertAlmostEqual(data1, data2, places=precision)
27
-
28
19
  def test_training_values_fir(self):
29
20
  NeuObj.clearNames()
30
21
  input1 = Input('in1')
@@ -280,6 +271,3 @@ class ModelyTrainingTest(unittest.TestCase):
280
271
  ## Print the initial weights
281
272
  optimizer_defaults = {'weight_decay': 0.3,}
282
273
  example.trainModel(train_dataset='dataset', lr=0.01, num_of_epochs=2, optimizer_defaults=optimizer_defaults)
283
-
284
- if __name__ == '__main__':
285
- unittest.main()
@@ -1517,7 +1517,4 @@ class ModelyTrainingTest(unittest.TestCase):
1517
1517
  self.assertListEqual(test2.training['error1']['train'] , test.training['error1']['train'])
1518
1518
  self.assertListEqual(test2.training['error1']['val'], test.training['error1']['val'])
1519
1519
  self.assertListEqual(test2.training['error2']['train'] , test.training['error2']['train'])
1520
- self.assertListEqual(test2.training['error2']['val'], test.training['error2']['val'])
1521
-
1522
- if __name__ == '__main__':
1523
- unittest.main()
1520
+ self.assertListEqual(test2.training['error2']['val'], test.training['error2']['val'])
@@ -23,6 +23,3 @@ class ModelyTrainingTest(unittest.TestCase):
23
23
 
24
24
  y = linear_interp(x,x_data,y_data)
25
25
  self.assertEqual(y.shape, x.shape) # check that the output has the same shape as the input
26
-
27
- if __name__ == '__main__':
28
- unittest.main()
@@ -161,7 +161,4 @@ class ModelyTestVisualizer(unittest.TestCase):
161
161
  # test.loadData(name='dataset', source=dataset) # Create the dataset
162
162
  # test.trainModel(optimizer='SGD', training_params=params) # Train the traced model
163
163
  # m.showFunctions(list(test.model_def['Functions'].keys()), xlim=[[-5, 5], [-1, 1]])
164
- # m.closeFunctions()
165
-
166
- if __name__ == '__main__':
167
- unittest.main()
164
+ # m.closeFunctions()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes