wolffd@0: function [mixparams, y, z, a] = mdnfwd(net, x) wolffd@0: %MDNFWD Forward propagation through Mixture Density Network. wolffd@0: % wolffd@0: % Description wolffd@0: % MIXPARAMS = MDNFWD(NET, X) takes a mixture density network data wolffd@0: % structure NET and a matrix X of input vectors, and forward propagates wolffd@0: % the inputs through the network to generate a structure MIXPARAMS wolffd@0: % which contains the parameters of several mixture models. Each row wolffd@0: % of X represents one input vector and the corresponding row of the wolffd@0: % matrices in MIXPARAMS represents the parameters of a mixture model wolffd@0: % for the conditional probability of target vectors given the input wolffd@0: % vector. This is not represented as an array of GMM structures to wolffd@0: % improve the efficiency of MDN training. wolffd@0: % wolffd@0: % The fields in MIXPARAMS are wolffd@0: % type = 'mdnmixes' wolffd@0: % ncentres = number of mixture components wolffd@0: % dimtarget = dimension of target space wolffd@0: % mixcoeffs = mixing coefficients wolffd@0: % centres = means of Gaussians: stored as one row per pattern wolffd@0: % covars = covariances of Gaussians wolffd@0: % nparams = number of parameters wolffd@0: % wolffd@0: % [MIXPARAMS, Y, Z] = MDNFWD(NET, X) also generates a matrix Y of the wolffd@0: % outputs of the MLP and a matrix Z of the hidden unit activations wolffd@0: % where each row corresponds to one pattern. wolffd@0: % wolffd@0: % [MIXPARAMS, Y, Z, A] = MLPFWD(NET, X) also returns a matrix A giving wolffd@0: % the summed inputs to each output unit, where each row corresponds to wolffd@0: % one pattern. wolffd@0: % wolffd@0: % See also wolffd@0: % MDN, MDN2GMM, MDNERR, MDNGRAD, MLPFWD wolffd@0: % wolffd@0: wolffd@0: % Copyright (c) Ian T Nabney (1996-2001) wolffd@0: % David J Evans (1998) wolffd@0: wolffd@0: % Check arguments for consistency wolffd@0: errstring = consist(net, 'mdn', x); wolffd@0: if ~isempty(errstring) wolffd@0: error(errstring); wolffd@0: end wolffd@0: wolffd@0: % Extract mlp and mixture model descriptors wolffd@0: mlpnet = net.mlp; wolffd@0: mixes = net.mdnmixes; wolffd@0: wolffd@0: ncentres = mixes.ncentres; % Number of components in mixture model wolffd@0: dim_target = mixes.dim_target; % Dimension of targets wolffd@0: nparams = mixes.nparams; % Number of parameters in mixture model wolffd@0: wolffd@0: % Propagate forwards through MLP wolffd@0: [y, z, a] = mlpfwd(mlpnet, x); wolffd@0: wolffd@0: % Compute the postion for each parameter in the whole wolffd@0: % matrix. Used to define the mixparams structure wolffd@0: mixcoeff = [1:1:ncentres]; wolffd@0: centres = [ncentres+1:1:(ncentres*(1+dim_target))]; wolffd@0: variances = [(ncentres*(1+dim_target)+1):1:nparams]; wolffd@0: wolffd@0: % Convert output values into mixture model parameters wolffd@0: wolffd@0: % Use softmax to calculate priors wolffd@0: % Prevent overflow and underflow: use same bounds as glmfwd wolffd@0: % Ensure that sum(exp(y), 2) does not overflow wolffd@0: maxcut = log(realmax) - log(ncentres); wolffd@0: % Ensure that exp(y) > 0 wolffd@0: mincut = log(realmin); wolffd@0: temp = min(y(:,1:ncentres), maxcut); wolffd@0: temp = max(temp, mincut); wolffd@0: temp = exp(temp); wolffd@0: mixpriors = temp./(sum(temp, 2)*ones(1,ncentres)); wolffd@0: wolffd@0: % Centres are just copies of network outputs wolffd@0: mixcentres = y(:,(ncentres+1):ncentres*(1+dim_target)); wolffd@0: wolffd@0: % Variances are exp of network outputs wolffd@0: mixwidths = exp(y(:,(ncentres*(1+dim_target)+1):nparams)); wolffd@0: wolffd@0: % Now build up all the mixture model weight vectors wolffd@0: ndata = size(x, 1); wolffd@0: wolffd@0: % Return parameters wolffd@0: mixparams.type = mixes.type; wolffd@0: mixparams.ncentres = mixes.ncentres; wolffd@0: mixparams.dim_target = mixes.dim_target; wolffd@0: mixparams.nparams = mixes.nparams; wolffd@0: wolffd@0: mixparams.mixcoeffs = mixpriors; wolffd@0: mixparams.centres = mixcentres; wolffd@0: mixparams.covars = mixwidths; wolffd@0: