www.gusucode.com > nnet 工具箱 matlab 源码程序 > nnet/nnnetfun/closeloop.m
function [netc,xic,aic] = closeloop(neto,xio,aio) %CLOSELOOP Convert neural network open feedback to closed feedback loops. % % <a href="matlab:doc closeloop">closeloop</a>(NET) takes a network and transforms any outputs marked % as open loop (i.e. NET.<a href="matlab:doc nnproperty.net_outputs">outputs</a>{i}.<a href="matlab:doc nnproperty.output_feedbackMode">feedbackMode</a> = 'open') to closed % loop. % % This is done by replacing the input associated with the open loop % output (i.e. the input whose index is NET.<a href="matlab:doc nnproperty.net_outputs">outputs</a>{i}.<a href="matlab:doc nnproperty.output_feedbackInput">feedbackInput</a>) % with an interal layer weight connection. % % Here a NARX network is designed. The NARX network has a standard input % and an open loop feedback output to an associated feedback input. % % [X,T] = <a href="matlab:doc simplenarx_dataset">simplenarx_dataset</a>; % net = <a href="matlab:doc narxnet">narxnet</a>(1:2,1:2,10); % [Xs,Xi,Ai,Ts] = <a href="matlab:doc preparets">preparets</a>(net,X,{},T); % net = <a href="matlab:doc train">train</a>(net,Xs,Ts,Xi,Ai); % <a href="matlab:doc view">view</a>(net) % Y = net(Xs,Xi,Ai) % % Now the network is converted to closed loop form and simulated. % % netc = <a href="matlab:doc closeloop">closeloop</a>(net); % <a href="matlab:doc view">view</a>(netc) % [Xc,Xic,Aic,Tc] = <a href="matlab:doc preparets">preparets</a>(netc,X,{},T); % Y = net(Xc,Xic,Aic) % % The function <a href="matlab:doc openloop">openloop</a> reverses this transformation. % % neto = <a href="matlab:doc openloop">openloop</a>(netc); % view(neto) % % Converting Delay States % % [NET,Xi,Ai] = openloop(NET,Xi,Ai) converts a open-loop network and its % current input delay states Xi and layer delay states Ai to closed-loop form. % % For examples on using <a href="matlab:doc closeloop">closeloop</a> and <a href="matlab:doc openloop">openloop</a> to implement multistep % prediction, see <a href="matlab:doc narxnet">narxnet</a> and<a href="matlab:doc narnet">narnet</a>. % % See also OPENLOOP, NARXNET, NARNET. % Copyright 2010-2013 The MathWorks, Inc. % Check original network for zero delay loops [~,zeroDelayLoop] = nn.layer_order(neto); if zeroDelayLoop, error(message('nnet:NNet:ZeroDelayLoop')); end % Close all open loops netc = neto; for i=find(netc.outputConnect) if strcmp(netc.outputs{i}.feedbackMode,'open') j = netc.outputs{i}.feedbackInput; k = find(netc.inputConnect(:,j) & netc.layerConnect(:,i),1); if ~isempty(k) msg = ['Layer ' num2str(k) ' has both open and closed-loop connections from the same output layer.']; error('nnet:closeloop:OpenAndClosedLoop',msg); end numLayerDelaysI = 0; for k=1:netc.numLayers if netc.layerConnect(k,i) numLayerDelaysI = max(numLayerDelaysI,max(netc.layerWeights{k,i}.delays)); end end numInputDelaysJ = 0; for k=1:netc.numLayers if netc.inputConnect(k,j) numInputDelaysJ = max(numInputDelaysJ,max(netc.inputWeights{k,j}.delays)); end end if (numLayerDelaysI > 0) && (numInputDelaysJ > 0) msg = ['Layer ' num2str(i) ' has delay states to another layer and from its feedback input.']; error('nnet:closeloop:LayerAndInputDelays',msg); end netc.outputs{i}.feedbackMode = 'closed'; end end % Check closed-loop network for zero delay loops [~,zeroDelayLoop] = nn.layer_order(netc); if zeroDelayLoop, error(message('nnet:NNet:ZeroDelayLoop')); end % Return if no delay state arguments if (nargin == 1) if (nargout > 1) error('nnet:arguments:TooManyOutputArguments','Too many output arguments.'); end return elseif (nargout <= 1) return; end % Two output arguments not allowed (only 1 or 3) because % closing the loop typically creates layer states Aic. if (nargout == 2) error('nnet:arguments:NotEnoughOutputArguments','Not enough output arguments.'); end % Default Aio input argument if (nargin < 3) if (neto.numLayerDelays > 0) error('nnet:arguments:NotEnoughInputArguments','Not enough input arguments.'); else aio = cell(neto.numLayers,0); end end % Number of samples if ~isempty(xio) Q = size(xio{1},2); elseif ~isempty(aio) Q = size(aio{1},2); else Q = 0; end % Check Xio size if ~iscell(xio) || ~ismatrix(xio) || any(size(xio) ~= [neto.numInputs neto.numInputDelays]) msg = ['Xi is not a ' num2str(neto.numInputs) '-by-' num2str(neto.numInputDelays) ' cell array.']; error('nnet:data:XiNotCorrectDimensions',msg); end for i=1:neto.numInputs for j=1:neto.numInputDelays xi = xio{i,j}; if ~isnumeric(xi) || ~ismatrix(xi) || any(size(xi) ~= [neto.inputs{i}.size Q]) msg = ['Xi{' num2str(i) ',' num2str(j) '} is not a ' num2str(neto.inputs{i}.size) '-by-' num2str(Q) ' numeric array.']; error('nnet:data:IncorrectDimensions',msg); end end end % Check Aio size if ~iscell(aio) || ~ismatrix(aio) || any(size(aio) ~= [neto.numLayers neto.numLayerDelays]) msg = ['Ai is not a ' num2str(neto.numLayers) '-by-' num2str(neto.numLayerDelays) ' cell array.']; error('nnet:data:IncorrectDimensions',msg); end for i=1:neto.numLayers for j=1:neto.numLayerDelays ai = aio{i,j}; if ~isnumeric(ai) || ~ismatrix(ai) || any(size(ai) ~= [neto.layers{i}.size Q]) msg = ['Ai{' num2str(i) ',' num2str(j) '} is not a ' num2str(neto.layers{i}.size) '-by-' num2str(Q) ' numeric array.']; error('nnet:data:IncorrectDimensions',msg); end end end % Keep Non-Feedback Input States nonFeedbackInputs = true(1,neto.numInputs); for i=neto.numInputs:-1:1 nonFeedbackInputs(i) = isempty(neto.inputs{i}.feedbackOutput); end delayShift = neto.numInputDelays - netc.numInputDelays; xic = xio(nonFeedbackInputs,(1:netc.numInputDelays)+delayShift); % Allocate Layer States aic = cell(netc.numLayers,netc.numLayerDelays); for i=1:netc.numLayers aic(i,:) = {nan(netc.layers{i}.size,Q)}; end % Keep Layer States delayShift = netc.numLayerDelays - neto.numLayerDelays; aic(:,(1:neto.numLayerDelays)+delayShift) = aio; % Convert Open Feedback Input States to Layer States % by applying input processing for i=1:neto.numLayers if neto.outputConnect(i) if strcmp(neto.outputs{i}.feedbackMode,'open') j = neto.outputs{i}.feedbackInput; numDelays = min(neto.numInputDelays,netc.numLayerDelays); delayShift1 = neto.numInputDelays - numDelays; delayShift2 = netc.numLayerDelays - numDelays; for ts=1:numDelays ai = xio(j,ts+delayShift1); for k=1:length(neto.inputs{j}.processFcns) fcn = neto.inputs{j}.processFcns{k}; settings = neto.inputs{j}.processSettings{k}; ai = feval(fcn,'apply',ai,settings); end aic(i,ts+delayShift2) = ai; end end end end