В этом примере показано, как настроить процесс настройки FIS путем определения пользовательской функции затрат или пользовательского метода оптимизации.
Для получения дополнительной информации о настройке FIS, смотрите Настройка нечетких правил и Параметры функции принадлежности и Настройка нечетких деревьев.
Можно задать пользовательскую функцию затрат для настройки нечеткой системы. Это полезно для:
Настройка FIS с помощью пользовательской модели без использования входных/выходных обучающих данных. Для получения примера смотрите Настроить Нечеткую Систему Предотвращения Препятствий Робота Используя Пользовательскую Функцию Стоимости.
Объединение выходов FIS компонента дерева FIS с помощью математических операций, как показано в этом примере.
В качестве примера рассмотрим дерево FIS из Tune Fuzzy Trees.
Предположим, что вы хотите изменить дерево FIS, как показано на следующей схеме, объединяя выходы FIS с помощью известных математических операций из обучающих данных.
Создайте дерево FIS, которое содержит три объекта FIS. Выходы дерева FIS являются выходами отдельных объектов FIS.
fis1 = sugfis('Name','fis1'); fis1 = addInput(fis1,[0 10],'NumMFs',3,'MFType','gaussmf'); fis1 = addOutput(fis1,[-1 1],'NumMFs',3); fis2 = sugfis('Name','fis2'); fis2 = addInput(fis2,[0 10],'NumMFs',3,'MFType','gaussmf'); fis2 = addOutput(fis2,[-1 1],'NumMFs',3); fis3 = sugfis('Name','fis3'); fis3 = addInput(fis3,[0 10],'NumMFs',3,'MFType','gaussmf'); fis3 = addOutput(fis3,[0 1],'NumMFs',3); con = ["fis1/input1" "fis2/input1";"fis2/input1" "fis3/input1"]; fisT = fistree([fis1 fis2 fis3],con);
Сгенерируйте обучающие данные.
x = (0:0.1:10)'; y1 = sin(x)+cos(x); y2 = y1./exp(x); y = [y1;y2];
Для реализации операций сложения и умножения используйте функцию затрат. В данном примере используйте пользовательскую функцию customcostfcn
, включенный в конец примера. Изучение основы правил с помощью этой функции затрат.
options = tunefisOptions('Method',"particleswarm",'OptimizationType',"learning"); options.MethodOptions.MaxIterations = 5; rng('default') fisTout1 = tunefis(fisT,[],@(fis)customcostfcn(fis,x,y),options);
Best Mean Stall Iteration f-count f(x) f(x) Iterations 0 100 0.746 1.31 0 1 200 0.5089 1.249 0 2 300 0.5089 1.086 1 3 400 0.5089 1.112 2 4 500 0.5089 1.106 3 5 600 0.4999 1.051 0 Optimization ended: number of iterations exceeded OPTIONS.MaxIterations.
Затем настройте все параметры дерева FIS.
options.Method = 'patternsearch'; options.MethodOptions.MaxIterations = 25; [in,out,rule] = getTunableSettings(fisTout1); rng('default') fisTout2 = tunefis(fisTout1,[in;out;rule],@(fis)customcostfcn(fis,x,y),options);
Iter Func-count f(x) MeshSize Method 0 1 0.499882 1 1 13 0.499864 2 Successful Poll 2 51 0.499727 4 Successful Poll 3 72 0.499727 2 Refine Mesh 4 117 0.499727 1 Refine Mesh 5 157 0.499542 2 Successful Poll 6 170 0.499485 4 Successful Poll 7 191 0.499485 2 Refine Mesh 8 217 0.499483 4 Successful Poll 9 238 0.499483 2 Refine Mesh 10 275 0.499483 4 Successful Poll 11 296 0.499483 2 Refine Mesh 12 340 0.499483 1 Refine Mesh 13 381 0.499483 2 Successful Poll 14 425 0.499483 1 Refine Mesh 15 497 0.499483 0.5 Refine Mesh 16 536 0.499394 1 Successful Poll 17 547 0.499217 2 Successful Poll 18 591 0.499217 1 Refine Mesh 19 603 0.499211 2 Successful Poll 20 630 0.498972 4 Successful Poll 21 652 0.498972 2 Refine Mesh 22 696 0.498972 1 Refine Mesh 23 768 0.498972 0.5 Refine Mesh 24 843 0.498972 0.25 Refine Mesh 25 859 0.495584 0.5 Successful Poll 26 869 0.494138 1 Successful Poll Maximum number of iterations exceeded: increase options.MaxIterations.
Можно добавить больше входных/выходных MF и задать дополнительные выходы дерева FIS, чтобы улучшить эффективность настройки. Использование дополнительных параметров MF и дополнительных обучающих данных для дополнительных выходов дерева FIS может дополнительно настроить выходы fis1
, fis2
, и fis3
.
Можно также реализовать свой собственный метод оптимизации параметров управления FIS с помощью getTunableSettings
, getTunableValues
, и setTunableValues
. Этот пример использует эти функции, чтобы настроить основу правил нечеткой системы.
Создайте FIS, чтобы аппроксимировать , где изменяется от 0 до .
fisin = mamfis;
Добавьте вход с областью значений [0, ] и имеющий пять Гауссовых МФ. Кроме того, добавьте выход с областью значений [-1, 1] и имеющий пять гауссовских MF.
fisin = addInput(fisin,[0 2*pi],'NumMFs',5,'MFType','gaussmf'); fisin = addOutput(fisin,[-1 1],'NumMFs',5,'MFType','gaussmf');
Добавьте пять правил.
fisin = addRule(fisin,[1 1 1 1;2 2 1 1;3 3 1 1;4 4 1 1;5 5 1 1]); fisin.Rules
ans = 1x5 fisrule array with properties: Description Antecedent Consequent Weight Connection Details: Description ________________________________ 1 "input1==mf1 => output1=mf1 (1)" 2 "input1==mf2 => output1=mf2 (1)" 3 "input1==mf3 => output1=mf3 (1)" 4 "input1==mf4 => output1=mf4 (1)" 5 "input1==mf5 => output1=mf5 (1)"
Для более быстрого обновления FIS установите DisableStructuralChecks
на true
.
fisin.DisableStructuralChecks = true;
Получите настройки параметра правила.
[~,~,rule] = getTunableSettings(fisin);
Сделать правила, предшествующие изменениям, нетронутыми. В последствиях правила не допускайте логику NOT (отрицательные индексы MF) или пустые переменные (нулевые индексы MF).
for i = 1:numel(rule) rule(i).Antecedent.Free = false; rule(i).Consequent.AllowNot = false; rule(i).Consequent.AllowEmpty = false; end
Сгенерируйте данные для настройки.
x = (0:0.1:2*pi)'; y = sin(x);
Чтобы настроить параметры правила, используйте пользовательскую функцию customtunefis
включенный в конец этого примера. Установите количество итераций равным 2 и не допускайте недопустимых значений параметров при обновлении FIS с помощью setTunableValues
.
numite = 2; ignoreinvp = false; fisout = customtunefis(fisin,rule,x,y,numite,ignoreinvp);
Initial cost = 1.170519 Iteration 1: Cost = 0.241121 Iteration 2: Cost = 0.241121
Отображение настроенных правил.
fisout.Rules
ans = 1x5 fisrule array with properties: Description Antecedent Consequent Weight Connection Details: Description ________________________________ 1 "input1==mf1 => output1=mf4 (1)" 2 "input1==mf2 => output1=mf5 (1)" 3 "input1==mf3 => output1=mf3 (1)" 4 "input1==mf4 => output1=mf1 (1)" 5 "input1==mf5 => output1=mf2 (1)"
Разрешить НЕ логику в правилах и снова оптимизировать FIS.
for i = 1:numel(rule) rule(i).Consequent.AllowNot = true; end fisout = customtunefis(fisin,rule,x,y,numite,ignoreinvp);
Initial cost = 1.170519 Iteration 1: Cost = 0.357052 Iteration 2: Cost = 0.241121
fisout.Rules
ans = 1x5 fisrule array with properties: Description Antecedent Consequent Weight Connection Details: Description ________________________________ 1 "input1==mf1 => output1=mf4 (1)" 2 "input1==mf2 => output1=mf5 (1)" 3 "input1==mf3 => output1=mf3 (1)" 4 "input1==mf4 => output1=mf1 (1)" 5 "input1==mf5 => output1=mf2 (1)"
Использование логики NOT создает больше комбинаций параметров правил, что приводит к большему количеству итераций для настройки FIS.
Далее сбросьте AllowNot
на false
и установите AllowEmpty
на true
. Другими словами, допустим отсутствие переменных (нулевых выходных индексов MF) в последующих. Настройте FIS с помощью обновленных настроек параметра rule.
for i = 1:numel(rule) rule(i).Consequent.AllowNot = false; rule(i).Consequent.AllowEmpty = true; end try fisout = customtunefis(fisin,rule,x,y,numite,ignoreinvp); catch me disp("Error: "+me.message) end
Initial cost = 1.170519
Error: Rule consequent must have at least one nonzero membership function index.
Процесс настройки завершается неуспешно, поскольку FIS содержит только один выход, который должен быть ненулевым (непустым) в последующем правиле. Чтобы игнорировать недопустимые значения параметров, задайте IgnoreInvalidParameters
с setTunableValues
.
Задайте ignoreinvp
на true
, который задает IgnoreInvalidParameters
значение в вызове setTunableValues
используется в customtunefis
.
ignoreinvp = true; fisout = customtunefis(fisin,rule,x,y,numite,ignoreinvp);
Initial cost = 1.170519 Iteration 1: Cost = 0.241121 Iteration 2: Cost = 0.241121
fisout.Rules
ans = 1x5 fisrule array with properties: Description Antecedent Consequent Weight Connection Details: Description ________________________________ 1 "input1==mf1 => output1=mf4 (1)" 2 "input1==mf2 => output1=mf5 (1)" 3 "input1==mf3 => output1=mf3 (1)" 4 "input1==mf4 => output1=mf1 (1)" 5 "input1==mf5 => output1=mf2 (1)"
В этом случае процесс настройки обходит недопустимые значения и использует только допустимые значения параметров для оптимизации.
По умолчанию tunefis
игнорирует недопустимые значения при обновлении нечетких системных параметров. Изменить это поведение можно путем установки tunefisOptions.IgnoreInvalidParameters
на false
.
function cost = customcostfcn(fis,x,y) tY = evalfis(fis,x); sincosx = tY(:,1)+tY(:,2); sincosexpx = sincosx.*tY(:,3); actY = [sincosx;sincosexpx]; d = y(:)-actY; cost = sqrt(mean(d.*d)); end
function fis = customtunefis(fis,rule,x,y,n,ignore) % Show the initial cost. cost = findcost(fis,x,y); fprintf('Initial cost = %f\n',cost); % Optimize the rule parameters. numMFs = numel(fis.Outputs.MembershipFunctions); for ite = 1:n for i = 1:numel(rule) % Get the consequent value. pval = getTunableValues(fis,rule(i)); % Loop through the output MF indices to minimize the cost. % Use the output indices according to AllowNot and AllowEmpty. allowNot = rule(i).Consequent.AllowNot; allowEmpty = rule(i).Consequent.AllowEmpty; if allowNot && allowEmpty mfID = -numMFs:numMFs; elseif allowNot && ~allowEmpty mfID = [-numMFs:-1 1:numMFs]; elseif ~allowNot && allowEmpty mfID = 0:numMFs; else mfID = 1:numMFs; end cost = 1000; minCostFIS = fis; for j = 1:length(mfID) % Update the consequent value. pval(1) = mfID(j); % Set the consequent value in the FIS. fis = setTunableValues(fis,rule(i),pval,'IgnoreInvalidParameters',ignore); % Evaluate cost. rmse = findcost(fis,x,y); % Update the FIS with the minimum cost. if rmse<cost cost = rmse; minCostFIS = fis; end end fis = minCostFIS; end fprintf('Iteration %d: Cost = %f\n',ite,cost); end end
function cost = findcost(fis,x,y) actY = evalfis(fis,x); d = y - actY; cost = sqrt(mean(d.*d)); end