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.
- {nnodely-1.3.0/nnodely.egg-info → nnodely-1.3.1}/PKG-INFO +17 -15
- {nnodely-1.3.0 → nnodely-1.3.1}/README.md +17 -15
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/__init__.py +1 -1
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/activation.py +21 -20
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/arithmetic.py +2 -2
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/initializer.py +22 -22
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/input.py +9 -11
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/nnodely.py +1 -3
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/relation.py +3 -0
- {nnodely-1.3.0 → nnodely-1.3.1/nnodely.egg-info}/PKG-INFO +17 -15
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely.egg-info/SOURCES.txt +1 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_dataset.py +1 -5
- nnodely-1.3.1/tests/test_documentation.py +25 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_export.py +1 -6
- {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_export_recurrent.py +0 -3
- {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_input_dimensions.py +0 -2
- {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_json.py +0 -2
- {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_losses.py +1 -4
- {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_model_predict.py +35 -22
- {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_model_predict_recurrent.py +0 -4
- {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_network_element.py +0 -4
- {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_parameters_of_train.py +0 -9
- {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_results.py +0 -18
- {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_train.py +0 -12
- {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_train_recurrent.py +1 -4
- {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_utils.py +0 -3
- {nnodely-1.3.0 → nnodely-1.3.1}/tests/test_visualizer.py +1 -4
- {nnodely-1.3.0 → nnodely-1.3.1}/LICENSE +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/mplplots/__init__.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/mplplots/plots.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/earlystopping.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/equationlearner.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/exporter/__init__.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/exporter/export.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/exporter/exporter.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/exporter/reporter.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/exporter/standardexporter.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/fir.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/fuzzify.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/interpolation.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/linear.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/localmodel.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/logger.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/loss.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/model.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/modeldef.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/optimizer.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/output.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/parameter.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/parametricfunction.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/part.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/timeoperation.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/trigonometric.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/utils.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/visualizer/__init__.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/visualizer/dynamicmpl/functionplot.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/visualizer/dynamicmpl/fuzzyplot.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/visualizer/dynamicmpl/resultsplot.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/visualizer/dynamicmpl/trainingplot.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/visualizer/mplnotebookvisualizer.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/visualizer/mplvisualizer.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/visualizer/textvisualizer.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely/visualizer/visualizer.py +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely.egg-info/dependency_links.txt +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely.egg-info/requires.txt +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/nnodely.egg-info/top_level.txt +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/pyproject.toml +0 -0
- {nnodely-1.3.0 → nnodely-1.3.1}/setup.cfg +0 -0
- {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.
|
|
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
|
[](https://nnodely.readthedocs.io/en/latest/)
|
|
52
52
|
|
|
53
53
|
<a name="readme-top"></a>
|
|
54
|
-
|
|
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
|
-
|
|
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
|
|
95
|
+
<a href="#basicfunctionalities">Basic Example</a>
|
|
96
96
|
<ul>
|
|
97
|
-
<li><a href="#structuredneuralmodel">Build the
|
|
98
|
-
<li><a href="#neuralizemodel">Neuralize the
|
|
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
|
|
101
|
-
<li><a href="#testmodel">Test the
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
[](https://nnodely.readthedocs.io/en/latest/)
|
|
8
8
|
|
|
9
9
|
<a name="readme-top"></a>
|
|
10
|
-
|
|
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
|
-
|
|
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
|
|
51
|
+
<a href="#basicfunctionalities">Basic Example</a>
|
|
52
52
|
<ul>
|
|
53
|
-
<li><a href="#structuredneuralmodel">Build the
|
|
54
|
-
<li><a href="#neuralizemodel">Neuralize the
|
|
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
|
|
57
|
-
<li><a href="#testmodel">Test the
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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>
|
|
@@ -85,17 +85,17 @@ class Identity(Stream, ToStream):
|
|
|
85
85
|
|
|
86
86
|
class Softmax(Stream, ToStream):
|
|
87
87
|
"""
|
|
88
|
-
|
|
88
|
+
Implement the Softmax relation function.
|
|
89
89
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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
|
-
|
|
95
|
-
|
|
94
|
+
:param obj: The relation stream.
|
|
95
|
+
:type obj: Stream
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
|
|
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
|
-
|
|
111
|
-
|
|
109
|
+
r"""
|
|
110
|
+
Implement the Sigmoid relation function.
|
|
111
|
+
The Sigmoid function is defined as:
|
|
112
112
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
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
|
-
|
|
118
|
-
\sigma(x) = \frac{1}{1 + e^{-x}}
|
|
117
|
+
.. math::
|
|
119
118
|
|
|
120
|
-
|
|
121
|
-
:type obj: Stream
|
|
119
|
+
\sigma(x) = \frac{1}{1 + e^{-x}}
|
|
122
120
|
|
|
123
|
-
|
|
124
|
-
|
|
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
|
|
135
|
-
`torch.
|
|
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
|
-
|
|
11
|
-
|
|
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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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
|
-
|
|
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])
|
|
121
|
-
T.s([0,1])
|
|
122
|
-
T.s([-4,-2])
|
|
123
|
-
|
|
124
|
-
The total number of samples can be computed #2-#1
|
|
125
|
-
|
|
126
|
-
T.s(2,offset=-
|
|
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
|
|
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.
|
|
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
|
[](https://nnodely.readthedocs.io/en/latest/)
|
|
52
52
|
|
|
53
53
|
<a name="readme-top"></a>
|
|
54
|
-
|
|
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
|
-
|
|
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
|
|
95
|
+
<a href="#basicfunctionalities">Basic Example</a>
|
|
96
96
|
<ul>
|
|
97
|
-
<li><a href="#structuredneuralmodel">Build the
|
|
98
|
-
<li><a href="#neuralizemodel">Neuralize the
|
|
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
|
|
101
|
-
<li><a href="#testmodel">Test the
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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())
|
|
@@ -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()
|
|
@@ -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'])
|
|
@@ -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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|