IST - Física HowTo - Informática 14:34
2025-12-22
  Programação
 
     Matlab
 
        Pacotes (Toolboxes)
 
           Neural Network
 
              Rede neural
 
              Métodos e funções
 
              Treino
 
              linearlayer
 
              nntraintool
 
              Deep learning
 
              Backpropagation
 
              Redes dinâmicas
 

Neural Network Toolkit - Redes dinâmicas

Sumário
1. Introdução
2. Exemplos de redes dinâmicas com atraso e feedback
3. Rede Dinâmica Digital em Camadas (LDDN) - Definição
4. Redes neurais de atraso temporal em séries temporais na primeira entrada (FTDNN)
5. Redes neurais de atraso distribuído em séries temporais (TDNN)
6. Redes Neurais de Feedback NARX de Séries Temporais
7. Redes Neurais Recorrentes em Camadas
8. Criar Controlador de Modelo de Referência
9. Redes Neurais Dinâmicas usando Várias Sequências
10. Como treinar redes neurais com pesos de erro
11. Normalização dos erros de múltiplas saídas
12. Previsão de Redes Neurais Multietapas
13. Links úteis
Início

1. Introdução

Redes dinâmicas são aquelas em que as saídas não só dependem da rede inicial mas também das entradas, das saídas, dos estados actuais ou dos anteriores da rede.
Note-se que, ao contrário, as rede estáticas não têm elementos de feedback nem atrasos.
Início

2. Exemplos de redes dinâmicas com atraso e feedback

Seja o vector de entrda:
p = {0 0 1 1 1 1 0 0 0 0 0 0};
e criemos a seguinte rede estática e visualemo-la:
net = linearlayer;
net.inputs{1}.size = 1;
net.layers{1}.dimensions = 1;
net.biasConnect = 0;
net.IW{1,1} = 2;
view(net);
a = net(p);
a -> {0 0 2 2 2 2 0 0 0 0 0 0}
Seja agora uma rede com um atraso na entrada (redes dinâmicas feedforward):
net = linearlayer([0 1]);
net.inputs{1}.size = 1;
net.layers{1}.dimensions = 1;
net.biasConnect = 0;
net.IW{1,1} = [1 1];
view(net);
a = net(p);
a -> {0 0 1 2 2 2 1 0 0 0 0 0}
Finalmente seja agora uma rede realimentação (feedback) com séries temporais [NARX] (rede dinâmicas recorrentes). A função que a cria é então narxnet
net = narxnet(0,1,[],'closed');
net.inputs{1}.size = 1;
net.layers{1}.dimensions = 1;
net.biasConnect = 0;
net.LW{1} = 0.5;
net.IW{1} = 1;
view(net);
a = net(p);
a -> {0 0 1 1.5 1.75 1.875 0.9375 0.4688 0.2344 0.1172 0.0586 0.0293}
Note-se que as redes dinâmicas recorrentes têm normalmente uma resposta mais longa do que as redes dinâmicas feedforward. Para redes lineares, as redes dinâmicas feedforward são designadas por resposta ao impulso finita (FIR, Finite Impulse Response), uma vez que ficam nulas num tempo finito; enquanto as redes dinâmicas recorrentes lineares são chamadas de resposta ao impulso infinita (IIR, Infinite Impulse Response), pois, o valor vai apenas tendendo para zero.

As redes dinâmicas, como vimos, uma vez que têm realimentação, logo têm memória, assim são indicadas para analisar padrões sequenciais ou séries variáveis no tempo.

Início

3. Rede Dinâmica Digital em Camadas (LDDN) - Definição

Uma Rede Dinâmica Digital em Camadas (LDDN, Layered Digital Dynamic Network) caracteriza-se por, cada camada ser composta por:
  • Conjunto de matrizes de pesos que entram na camada, regra de função de peso utilizada para combinar a matriz dos pesos com a sua entrada (normalmente multiplicação "dotprod") e linha de atraso de derivação associada;
  • Um vector de viés (bias);
  • Regra de função de entrada de rede que é utilizada para combinar as saídas das várias funções de peso com o viés (bias) para produzir a entrada de rede (normalmente uma junção somadora "netprod")
  • Função de transferência
O software Neural Network Toolbox pode ser utilizado para treinar qualquer LDDN, desde que as funções de peso, funções de entrada líquida e funções de transferência têm derivadas.
A eficiência do cálculo do gradiente depende fortemente do desempenho dos algoritmos. Os pesos podem ter dois efeitos na saída, o directo e o indirecto, e isso complica mais o cálculo dos mínimos e. para evitar cair em mínimos locais, é conveniente fazer vários testes de treino.
Início

4. Redes neurais de atraso temporal em séries temporais na primeira entrada (FTDNN)

Vamos começar pela rede dinâmica mais simples: uma rede de alimentação directa com uma linha de atraso ligada à entrada, isto é, uma rede neural de atraso focalizada (FTDNN, focused Time-Delay Neural Network). Faz parte de uma classe mais geral de redes dinâmicas, denominadas redes focalizadas, em que a dinâmica surge apenas na camada de entrada de uma rede de alimentação direta multicamada estática.
Como exemplo, sejam os dados de intensidade registados por um laser de infravermelho distante em estado caótico (dados normalizados) [dados de "Competição de Séries Temporais de Santa Fé"]. O objectivo é, a partir dos 1000 primeiros pontos da série temporal, prever os pontos seguintes. Vamos agora limitarmo-nos apenas ao ponto seguinte. (Pode usar-se a rede resultante para previsões vários passos à frente.)
Comecemos por carregar os dados e convertê-los numa série temporal. Depois criar uma rede FTDNN com a função timedelaynet que é uma função análoga a feedforwardnet com uma entrada adicional para o vector de atraso. A seguir organizar as entradas, os atrasos e os alvos. Como rede possui uma linha de atraso com derivação com um atraso máximo de 8, começa-se por prever o nono valor da série.
y = laser_dataset;Carregar os dados
y = y(1:600);Escolher os primeiros 600 para os cálculos
net = timedelaynet([1:8],10);Criação de uma rede FTDNN com linha de atraso com derivação com atrasos de 1 a 8 e 10 neurónios na camada oculta;
net.trainParam.epochs = 1000;Definir o número máximo de iterações;
net.divideFcn = '';Não se define função de divisão dos dados;
p = y(9:end);Entradas do nono até ao fim;
t = y(9:end);Alvos do nono até ao fim;
Pi=y(1:8);Valores iniciais para o atraso;
net = train(net,p,t,Pi);Treino da rede
Note-se que a entrada para a rede é a mesma que a do alvo. Como a rede tem um atraso mínimo de um passo de tempo, isto significa que está a realizar uma previsão um passo à frente.
Pode-se agora o erro da previsão:
yp = net(p,Pi);Geração das saídas a partir das entradas;
e = gsubtract(yp,t)Calculo o erro subtraindo as saídas aos lavos;
rmse = sqrt(mse(e))Cálulo da raiz quadrada do erro quadrático médio normalizado;
rmse -> 0.9740Resultado da operação anterior.
Como se pode ver pelo cálculo que se segue, este resultado do erro é muito melhor do que se usasse a função linearlayer:
net1 = linearlayer([1:8]);Criação a rede linear
net1.trainFcn='trainlm';Escolha da função de treino
[net1,tr] = train(net1,p,t,Pi);Treino
yp1 = net1(p,Pi);Geração das saídas a partir das entradas;
e1 = gsubtract(yp1,t);Calculo o erro subtraindo as saídas aos lavos;
rmse1 = sqrt(mse(e1))Cálulo da raiz quadrada do erro quadrático médio normalizado;
rmse1 -> 21.1386Resultado da operação anterior.
Uma característica importante das FTDNN é que não requerem retropropagação dinâmica para calcular o gradiente da rede, porque a linha de atraso tocada aparece apenas na entrada da rede e não contém loops de feedback ou parâmetros ajustáveis, assim, este tipo de rede treina mais rapidamente do que outras redes dinâmicas.
Como se pode ver por este exemplo simples, as redes dinâmicas exigem uma maior preparação na introdução dos dados, pois, é necessário ter em conta as como os dados iniciais são organizados. Para o simplificar pode usar-se a função preparets (Ver: Funções de preparação dos dados). Assim, as anteriores linhas de comandos:
p = y(9:end);Entradas do nono até ao fim;
t = y(9:end);Alvos do nono até ao fim;
Pi=y(1:8);Valores iniciais para o atraso;
podem ser substituídas por
[p, Pi, Ai, t] = preparets (net, y, y);
em que Ai são as saídas iniciais da camada para carregar as linhas de atraso derivadas para os pesos da camada.
Início

5. Redes neurais de atraso distribuído em séries temporais (TDNN)

Como se viu as FTDNN tem a memória da linha de atraso com derivação apenas na entrada da primeira camada. Agora vanos ver as redes em que os atrasos podem ser encontrados em qualquer camada, isto é, redes neurais de atraso distribuído em séries temporais (TDNN).
Este tipo de redes podem ser usados no reconhecimento de fonemas. Se uma rede simplicada que procurará reconhecer o conteúdo de frequência de um sinal de entrada. Esta rede pode ser utilizada para um problema simplificado semelhante ao reconhecimento de fonemas.
Seja então uma rede com duas camadas ambas com viés e atraso. A saída alvo é 1 quando a entrada está abaixo e -1 quando a entrada está acima.
time = 0:99;Tempo de 0 a 99
y1 = sin(2*pi*time/10); Função seno de frequência 0.1
y2 = sin(2*pi*time/5); Função seno de frequência 0.2
y = [y1 y2 y1 y2]; Junção dos sinais anteriores
t1 = ones(1,100); Alvo para 'y1' (frequência 0.1)
t2 = -ones(1,100); Alvo para 'y2' (frequência 0.2)
t = [t1 t2 t1 t2]; junção dos alvos anteriores
Os atrasos vão ser de 0 a 4 na primeira camada e de 0 a 3 na segunda. A função de treino irá ser trainbr.
d1 = 0:4;Atraso de 0 a 4 na primeira camada
d2 = 0:3;Atraso de 0 a 3 na segunda camada
p = con2seq(y);Converte o vector 'y' para um vector de células
t = con2seq(t);Converte o vector 'y' para um vector de células
net = distdelaynet({d1,d2},5);Cria a rede
net.trainFcn = 'trainbr';Define a função de treino a utilizar
net.divideFcn = '';Não se define função de divisão dos dados
net.trainParam.epochs = 100;Define o número máximo de iterações
net = train(net,p,t);Executa o treico da rede
yp = sim(net,p);Simula a rede
plotresponse(t,yp);Faz o gráfico dos alvos e respostas da rede
Início

6. Redes Neurais de Feedback NARX de Séries Temporais

Uma rede autoregressiva não linear com entradas exógenas (NARX, Nonlinear AutoRegressive network with eXogenous inputs) é uma rede dinâmica recorrente, com ligações de feedback envolvendo várias camadas da rede, definida por uma função "f" que depende de atrasos e feedbacks. Pode implementar-se o modelo NARX utilizando uma rede neural feedforward para aproximar a função "f".
Assim, uma vez que a saída de um sinal vai realimentar a entrada, podemos substituir a saída pelo sinal corespondente na rede de entrada, tal torna o treino mais fiável e por outro lado torna a rede assim formada numa rede feedforward. Ou seja, transformamos uma rede de arquitectura paralela num rede de arquitectura série-paralela.
Como exemplo, vão se usados os dados de levitação magnética: posição do íman permanente "y(t)" e tensão aplicada "u(t)". Criamos uma rede NARX série-paralela com 10 neurónios na camada oculta e vamos fazer o treino com a função trainlm e dão-se os dados das entradas:
load magdata;Carrega os dados magnéticos
y = con2seq(y); Converte o vector num vector de células
u = con2seq(u); Converte o vector num vector de células
d1 = [1:2];Atrasos na entrada
d2 = [1:2];Atrasos no feedback
net = narxnet (d1, d2, 10); Cria rede neural 'NARX'
net.divideFcn = '';Não define função de divisão dos dados
net.trainParam.min_grad = 1e-10;Valor mínimo do gradiente para parar o treino
[p, Pi, Ai, t] = preparets (net, u, {}, y); Prepara os dados
net = train (net, p, t, Pi); Executa o treino
Note-se que y(t), que é o vector alvo, vai ser a entrada de feedback. Depois do treino, a rede vai ser alterada para paralela e passa a alimentda pelo valor de saída.
Feito o treino, podemos ver os erros da implementação série-paralelo.
yp = sim (net,p,Pi); Simula a rede neural
e = cell2mat(yp) - cell2mat(t); Calcula a diferença entre a saída e o alvo
plot (e);Mostra o gráfico
Pode ver-se que os erros são pequenos mas, atenção, estamos a usar a configuração série-paralelo. Para melhorar o teste é preciso reorganizar a rede série-paralela (loop aberto) para paralela (loop fechado). A função closeloop faz isso. Assim, passemos à rede paralela e calculemos novamente os erros:
view (net);Visualiza a rede antes de a transformar
net_closed = closeloop (net); Converte a rede loop aberto em loop fechado
view (net_closed);Visualiza a rede depois de transformada
Em resumo, o treino de uma rede deste tipo deve ser feito em loop aberto incluindo validação e teste. Só depois é que se deve passar à rede de loop fechado. Não esquecer que se deve usar a função preparets para fazer preparar os dados para esta nova configuração.
Note-se que se pode criar uma rede de loop fechado directamente a partir narxnet, basta para isso por acrescentar um quarto argumento: "close". Normalmente leva mais tempo e o resultado é pior...
Assim, por exemplo, se quisermos realizar uma previsão iterada de 900 passos de tempo:
y1 = y(1700:2600);
u1 = u(1700:2600);
[p1, Pi1, Ai1, t1] = preparets (net_closed, u1, {}, y1);
yp1 = net_closed(p1, Pi1, Ai1);
TS = size(t1, 2);
plot (1:TS, cell2mat(t1), 'b', 1:TS, cell2mat(yp1), 'r')
Aqui estudou-se o caso de um único valor de entrada. No entanto, não limita que possa haver múltiplos elementos. A título de exemplo veja se um caso com dois elementos na entrada com os de PH:
[X,T] = ph_dataset;Lê os dados de PH
net = narxnet (10); Cria uma rede de loop aberto
[x, xi, ai, t] = preparets (net, X, {}, T); Prepara os dados
net = train (net,x,t,xi,ai); Executa o treino
y = net(x, xi, ai);Obtém os saídas da rede
e = gsubtract (t,y); Calcula o erro na saída
plot (cell2mat(e))mostra o gráfico
Início

7. Redes Neurais Recorrentes em Camadas

Uma Rede Recorrente em Camadas (LRN, Layer-Recurrent Network) é uma rede neural multicamada com um loop de realimentação, com um único atraso, em cada camada excepto na última. Estas redes podem ser usadas em aplicações de filtragem e modelagem. Pode ser criação com o comando layrecnet.
Seja um exemplo com fonemas:
load phoneme;Carrega os dados de fonemas
p = con2seq (y); Converte o vector num vector de células
t = con2seq (t); Converte o vector num vector de células
net = layrecnet (1, 8);Cria rede neural 'LRN'
net.trainFcn = 'trainbr';Define a função de treino a utilizar
net.trainParam.show = 5;Mostra os dados do treino de 5 em 5 iterações
net.trainParam.epochs = 50;Define o número máximo de iterações
net = train (net, p, t);Executa o treino
y = net(p);Gera as saídas
plot(cell2mat(y));Faz o gráfico
Início

8. Criar Controlador de Modelo de Referência

Vamos aqui ver como se pode criar uma rede personalizada.
Como se poderá ver mais à frente em "Projetar Controlador Neural de Referência de Modelo no Simulink", uma arquitectura de controle pode ser representada por duas sub-redes: uma é o modelo a controlar; a outra é o controlador. Esta arquitetura é o sistema de controle adaptativo de referência de modelo (MRAC). Primeiro treina a rede modelo.
No exemplo aqui apresentado, são carregados os dados do braço robótico para criar e treinar uma rede NARX (ver: nnet_04_07__MRAC.m).
[u, y] = robotarm_dataset; Carrega os dados do braço robótico
d1 = [1:2];Atrasos na entrada
d2 = [1:2];Atrasos no feedback
S1 = 5;Tamanho da camada oculta
narx_net = narxnet (d1, d2, S1); Cria rede neural 'NARX' em loop aberto
view (narx_net)Visualiza a rede em loop aberto
narx_net.divideFcn = '';Não define função de divisão dos dados
narx_net.inputs{1}.processFcns = {};Não define função de pré-processamento da camada "1"
narx_net.inputs{2}.processFcns = {};Não define função de pré-processamento da camada "2"
narx_net.outputs{2}.processFcns = {};Não define função de pós-processamento da camada "2"
narx_net.trainParam.min_grad = 1e-10;Valor mínimo do gradiente para parar
[p, Pi, Ai, t] = preparets (narx_net, u, {}, y);Prepara os dados
narx_net = train (narx_net, p, t, Pi); Executa o treino
narx_net_closed = closeloop (narx_net); Converte a rede loop aberto em loop fechado
view (narx_net_closed)Visualiza a rede em loop fechado
Uma vez treinado o modelo NARX, vamos criar o sistema MRAC. Para tal é necessário criar o controlador, juntá-lo com a rede do modelo treinada e treinar agora apenas o controlador.
Vamos agora criar o sistema MRAC com um controlador: cria-se uma rede feedforward com três camadas ocultas em loop fechado com atrasos
mrac_net = feedforwardnet ([S1 1 S1]); Cria rede neural feedforward
mrac_net.layerConnect = [0 1 0 1 ; 1 0 0 0 ; 0 1 0 1 ; 0 0 1 0]; Estabelece as ligações entre as camadas
mrac_net.outputs{4}.feedbackMode = 'closed'; Indica que a rede está em loop fechado
mrac_net.layers{2}.transferFcn = 'purelin'; Define a função de transferência da camada "2"
mrac_net.layerWeights{3,4}.delays = 1:2; Define os atrasos da camada "4" (output) para a "3"
mrac_net.layerWeights{3,2}.delays = 1:2; Define os atrasos da camada "2" para a "3"
mrac_net.layerWeights{3,2}.learn = 0; Marca-se para não alterar no treino o peso da camada "2" para a "3"
mrac_net.layerWeights{3,4}.learn = 0; Marca-se para não alterar no treino o peso da camada "4" para a "3"
mrac_net.layerWeights{4,3}.learn = 0; Marca-se para não alterar no treino o peso da camada "3" para a "4"
mrac_net.biases{3}.learn = 0; Marca-se para não alterar no treino o peso do viés da camada "3"
mrac_net.biases{4}.learn = 0; Marca-se para não alterar no treino o peso do viés da camada "4"
mrac_net.divideFcn = '';Não define função de divisão dos dados
mrac_net.inputs{1}.processFcns = {}; Não define funções de pré-processamento na camada "1"
mrac_net.outputs{4}.processFcns = {}; Não define funções de pós-processamento na camada "4"
mrac_net.name = 'Model Ref. Adaptive Control';Atribui um nome à rede
mrac_net.layerWeights{1,2}.delays = 1:2; Define os atrasos da camada "2" para a "1"
mrac_net.layerWeights{1,4}.delays = 1:2; Define os atrasos da camada "4" para a "1"
mrac_net.inputWeights{1}.delays = 1:2; Define o atraso na camada inicial
São necessários dados de treinamento para configurar a rede:
[refin,refout] = refmodel_dataset;
ind = 1:length(refin);
plot (ind, cell2mat(refin), ind, cell2mat(refout))
mrac_net = configure (mrac_net, refin, refout);
Vamos agora inserir os pesos do modelo da planta treinada ("narx_net_closed"), ou seja, as camadas "3" e "4" vão ser substituídas pelas camadas "1" e "2" da rede do modelo. Por outras palavras: as camadas "3" e "4" são a sub-rede do modelo e as camadas "1" e "2" o controlador:
mrac_net.LW{3,2} = narx_net_closed.IW{1};
mrac_net.LW{3,4} = narx_net_closed.LW{1,2};
mrac_net.b{3} = narx_net_closed.b{1};
mrac_net.LW{4,3} = narx_net_closed.LW{2,1};
mrac_net.b{4} = narx_net_closed.b{2};
Podemos definir os pesos de saída da rede do controlador como "0" o que dará à planta uma entrada inicial de zero:
mrac_net.LW{2,1} = zeros(size(mrac_net.LW{2,1}));
mrac_net.b{2} = 0;
Também se podem associar gráficos e funções de treino e visualizá-la:
mrac_net.plotFcns = {'plotperform', 'plottrainstate', 'ploterrhist', 'plotregression', 'plotresponse'};
mrac_net.trainFcn = 'trainlm';
view(mrac_net)
Falta fazer o treino do controlador:
[x_tot, xi_tot, ai_tot, t_tot] = preparets (mrac_net, refin, {}, refout); Preparação dos dados
mrac_net.trainParam.epochs = 50;Número de iterações
mrac_net.trainParam.min_grad = 1e-10;Valor mínimo do gradiente para parar
[mrac_net, tr] = train (mrac_net, x_tot, t_tot, xi_tot, ai_tot);Executa o treino
O treino desta rede é mais demorado, pois, é uma rede é recorrente e a retropropagação dinâmica deve ser usada. Isto é determinado automaticamente, pelo que não requer qualquer acção específica.
Podemos agora testar a rede:
testin = skyline (1000, 50, 200, -.7, .7);
testinseq = con2seq (testin);
testoutseq = mrac_net(testinseq);
testout = cell2mat (testoutseq);
figure
plot([testin' testout'])
Início

9. Redes Neurais Dinâmicas usando Várias Sequências

É, por vezes, conveniente fornecer diversas sequências de dados separados para treinar ou obter valores de uma rede. Quando se treina uma rede como diversas sequências é necessário garantir que têm todas o mesmo tamanho. Para tal acrescentam-se NaN (None a Number) para ficarem todas iguais. Vejamos como se podem organizar:
load magmulseq;% Carrega as sequências
y_mul = catsamples (y1, y2, y3, 'pad'); % Junta as sequências
u_mul = catsamples (u1, u2, u3, 'pad'); % Junta as sequências
d1 = [1:2];% Atrasos na entrada
d2 = [1:2];% Atrasos no feedback
narx_net = narxnet (d1, d2, 10); % Cria rede neural 'NARX' em loop aberto
narx_net.divideFcn = '';% Não define função de divisão dos dados
narx_net.trainParam.min_grad = 1e-10;% Valor mínimo do gradiente para parar
[p, Pi, Ai, t] = preparets (narx_net, u_mul, {}, y_mul); % Prepara os dados
narx_net = train (narx_net, p, t, Pi); % Executa o treino
Início

10. Como treinar redes neurais com pesos de erro

Na função de desempenho padrão de erro quadrático médio, cada erro quadrático (mse) contribui igualmente para a função de desempenho da seguinte: \[F = mse = {1 \over N}\,\sum_{k=1}^N\,e_k^2 = {1 \over N}\,\sum_{k=1}^N\,(t_k - a_k)^2\] mas, podemos querer ponderar cada erro quadrático individualmente: \[F = mse = {1 \over N}\,\sum_{k=1}^N\,w_k^e\,e_k^2 = {1 \over N}\,\sum_{k=1}^N\,w_k^e\,(t_k - a_k)^2\] Note-se, no entanto, que a ponderação do erro tem de manter as mesmas dimensões que os dados, isto é, na prática os "\(\bf{\color{green}{w_k^e}}\)" têm de ser adimensionais.
Exemplo em que se ponderam os erros:
y = laser_dataset; % Carrega a sequência de dados;
y = y(1:600);% Escolhem-se as 600 primeiras entradas;
ind = 1:600;% Cria-se um vector com os valores 1 a 600;
ew = 0.99.^(600-ind);% Define o pesos de cada erro;
figure;% Cria-se uma figura;
plot(ew);% faz-se o gráfico dos pesos dos erros;
ew = con2seq (ew); % Converte o vector num vector de células;
ftdnn_net = timedelaynet ([1:8], 10); % Cria-se a rede com atraso;
ftdnn_net.trainParam.epochs = 1000;% Definir o número máximo de iterações;
ftdnn_net.divideFcn = '';% Não se define função de divisão dos dados;
[p, Pi, Ai, t, ew1] = preparets (ftdnn_net, y, y, {}, ew); % Prepara os dados
[ftdnn_net1, tr] = train(ftdnn_net, p, t, Pi, Ai, ew1); % Executa o treino
Início

11. Normalização dos erros de múltiplas saídas

A função de desempenho mais comum utilizada para treinar redes neuronais é o erro quadrático médio (EQM). Quando há saídas com valores muito diferentes em valor absoluto, os erros dos valores pequenos são quase ignorados. Por exemplo (Ver nnet_04_09__MRAC.m):
x = -1:0,01:1;
t1 = 100*sin(x);
t2 = 0,01*cos(x);
t = [t1; t2];
net = feedforwardnet(5);
net1 = train(net,x,t);
y = net1(x);
figura(1);
plot(x,y(1,:),x,t(1,:));
figure(2);
plot(x,y(2,:),x,t(2,:));
Para que os elementos de saída sejam tratados de igual modo, faz-se a sua normalização para o intervalo [-1, 1]. Tal é feito, definindo parâmetro de desempenho da normalização em 'standard' (net.performParam.normalization).
net.performParam.normalization = 'standard';
net2 = train(net,x,t);
y = net2(x);
figura(3);
plot(x,y(1,:),x,t(1,:));
figure(4);
plot(x,y(2,:),x,t(2,:));
Início

12. Previsão de Redes Neurais Multietapas

Como se viu, as rede dinâmicas com feedback (narxnet, narnet, ...) podem ser transformadas em loop aberto ou fechado. Por vezes, pode ser conveniente alterar entre as duas situações, por exemplo, em situações em que se estar a receber um sinal em en que este último pode ser fiável ou não para a simulação.
Recapitulemos o que se viu sobre o treino em situação de loop aberto, com os dados da levitação magnética:
[X,T] = maglev_dataset;
net = narxnet (1:2, 1:2, 10);
[x, xi, ai, t] = preparets(net, X, {}, T);
net = train (net, x, t, xi, ai);
y = net(x, xi, ai);
view(net);
Podemos agora passá-la a rede de loop fechado, usar os dados para fazer previsões para uma qualquer série de entrada e de estados iniciais:
netc = closeloop (net);
view (netc);
[x, xi, ai, t] = preparets (netc, X, {}, T);
yc = netc(x, xi, ai);
Também se pode desejar pegar nesta rede já treinada em loop aberto e, passá-la a modo fechado para continuar a simulação. Note-se que openloop como closeloop para além de alterarem a rede também convertem os estados da rede:
[open_net, open_xi, open_ai] = openloop (closed_net, closed_xi, closed_ai);
[closed_net, closed_xi, closed_ai] = closeloop (open_net, open_xi, open_ai);
Considere o caso em que pode ter um registo do comportamento do Maglev durante 20 passos de tempo e pretende prever com antecedência mais 20 passos de tempo (em modo aberto):
x1 = x(1:20);
t1 = t(1:20);
x2 = x(21:40);
[x, xi, ai, t] = preparets (net, x1, {}, t1);
[y1, xf, af] = net(x, xi, ai);
Agora, os estados finais de entrada e de camada devolvidos pela rede são convertidos para a forma de loop fechado juntamente com a rede, os quais passam a ser os estados iniciais:
[netc, xi, ai] = closeloop(net,xf,af);
[y2, xf, af] = netc(x2, xi, ai);
então, pode definir-se uma sequência de entradas e testar a rede treinada:
x2 = num2cell (rand(1, 10));
[y2, xf, af] = netc(x2, xi, ai);
pode-se agora voltar ao modo aberto (não é necessário converter a rede porque já a temos), e obter as novas saídas:
[~,xi,ai] = openloop(netc,xf,af);
x3 = num2cell (rand(2, 10));
y3 = net (x3, xi, ai);
Início