This Project aims to bring modifications to OpenVibe and to widen its data-oriented functionnalities. OpenVibe is a signal processing software allowing the use of machine learning algorithms, however their number is reduced. Thus, we woud like to benefit from the Openvibe Python scripting box (which allows the use of python scripts in OV) in order to allow users to use Scikit-learn Machine Learning algorithms.
pip install pyqt5 pandas numpy natsort pygame sklearn matplotlib pyriemann
The reuse of our scripts in order to simply implement your own python data management
Translated with www.DeepL.com/Translator (free version)
The TrainerML class defined in TrainerML.py is a class that inherits from PolyBox, its purpose is to be used in boxes that will be configured to allow the use of certain learning machine algorithms. The following parameters can be passed to it:
TangentSpace
, it is necessary to provide a second algorithm which will be used to classify after the projection on the tangent space. All the previous algorithms can be used except TangentSpace
and MDM
. If no algorithm is specified, LinearDiscriminantAnalysis
will be used by default.
Similarly for MDM
, a second algorithm may be used, but is not mandatory.my label1, my label2, my label3
, otherwise, the labels will be as follows 1, 2, 3, 4, ...
. If the read mode is ov-mode, you can leave the field blank, the labels will be extracted from the stimuli.Here are the new algorithms / boxes implemented in OV :
https://scikit-learn.org/stable/
Box Name Algorithm Nearest Centroid NearestCentroid Nearest Neighbors Classifier KNeighborsClassifier Gaussian Naive Bayes GaussianNB Stochastic Gradient Descent SGDClassifier Logistic Regression LogisticRegression Decision Tree Classifier DecisionTreeClassifier Extra Trees ExtraTreesClassifier Bagging BaggingClassifier Random Forest RandomForestClassifier Support Vector Machine LinearSVC Linear Discriminant Analysis LinearDiscriminantAnalysis AdaBoost AdaBoostClassifier Multi Layer Perceptron MLPClassifier Linear SVC LinearSVC
https://pyriemann.readthedocs.io/en/latest/index.html
String Algorithm Riemann Minimum Distance to Mean MDM Riemann Tangent Space TangentSpace
You can easily find information on each of these methods in the docs of their library.
For each of these classifiers, an Openvibe box using TrainerML with the appropriate parameters has been created. So, if you want to train with the Random Forest algorithm of Scikit-learn for example, you just have to look for the associated box in Openvibe and you will be able to use it directly, and modify the parameters related to the algorithm. You will find the information concerning all these parameters on the respective pages of the algorithms, ex: https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html.
Example of parameterization of a box implementing Random Forest
This box allows you to make classification predictions on new data using a previously trained model (via TrainerML or the boxes that inherit it, e.g. SVM, LDA, RandomForest …).
pred1,pred2,pred3 ...
.Once the model is loaded, the predictions will be made on each chunk of data received, they can be used in real time, and if a path is given, they can be saved for later use.
The DataViz Box allows the visualization of our data. To do this, it applies a dimension reduction via an LDA or PCA and then displays our data using the matplotlib library. It inherits from PolyBox. It requires the following parameters:
PCA
or LDA
. The default algorithm used is LDA.my label1, my label2, my label3
if the read mode is poly-mode. Otherwise, the labels will be in the form 1, 2, 3, 4, ...
.To facilitate data acquisition during our experiments, we created the python box DatasetCreator
. This box takes a signal as an input and outputs a `OVTK_StimulationId_ExperimentStop’ stimulation when it has finished creating the dataset.
It works in the following way: the user first chooses some labels, then the box will randomly determine an order between them. It will then record the user’s brain activity while verbally indicating the current action. In this way, we will be able to create a labeled dataset that can be used for learning.
The recording of an action takes place in the following way:
It can be configured by indicating :
pybox-manager/Assets/Sounds/
, you can create new labels with the manager).The Pybox Manager allows you to simply create and incorporate new boxes running a Python script of your choice, new labels/stimulations and new Custom Settings for your python boxes into OpenVibe.
To run it: python pybox_manager.py
.
(Python 2.7 and python 3.X compatible.)
An option is available to enable the so-called “developer settings” i.e. the ones you created.
To do this, run the manager with the -mode=developer
option.
The Box Manager looks like this:
PyBox Manager.
Once your modifications are finished you can press Build to have the modifications taken into account, and the compilation is done (mandatory to have your modifications and new boxes). The compilation.log file contains information from the last compilation.
Delete Box deletes the currently selected box (a compilation is necessary to take the deletion into account).
When reading and processing our signals, OpenViBE can handle stimulations. These can be used to label our data during a classification/training procedure.
All these stimulations are indicated in the file pybox-manager/share/PolyStimulations.py
.
The DatasetCreator box we have created allows you to monitor the creation of a labeled dataset for the user. To do this, the box plays a sound during each action, indicating the action the user should think about. Basically, the user will have at his disposal about ten different labels.
We allow the user to add labels (stimulations) via the Stimulations/Labels Manager
interface present in the manager.
To do this, the manager must provide the name of the label, and a corresponding .mp3
file, which will be played by the DatasetCreator.
Add a label/stimulation to OpenViBE.
The Custom Settings Manager
allows you to create or delete special types of settings, as well as possible values for these settings, according to your needs.
This is especially useful to allow easy use on OpenVibe using a drop-down list. For example, if you want to be able to choose one algorithm among several, directly in your OpenVibe box configuration, you just have to create this new type as well as the associated values via the manager as shown in the following illustration.
To be able to use them with the manager when defining the parameters of a box, you have to launch the manager with the option mode=developer
.
Add/Remove/Manage Custom Settings.
Result in OpenVibe :
Example with a new type ‘classifier’.
To facilitate our development phases, we have added in pybox-manager/share/PolyBox.py
a class called PolyBox
. This class inherits from the OVBox class. It automates the reception and storage of an input signal and allows the development of simple methods called at key moments:
We have created this box in order to be able to attribute behaviors adapted to our use cases, in particular to easily create boxes proposing Machine Learning algorithms based on its architecture.
Any box inheriting the PolyBox automatically has two possible read modes to retrieve input data.
The first mode (ov-mode
) corresponds to the classic OpenViBE reading mode: the different classes are all included in the same .csv file, and we use input stimuli to separate our data into different classes. To use this mode, you just have to give the box only two inputs: 1 StreamedMatrix and 1 Stimulation.
For example:
Figure 1 - ov-mode
The second mode (poly-mode
) consists in considering as many files as there are classes, i.e. one .csv file per class. To read all these files, the box then needs to have at least as many StreamedMatrix inputs as there are different classes. To use this mode, you just have to create only StreamedMatrix inputs.
(Often, this mode requires a label
parameter in which to fill in the labels of our different classes in the form: my label1, my label2, my label3
).
For example:
Thus, these two reading modes are transparent for the user and allow him to operate the PolyBoxes
either with a single file containing all the actions, or with several files: one per action.
The user doesn’t need to indicate anything for the box to choose the right behavior to adopt, the box chooses its behavior according to its inputs.
Toutes les modifications ont été faite, on peut maintenant compiler. Toutes ces étapes sont implémentées dans pybox-manager/ov-manager.py
.
All the modifications we have made to the software are based on the duplication of the Python Scripting box. Since the latter allows the use of a python script, we decided to create a manager that allows us to automatically make changes in the OV code to duplicate the C++ files needed to duplicate the Python Scripting Box. This way, we can definitively associate a script to a box, and let the user configure it and integrate it into OpenViBE.
Each time a python box is created, the manager performs the following tasks:
pybox-manager/src/
.pybox-manager/Assets/BoxManager/NewBoxPattern-skeletton.h
into ovpBoxName.h
src/defines.hpp
.src/main.cpp
the imports of the newly created files for the box creation as well as the declarations.src/box-algorithms/ovpBoxName.h
, replace the box name and includes/declarations.src/box-algorithms/ovpBoxName.h
.src/box-algorithms/ovpBoxName.h
.src/box-algorithms/ovpBoxName.h
.src/box-algorithms/ovpBoxName.h
.All changes have been made, we can now compile. All these steps are implemented in pybox-manager/ov-manager.py
.
Automatically, the box stores all received chunk in self.data
. This can be handy if the user wants to use all the data at the end of the box (to train a learning machine model for example).
However, it is possible to prevent this behavior voluntarily. To do this, simply give as a parameter when creating the PolyBox record=False
. By default, record is set to True.
We add to meta/sdk/toolkit/include/toolkit/ovtk_defines.hpp
the declaration of our new Custom Settings and to meta/sdk/toolkit/src/ovtk_main.cpp
the creation of the custom setting and the declaration of its different values.