fixunknows on nftool GUI matlab - matlab

I am using the nftool GUI to set up a regression neural network.
My database has various NaN (missing values). When I run the GUI, everything seems to go right. It gives me the performance and the regression graph.
I read that by line code you can add a processFcn named 'fixunknowns' to the network.
My question is: In the GUI, is the neural network making the fixunknows? How the GUI is procesing this NaN?
When I generate the script, the fixunknows function does not appear.
I wonder if it is only possible to treat this NaN values on line code? Or... perhaps the GUI implements the fixnknowns automatically?
Thank you.

When you get to the end of nftool, click 'advanced script'. This script will repeat exactly what you have done in nftool. In it you will see
% Choose Input and Output Pre/Post-Processing Functions
% For a list of all processing functions type: help nnprocess
net.input.processFcns = {'removeconstantrows','mapminmax'};
net.output.processFcns = {'removeconstantrows','mapminmax'};
This would indicate that fixunknowns is not run, (unless it is called by a function we can't see in this script). So you can add this line
net.input.processFcns = {'fixunknowns'};
Note that you should not run fixunknowns on the output. If there are NaNs in the output, delete the entire row/sample.
If you make a change in the GUI, you will have to add the fixunknowns each time.

Related

Programmatically open a Simulink MATLAB function block's code

Can I open a local Simulink MATLAB function block's code in the MATLAB editor via some command?
For example, let us say I have a Simulink model named mainModel.slx.
In it, there is a MATLAB function block named localFunction.
This is not defined in a .m-file.
I would be able to edit the function which path is mainModel/localFunction, without having to open the simulink window and double click on the function block. Is this possible?
I have of course already tried open mainModel/localFunction and edit mainModel/localFunction. I have access to the handle for its StateFlow.EMChart object.
EDIT: Minimal, (hopefully) Complete and Verifiable Example
My minimal Simulink model is shown in the picture below. Code is present below it. For readability, I have not addressed bugs or glitches. It is not for general usage.
The function code for the MATLAB function block localFunction is
function y = fcn(u)
y = 'findThis'; % I want to end up here, in the MATLAB editor!
end
I am using the following code to load the model, search through all MATLAB function blocks and find the ones containing the string 'findThis'. The MATLAB function block named 'localFunction' should then be found. Again, ignore the bugs. The code is saved in a script called tmpScript.m.
% User set
model = 'mainModel';
expression = 'findThis';
blockType = 'Stateflow.EMChart'; % MATLAB function block, right?
% Load model
load_system(model)
% Find all MATLAB function block handles
blockHandles = find(slroot, '-isa', blockType);
% Find first block containing the defined expression
for iHandle = 1:numel(blockHandles)
tmpFind = strfind(blockHandles(iHandle).Script, expression);
if ~isempty(tmpFind)
break
end
end
foundBlockPath = blockHandles(iHandle ).Path; % Function block path
foundCharIdx = tmpFind; % Character index
% Print results in command window
fprintf('Function path: %s\n', foundBlockPath)
fprintf('Character index: %d\n', foundCharIdx)
In this example, the path should be mainModel/localFunction and the character index 29 (Note the three leading white spaces on the function's second line, and that the line break '\n' is worth one characters). The command window shows
>> tmpScript
Function path: mainModel/localFunction
Character index: 29
>>
I can thus load models and search through their MATLAB function blocks for specific strings. When I have found this function, I would like to be able to open it in the matlab editor. What is called when I double click on the block in the Simulink window?
These do NOT work
open(foundBlockPath)
edit(foundBlockPath)
blockHandles(iHandle).openEditor
I cannot change the Simulink model itself. I do not want to change the function script. I just want to be able to open it in the MATLAB editor.
You can open the code in the Editor using,
view(blockHandles(iHandle))
You could change the Matlab function block to an Interpreted Matlab function block.
This does have the limitation that it only can have one input and one output (which can be vectors), so depending on your problem, you might have to mux/demux some data.
Alternatively you can change to an S-function, which gives more flexibility, but might be a bit more complex to setup.

How to call simulink model(.slx) from script

I'm a super beginner in Simulink models and control systems.
I have .slx Simulink model for drone dynamics system.
It takes in two inputs (roll cmd, pitch cmd) and outputs velocity x, velocity y, position x, and position y.
From here, it seems like I can open the system by calling
open_system('myModel.slx', 'loadable');
But how do I put inputs and get output values?
Is there a way I can do this in a gui?
EDIT:
Here is the full layout of my model:
When I did
roll_CMD=10;
pitch_CMD=20;
I got a warning saying:
Input port 1 of 'SimpleDroneDynamics/...' is not connected.
How do I feed inputs using port numbers?
How do I get outputs with port numbers? I tried
[vx, vy, px, py] = sim('SimpleDroneDynamics.slx');
and got an error saying
Number of left-hand side argument doesn't match block diagram...
Is there a way to continuously feed inputs at every time step? This being controller module, I think I'm supposed to feed in different values based on output position and velocity.
EDIT2:
I'm using Matlab2017a
About the first two points of your question:
In simulink:
For the inputs you can use a constant block and when you double click the input block you can assign a value, which can be a workspace variable.
To get the outputs to your workspace you can use the simout block (make sure to put Save format to array).
Connect inputs to your simulink model
Connect outputs of your simulink model to the simout blocks.
MATLAB script
clc;
clear all;
roll = 10;
pitch = 20;
sim('/path_to_simulinkmodel.slx')
time = simout(:,1);
velocity_X = simout(:,2);
velocity_Y = simout(:,3);
position_X = simout(:,4);
position_Y = simout(:,5);
About the third point of your question
You can define the duration of your simulation in the block diagram editor. You can put a variable which is defined in the calling script. There are multiple ways of achieving time dependent input variables:
One option I personally don't recommend is using a for-loop and calling the simulink model with a different value of roll and pitch
for i = 1:numberOfTimesteps
roll = ...
...
sim('simulinkModel.slx')
end
A second and more efficient approach is changing the constant blocks to other source blocks like ramp signals or sinusoid signals
First of all Simulink model use main Matlab workspace. So you can change your variables values at command window (or just at your script) and run Simulink model.
There are several ways to initialize this constants for Simulink. One more useful way is to create script containing all your variables and load it at Simulink model starts. You can do it by adding script name in Simulink/Model Explorer/Callbacks. (There are different callbacks - on Loading, on Starting and etc.). Read more about this: here.
Now you can run your simulation using sim function:
sim('name_of_model')
name_of_model must contain path if model is not in the active MATLAB folder (active folder you can see in your matlab window just under the main menu).
There are different properties of sim function, read about them in help this can be useful for you. By the way: you can change some parameters of your model using sim. You even can find any block in your model and change it's properties. Read more about sim and about finding current blocks. Interesting that the last solution give you ability to change parameters during the simulation!
About getting output. After you run simulation you get tout variable in main workspace. It is an array of timesteps. But if you add outport block (like at my image) you also get another variable in workspace yout. yout is an Datasets. It contain all your outports values. For 2 outports for example:
yout
yout =
Simulink.SimulationData.Dataset
Package: Simulink.SimulationData
Characteristics:
Name: 'yout'
Total Elements: 2
Elements:
1 : ''
2 : ''
Get the values of any of outports:
yout.get(1).Values
it is a timeseries data type, so:
yout.get(1).Values.Time - give you times
yout.get(2).Values.Data - give you values of this outport at each time
We have one more method to take output values:
[t,x,y] = sim('model_name')
it returns double arrays. t- time array, y - matrix of all outports values (it already double and contain only values without times, but for each simulation time!)
So now you can create common Matlab GUI and work at this variables! There is no any difficulties. You can read more about GUI for Simulink here.

How can I get signal dimensions in Simulink model

I have a question.
After simulate a simulink model I need to get signal dimensions of each line using MATLAB command.
I get line handles by following
line_h = find_system(gcs, 'FindAll', 'on','SearchDepth', 1, 'Type', 'Line')
then how can I get signal dimensions from line handles
** When check 'signal dimensions' in Format menu -> Port/Signal Displays
After simulate a model number of signal dimensions will show on nonscalar line.
I need to get it using MATLAB command.
Sorry for my English skill
Thank you
Alternatively, you can find the signal dimensions and signal widths of each block they originate from, using:
get_param(<block_path>,'CompiledPortDimensions')
get_param(<block_path>,'CompiledPortWidths')
Replacing <block_path> with the appropriate block path for each block of interest. The model must be compiled before you can run these commands, but since you indicate doing this after running the model, that shouldn't be a problem.
If you have a set of line handles from your find_system command you can use the following command to get the block connected to the signal.
hblkSrc = get_param(h(k),'SrcBlockHandle');
You can then use get_param(hblkSrc,'CompiledPortDimensions') as suggested by am304 to get the dimensions.
You can solve it the following way.
Enable signal logging for the desired signals (Properties). For
example set the name to custom and signalone.
If you actually don't want to log the signal, set Limit data points to last to 1, so you avoid storing unused data.
Go to SImulink preferences and enable signal logging, default output name is logsout
after simulation you'll get a dataset logsout in your workspace
now evaluate this dataset as follows:
% returns data, if data limit is set to 1 it's a coloumn
% vector with just the last value
data = logsout.get('signalone').Values.Data
you can now just use the size of this vector and you know the dimension of the signal
[~,dim]=size(data)
or in one line:
[~,dim]=size(logsout.get('signalone').Values.Data)
If you have a a lot of signals and you want to evaluate them at once, give your signals convenient output-names and use a loop for iterating through a string vector with all your signal names.
As you say you want the dimensions of "all" (are you sure?) signals I think it is more convenient to just check "Enable signal logging" in each signal property and do all further definitions in the Simulink preferences where you have a list to manage all signals.

Matlab libsvm svmpredict accuracy verbose

I have a question of an annoying fact. I'm using libsvm with matlab and I'am able to predict using:
predicted_label = svmpredict(Ylabel, Xlabel, model);
but it happen that every time I make a predictions appears this:
Accuracy = X% (y/n) (classification)
Which I find annoying because I am repeating this procedure a lot of times and also makes it slow because its displaying in screen.
I think what I want is to avoid that svmpredict being verbose.
Can anyone help me with this? Thanks in advance.
-Jessica
I found a much better approach than editing the source code of the c library was to use matlabs evalc which places any output to the first output argument.
[~ predicted_label] = evalc('svmpredict(Ylabel, Xlabel, model)');
Because the string to be evaluated is fixed should be no performance decrease.
svmpredict(Ylabel, Xlabel, model, '-q');
From the manual:
Usage: [predicted_label, accuracy, decision_values/prob_estimates] = svmpredict(testing_label_vector, testing_instance_matrix, model, 'libsvm_options')
[predicted_label] = svmpredict(testing_label_vector, testing_instance_matrix, model, 'libsvm_options')
Parameters:
model: SVM model structure from svmtrain.
libsvm_options:
-b probability_estimates: whether to predict probability estimates, 0 or 1 (default 0); one-class SVM not supported yet
-q : quiet mode (no outputs)
If you are using matlab, just find the line of code that is displaying this information (usually using 'disp', 'sprintf', or 'fprintf') and comment it out using the commenting operator %.
example:
disp(['Accuracy= ' num2str(x)]);
change it to:
% disp(['Accuracy= ' num2str(x)]);
If you are using the main libsvm library then you need to modify it before making.
1- Open the file 'svmpredict.c'
2- find this line of code:
info("Accuracy = %g%% (%d/%d) (classification)\n",
(double)correct/total*100,correct,total);
3- just comment it out using // operator
4- save and close the file
5- make the project

How to run Matlab computations in parallel

I have Matlab .m script that sets and trains Neural network ("nn") using Matlab's Neural network toolbox. The script launches some GUI that shows trainig progress etc. The training of nn usually takes long time.
I'm doing these experiments on computer with 64 processor cores. I want to train several networks at the same time without having to run multiple Matlab sessions.
So I want to:
Start training of neural network
Modify script that creates network to create different one
Start training of modified network
Modify script to create yet another network...
Repeat steps 1-4 several times
The problem is that when I run the scrip it blocks Matlab terminal so I cannot do anything else until the script executes its last command - and that takes long. How can I run all those computations in parallel? I do have Matlab parallel toolbox.
EDIT: Matlab bug??
Update: This problem seems to happen only on R2012a, looks like fixed on R2012b.
There is very strange error when I try command sequence recommended in Edric's answer.
Here is my code:
>> job = batch(c, #nn, 1, {A(:, 1:end -1), A(:, end)});
>> wait(job);
>> r = fetchOutputs(job)
Error using parallel.Job/fetchOutputs (line 677)
An error occurred during execution of Task with ID 1.
Caused by:
Error using nntraintool (line 35)
Java is not available.
Here are the lines 27-37 of nntraintool (part of Matlab's Neural networks toolkit) where error originated:
if ~usejava('swing')
if (nargin == 1) && strcmp(command,'check')
result = false;
result2 = false;
return
else
disp('java used');
error(message('nnet:Java:NotAvailable'));
end
end
So it looks like the problem is that GUI (because Swing is not available) cannot be used when job is executed using batch command. The strange thing is that the nn function does not launch any GUI in it's current form. The error is caused by train that launches GUI by default but in nn I have switched that off:
net.trainParam.showWindow = false;
net = train(net, X, y);
More interestingly if the same nn function is launched normally (>> nn(A(:, 1:end -1), A(:, end));) it never enters the outer if-then statement of nntraintool on line 27 (I have checked that using debugger). So using the same function, the same arguments expression ~usejava('swing') evaluates to 0 when command is launched normally but to 1 when launched using batch.
What do you think about this? It looks like ugly Matlab or Neural networks toolbox bug :(((
With Parallel Computing Toolbox, you can run up to 12 'local workers' to execute your scripts (to run more than that, you'd need to purchase additional MATLAB Distributed Computing Server licences). Given your workflow, the best thing might be to use the BATCH command to submit a series of non-interactive jobs. Note that you will not be able to see any GUI from the workers. You might do something like this (using R2012a+ syntax):
c = parcluster('local'); % get the 'local' cluster object
job = batch(c, 'myNNscript'); % submit script for execution
% now edit 'myNNscript'
job2 = batch(c, 'myNNscript'); % submit script for execution
...
wait(job); load(job) % get the results
Note that the BATCH command automatically attaches a copy of the script to run to the job, so that you are free to make changes to it after submission.