%% Body Fat Estimation
% This example illustrates how a function fitting neural network can estimate body fat percentage based on anatomical measurements.
%% The Problem: Estimate Body Fat Percentage
% In this example we attempt to build a neural network that can estimate the body fat percentage of a person described by thirteen physical attributes:
% Age (years)
% Weight (lbs)
% Height (inches)
% Neck circumference (cm)
% Chest circumference (cm)
% Abdomen circumference (cm)
% Hip circumference (cm)
% Thigh circumference (cm)
% Knee circumference (cm)
% Ankle circumference (cm)
% Biceps (extended) circumference (cm)
% Forearm circumference (cm)
% Wrist circumference (cm)
% This is an example of a fitting problem, where inputs are matched up to associated target outputs, and we would like to create a neural network which not only estimates the known targets given known inputs, but can also generalize to accurately estimate outputs for inputs that were not used to design the solution.
%% Why Neural Networks?
% Neural networks are very good at function fit problems. A neural network with enough elements (called neurons) can fit any data with arbitrary accuracy. They are particularly well suited for addressing nonlinear problems. Given the nonlinear nature of real world phenomena, like body fat accretion, neural networks are a good candidate for solving the problem.
% The thirteen physical attributes will act as inputs to a neural network, and the body fat percentage will be the target.
% The network will be designed by using the anatomical quantities of bodies whose body fat percentage is already known to train it to produce the target valuations.
%% Preparing the Data
% Data for function fitting problems are set up for a neural network by organizing the data into two matrices, the input matrix X and the target matrix T.
% Each ith column of the input matrix will have thirteen elements representing a body with known body fat percentage.
% Each corresponding column of the target matrix will have one element, representing the body fat percentage.
% Here such a dataset is loaded.

[X,T] = bodyfat_dataset;

%
% We can view the sizes of inputs X and targets T.
% Note that both X and T have 252 columns. These represent 252 physiques (inputs) and associated body fat percentages (targets).
% The input matrix X has thirteen rows, for the thirteen attributes. The target matrix T has only one row, as for each example we only have one desired output, the body fat percentage.

size(X)
size(T)

%
%% Fitting a Function with a Neural Network
% The next step is to create a neural network that will learn to estimate body fat percentages.
% Since the neural network starts with random initial weights, the results of this example will differ slightly every time it is run. The random seed is set to avoid this randomness. However this is not necessary for your own applications.

setdemorandstream(491218382)

%
% Two-layer (i.e. one-hidden-layer) feed forward neural networks can fit any input-output relationship given enough neurons in the hidden layer. Layers which are not output layers are called hidden layers.
% We will try a single hidden layer of 15 neurons for this example. In general, more difficult problems require more neurons, and perhaps more layers. Simpler problems require fewer neurons.
% The input and output have sizes of 0 because the network has not yet been configured to match our input and target data. This will happen when the network is trained.

net = fitnet(15);
view(net)

%
%
% Now the network is ready to be trained. The samples are automatically divided into training, validation and test sets. The training set is used to teach the network. Training continues as long as the network continues improving on the validation set. The test set provides a completely independent measure of network accuracy.
% The Neural Network Training Tool shows the network being trained and the algorithms used to train it. It also displays the training state during training and the criteria which stopped training will be highlighted in green.
% The buttons at the bottom open useful plots which can be opened during and after training. Links next to the algorithm names and plot buttons open documentation on those subjects.

[net,tr] = train(net,X,T);

%
%
% To see how the network's performance improved during training, either click the "Performance" button in the training tool, or call PLOTPERFORM.
% Performance is measured in terms of mean squared error, and shown in log scale. It rapidly decreased as the network was trained.
% Performance is shown for each of the training, validation, and test sets. The final network is the network that performed best on the validation set.

plotperform(tr)

%
%% Testing the Neural Network
% The mean squared error of the trained neural network can now be measured with respect to the testing samples. This will give us a sense of how well the network will do when applied to data from the real world.

testX = X(:,tr.testInd);
testT = T(:,tr.testInd);

testY = net(testX);

perf = mse(net,testT,testY)

%
% Another measure of how well the neural network has fit the data is the regression plot. Here the regression is plotted across all samples.
% The regression plot shows the actual network outputs plotted in terms of the associated target values. If the network has learned to fit the data well, the linear fit to this output-target relationship should closely intersect the bottom-left and top-right corners of the plot.
% If this is not the case then further training, or training a network with more hidden neurons, would be advisable.

Y = net(X);

plotregression(T,Y)

%
% Another third measure of how well the neural network has fit data is the error histogram. This shows how the error sizes are distributed. Typically most errors are near zero, with very few errors far from that.

e = T - Y;

ploterrhist(e)

%
% This example illustrated how to design a neural network that estimates the body fat percentage from physical characteristics.
% Explore other examples and the documentation for more insight into neural networks and their applications.
%
% Copyright 2012 The MathWorks, Inc.