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