How can I fix the error message : Each rule must have a consequent pointing to a different output membership function.

3 views (last 30 days)
am tunning a fuzzy inference system using PSO, ANFIS and GA, I used PSO to learn the rules of the FIS labelled fisin, while the other two algorithms are used to tuned the parameters of the FIS. The rules are learned successfully using PSO. The issue is in the ANFIS, it keep showing an error message:
"Each rule must have a consequent pointing to a different output membership function."
The code is given below for references:
%% Load automobile fuel consumption data (https://archive.ics.uci.edu/dataset/9/auto+mpg)
[data,name] = loadGasData; % previous MATLAB versions used loadgas
X = data(:,1:6);
Y = data(:,7);
trnX = X(1:2:end,:); % Training input data set
trnY = Y(1:2:end,:); % Training output data set
vldX = X(2:2:end,:); % Validation input data set
vldY = Y(2:2:end,:); % Validation output data set
dataRange = [min(data)' max(data)'];
%% Create a Sugeno FIS for tuning
fisin = sugfis;
for i = 1:6
fisin = addInput(fisin, dataRange(i,:), 'Name', name(i), 'NumMFs', 2);
end
fisin = addOutput(fisin, dataRange(7,:), 'Name', name(7), 'NumMFs', 56);
figure
plotfis(fisin)
%% Stage 1: Learn the rule base using Particle Swarm optimizer, while keeping the input and output MF parameters constant
options = tunefisOptions('Method', 'particleswarm', 'OptimizationType', 'learning', 'NumMaxRules', 59);
options.MethodOptions.MaxIterations = 10;
rng('default')
fisout0 = tunefis(fisin, [], trnX, trnY, options); % carry out the tuning
fprintf('Training RMSE = %.3f MPG\n', calculateRMSE(fisout0, trnX, trnY));
[fisout0.Rules.Description]'
%% Stage 1: Tune the FIS parameters using Anfis
[in, out,rules] = getTunableSettings(fisout0);
options = tunefisOptions('Method', 'anfis');
% options.MethodOptions.MaxIterations = 20; % comment out this line
rng('default')
fisout1 = tunefis(fisout0, [in; out;rules], trnX, trnY, options); % carry out the tuning
fprintf('Training RMSE = %.3f MPG\n', calculateRMSE(fisout1, trnX, trnY));
figure
plotfis(fisout1) % view the PSO-tuned FIS
% view all tuned 64 Rules, if you like
plotActualAndExpectedResultsWithRMSE(fisout1, vldX, vldY) % calculate the RMSE to check accuracy
%% Stage 2: Use rule base from Stage 1 to tune FIS parameters using Genetic Algorithm
[in, out, rule] = getTunableSettings(fisout1);
options.OptimizationType = 'tuning';
options.Method = 'ga'; % Genetic Algorithm
options.MethodOptions.MaxIterations = 60;
options.MethodOptions.UseCompletePoll = true;
rng('default')
fisout = tunefis(fisout1, [in; out; rule], trnX, trnY, options);
fprintf('Training RMSE = %.3f MPG\n', calculateRMSE(fisout, trnX, trnY));
figure
plotfis(fisout) % view the Pattern Search-tuned FIS
plotActualAndExpectedResultsWithRMSE(fisout, vldX, vldY); % calculate the RMSE to check accuracy
% There are 2 Local functions that you need to create
%% Local function #1
function plotActualAndExpectedResultsWithRMSE(fis, x, y)
% Calculate RMSE bewteen actual and expected results
[rmse, actY] = calculateRMSE(fis, x, y);
% Plot results
figure
subplot(2,1,1)
hold on
bar(actY)
bar(y)
bar(min(actY, y),'FaceColor', [0.5 0.5 0.5])
hold off
axis([0 200 0 60])
xlabel("Validation input dataset index"),
ylabel("MPG")
legend(["Actual MPG" "Expected MPG" "Minimum of actual and expected values"], 'Location', 'NorthWest')
title("RMSE = " + num2str(rmse) + " MPG")
subplot(2,1,2)
bar(actY-y)
xlabel("Validation input dataset index"),ylabel("Error (MPG)")
title("Difference Between Actual and Expected Values")
end
%% Local function #2 (this one can be embedded in the local function #1)
function [rmse, actY] = calculateRMSE(fis, x, y)
% Specify options for FIS evaluation
persistent evalOptions
if isempty(evalOptions)
evalOptions = evalfisOptions("EmptyOutputFuzzySetMessage", "none", "NoRuleFiredMessage", "none", "OutOfRangeInputValueMessage", "none");
end
% Evaluate FIS
actY = evalfis(fis, x, evalOptions);
% Calculate RMSE
del = actY - y;
rmse = sqrt(mean(del.^2)); % the rmse() function was introduced in R2022b
% See https://www.mathworks.com/help/matlab/ref/rmse.html
end

Answers (2)

Sam Chak
Sam Chak on 11 Dec 2023
The tunefis() command enables the tuning of fuzzy systems by specifying one of the five optimization methods and their options using the tunefisOptions() command. What adds complexity is that the 'MethodOptions' property differs for each algorithm. One needs to be very familiar with all five types of optimization methods and their respective options.
As seen previously, the 'anfis' method in tunefisOptions() threw some error messages during the tuning of the 2nd stage due to its lack of support for certain tuning options, rendering it less flexible in this approach. However, the anfis() direct tuning method itself proves to be quite powerful when the training options are appropriately specified.
In this brief example with 2 inputs and 1 output, Stage 1 is tuned using PSO, and Stage 2 is tuned using GA.
%% Sam's Data for 2 inputs and 1 output
x = linspace(-4, 4, 21)';
y = x;
z = tanh(x) + tanh(y);
data = [x, y, z];
name = ["in1" "in2" "out"];
%% Data allocation for training and validation
X = data(:,1:2);
Y = data(:,end);
trnX = X(1:2:end,:); % Training input data set
trnY = Y(1:2:end,:); % Training output data set
vldX = X(2:2:end,:); % Validation input data set
vldY = Y(2:2:end,:); % Validation output data set
dataRange = [min(data)' max(data)'];
%% Create a Sugeno FIS for tuning
fisin = sugfis;
for i = 1:2
fisin = addInput(fisin, dataRange(i,:), 'Name', name(i), 'NumMFs', 3);
end
fisin = addOutput(fisin, dataRange(3,:), 'Name', name(3), 'NumMFs', 3^2);
figure
plotfis(fisin)
%% Stage 1: Learn the rule base using Particle Swarm optimizer, while keeping the input and output MF parameters constant
options = tunefisOptions('Method', 'particleswarm', 'OptimizationType', 'learning', 'NumMaxRules', 3^2);
options.MethodOptions.MaxIterations = 10;
rng('default')
fisout1 = tunefis(fisin, [], trnX, trnY, options); % carry out the tuning
Best Mean Stall Iteration f-count f(x) f(x) Iterations 0 100 0.8605 1.909 0 1 200 0.3841 1.94 0 2 300 0.3235 1.838 0 3 400 0.2938 1.801 0 4 500 0.2938 1.805 1 5 600 0.2938 1.741 2 6 700 0.2262 1.689 0 7 800 0.2262 1.642 1 8 900 0.2262 1.692 2 9 1000 0.2262 1.768 3 10 1100 0.2262 1.758 4 Optimization ended: number of iterations exceeded OPTIONS.MaxIterations.
fprintf('Training RMSE = %.3f \n', calculateRMSE(fisout1, trnX, trnY));
Training RMSE = 0.226
figure
plotfis(fisout1) % view the PSO-tuned FIS
[fisout1.Rules.Description]' % view all tuned 9 Rules, if you like
ans = 4×1 string array
"in1==mf3 & in2==mf3 => out=mf9 (1)" "in1==mf1 & in2==mf1 => out=mf1 (1)" "in1==mf2 & in2==mf3 => out=mf8 (1)" "in2==mf1 => out=mf1 (1)"
plotActualAndExpectedResultsWithRMSE(fisout1, vldX, vldY) % calculate the RMSE to check accuracy
%% Stage 2: Use rule base from Stage 1 to tune parameters of input/output MFs & rules using GA optimizer
[in, out, rule] = getTunableSettings(fisout1);
% options.OptimizationType = 'tuning';
% options.Method = 'patternsearch';
% options.MethodOptions.MaxIterations = 20;
% options.MethodOptions.UseCompletePoll = true;
tuningOpt = tunefisOptions; % 'ga' optimizer is selected by default
tuningOpt.MethodOptions.MaxGenerations = 10; % max iterations for 'ga'
rng('default')
% fisout = tunefis(fisout1, [in; out; rule], trnX, trnY, options); % if use 'patternsearch';
fisout = tunefis(fisout1, [in; out; rule], trnX, trnY, tuningOpt); % if use 'ga';
Single objective optimization: 39 Variables Options: CreationFcn: @gacreationuniform CrossoverFcn: @crossoverscattered SelectionFcn: @selectionstochunif MutationFcn: @mutationadaptfeasible Best Mean Stall Generation Func-count f(x) f(x) Generations 1 400 0.2262 1.813 0 2 590 0.2262 1.744 0 3 780 0.2262 1.606 1 4 970 0.2226 1.598 0 5 1160 0.2069 1.334 0 6 1350 0.19 1.214 0 7 1540 0.19 0.8974 0 8 1730 0.19 0.681 0 9 1920 0.1874 0.526 0 10 2110 0.1874 0.4472 1 ga stopped because it exceeded options.MaxGenerations.
fprintf('Training RMSE = %.3f \n', calculateRMSE(fisout, trnX, trnY));
Training RMSE = 0.187
figure
plotfis(fisout) % view the Pattern Search-tuned FIS
[fisout.Rules.Description]' % view all tuned 9 Rules, if you like
ans = 4×1 string array
"in1==mf3 & in2==mf3 => out=mf9 (1)" "in1==mf1 & in2==mf2 => out=mf1 (1)" "in1==mf2 & in2==mf3 => out=mf8 (1)" "in1==mf1 & in2==mf1 => out=mf1 (1)"
plotActualAndExpectedResultsWithRMSE(fisout, vldX, vldY); % calculate the RMSE to check accuracy
%% Local function #1
function plotActualAndExpectedResultsWithRMSE(fis, x, y)
% Calculate RMSE bewteen actual and expected results
[rmse, actY] = calculateRMSE(fis, x, y);
% Plot results
figure
subplot(2,1,1)
hold on
bar(actY)
bar(y)
bar(min(actY, y),'FaceColor', [0.5 0.5 0.5])
hold off
% axis([0 200 0 60])
xlabel("Validation input dataset index"),
ylabel("Amplitude")
legend(["Actual output" "Expected output" "Minimum of actual and expected values"], 'Location', 'NorthWest')
title("RMSE = " + num2str(rmse) + " amplitude")
subplot(2,1,2)
bar(actY-y)
xlabel("Validation input dataset index"), ylabel("Error")
title("Difference Between Actual and Expected Values")
end
%% Local function #2 (this one can be embedded in the local function #1)
function [rmse, actY] = calculateRMSE(fis, x, y)
% Specify options for FIS evaluation
persistent evalOptions
if isempty(evalOptions)
evalOptions = evalfisOptions("EmptyOutputFuzzySetMessage", "none", "NoRuleFiredMessage", "none", "OutOfRangeInputValueMessage", "none");
end
% Evaluate FIS
actY = evalfis(fis, x, evalOptions);
% Calculate RMSE
del = actY - y;
rmse = sqrt(mean(del.^2)); % the rmse() function was introduced in R2022b
% See https://www.mathworks.com/help/matlab/ref/rmse.html
end
  1 Comment
Ahmad
Ahmad on 11 Dec 2023
Moved: Sam Chak on 11 Dec 2023
@Sam Chak Thanks for the reply, I want to use other algorithms, I tried simulated annealing, but it stalls during the iteration process. If You can help with the tunning options of the simulated annealing I will be happy sir.

Sign in to comment.


Sam Chak
Sam Chak on 11 Dec 2023
As requested, Stage 1 is tuned using PSO, and Stage 2 is tuned using Simulated Annealing.
%% Sam's Data for 2 inputs and 1 output
x = linspace(-4, 4, 61)';
y = x;
z = tanh(x) + tanh(y);
data = [x, y, z];
name = ["in1" "in2" "out"];
%% Data allocation for training and validation
X = data(:,1:2);
Y = data(:,end);
trnX = X(1:2:end,:); % Training input data set
trnY = Y(1:2:end,:); % Training output data set
vldX = X(2:2:end,:); % Validation input data set
vldY = Y(2:2:end,:); % Validation output data set
dataRange = [min(data)' max(data)'];
%% Create a Sugeno FIS for tuning
fisin = sugfis;
for i = 1:2
fisin = addInput(fisin, dataRange(i,:), 'Name', name(i), 'NumMFs', 3);
end
fisin = addOutput(fisin, dataRange(3,:), 'Name', name(3), 'NumMFs', 3^2);
figure
plotfis(fisin)
%% Stage 1: Learn the rule base using Particle Swarm optimizer, while keeping the input and output MF parameters constant
options = tunefisOptions('Method', 'particleswarm', 'OptimizationType', 'learning', 'NumMaxRules', 3^2);
options.MethodOptions.MaxIterations = 10;
rng('default')
fisout1 = tunefis(fisin, [], trnX, trnY, options); % carry out the tuning
Best Mean Stall Iteration f-count f(x) f(x) Iterations 0 100 0.8896 1.892 0 1 200 0.4412 1.934 0 2 300 0.4028 1.891 0 3 400 0.3552 1.86 0 4 500 0.3552 1.848 1 5 600 0.3552 1.825 2 6 700 0.3292 1.707 0 7 800 0.3292 1.618 1 8 900 0.3292 1.623 2 9 1000 0.3292 1.787 3 10 1100 0.3292 1.794 4 Optimization ended: number of iterations exceeded OPTIONS.MaxIterations.
fprintf('Training RMSE = %.3f \n', calculateRMSE(fisout1, trnX, trnY));
Training RMSE = 0.329
figure
plotfis(fisout1) % view the PSO-tuned FIS
[fisout1.Rules.Description]' % view all tuned Rules
ans = 4×1 string array
"in1==mf3 & in2==mf3 => out=mf9 (1)" "in1==mf1 & in2==mf1 => out=mf1 (1)" "in1==mf2 & in2==mf3 => out=mf8 (1)" "in2==mf1 => out=mf1 (1)"
plotActualAndExpectedResultsWithRMSE(fisout1, vldX, vldY) % calculate the RMSE to check accuracy
%% Stage 2: Use rule base from Stage 1 to tune parameters of input/output MFs & rules using GA optimizer
[in, out, rule] = getTunableSettings(fisout1);
options.OptimizationType = 'tuning';
options.Method = 'simulannealbnd';
options.MethodOptions.MaxIterations = 180;
rng('default')
fisout = tunefis(fisout1, [in; out; rule], trnX, trnY, options);
Best Current Mean Iteration f-count f(x) f(x) temperature 0 1 0.329182 0.329182 100 10 11 0.30743 1.80356 56.88 20 21 0.30743 1.49834 34.0562 30 31 0.30743 2.05339 20.3907 40 41 0.30743 2.27764 12.2087 50 51 0.30743 1.00487 7.30977 60 61 0.30743 2.11915 4.37663 70 71 0.30743 1.69299 2.62045 80 81 0.30743 1.86859 1.56896 90 91 0.30743 1.51086 0.939395 100 101 0.30743 1.43074 0.56245 110 111 0.30743 1.68057 0.33676 120 121 0.30743 1.60476 0.201631 130 131 0.30743 1.60045 0.120724 140 141 0.30743 1.59789 0.0722817 * 145 185 0.30743 1.59927 15.4836 150 190 0.30743 1.22634 11.9809 160 200 0.30743 1.69857 7.17342 170 210 0.30743 1.59184 4.29499 180 220 0.30743 1.75657 2.57157 simulannealbnd stopped because it exceeded the iteration limit. Increase options.MaxIterations.
fprintf('Training RMSE = %.3f \n', calculateRMSE(fisout, trnX, trnY));
Training RMSE = 0.307
figure
plotfis(fisout) % view the Simulated Annealing-tuned FIS
[fisout.Rules.Description]' % view all tuned Rules
ans = 4×1 string array
"in1==mf3 & in2==mf3 => out=mf9 (1)" "in1==mf1 & in2==mf1 => out=mf1 (1)" "in1==mf2 & in2==mf3 => out=mf8 (1)" "in2==mf1 => out=mf1 (1)"
plotActualAndExpectedResultsWithRMSE(fisout, vldX, vldY); % calculate the RMSE to check accuracy
%% Local function #1
function plotActualAndExpectedResultsWithRMSE(fis, x, y)
% Calculate RMSE bewteen actual and expected results
[rmse, actY] = calculateRMSE(fis, x, y);
% Plot results
figure
subplot(2,1,1)
hold on
bar(actY)
bar(y)
bar(min(actY, y),'FaceColor', [0.5 0.5 0.5])
hold off
% axis([0 200 0 60])
xlabel("Validation input dataset index"),
ylabel("Amplitude")
legend(["Actual output" "Expected output" "Minimum of actual and expected values"], 'Location', 'NorthWest')
title("RMSE = " + num2str(rmse) + " amplitude")
subplot(2,1,2)
bar(actY-y)
xlabel("Validation input dataset index"), ylabel("Error")
title("Difference Between Actual and Expected Values")
end
%% Local function #2 (this one can be embedded in the local function #1)
function [rmse, actY] = calculateRMSE(fis, x, y)
% Specify options for FIS evaluation
persistent evalOptions
if isempty(evalOptions)
evalOptions = evalfisOptions("EmptyOutputFuzzySetMessage", "none", "NoRuleFiredMessage", "none", "OutOfRangeInputValueMessage", "none");
end
% Evaluate FIS
actY = evalfis(fis, x, evalOptions);
% Calculate RMSE
del = actY - y;
rmse = sqrt(mean(del.^2)); % the rmse() function was introduced in R2022b
% See https://www.mathworks.com/help/matlab/ref/rmse.html
end

Categories

Find more on Fuzzy Inference System Tuning in Help Center and File Exchange

Products


Release

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!