The ModelFeatures provides a common way of defining the layout of a model. This is
used to define the number of input features, the number of hidden layers, the number of
hidden features, and the number of output features.
The ModelFormat type enumerates the various formats a neural network may take, either
shallow or deep, providing a unified interface for accessing the number of hidden features
and layers in the model. This is done largely for simplicity, as it eliminates the need to
define a particular type of network as its composition has little impact on the actual
requirements / algorithms used to train or evaluate the model (that is, outside of the
obvious need to account for additional hidden layers in deep configurations). In other
words, both shallow and deep networks are requried to implement the same traits and
fulfill the same requirements, so it makes sense to treat them as a single type with
different configurations. The differences between the networks are largely left to the
developer and their choice of activation functions, optimizers, and other considerations.
The ModelLayout trait defines an interface for object capable of representing the
layout; i.e. the number of input, hidden, and output features of a neural network model
containing some number of hidden layers.