The fundamental goal of this example is to predict the noise generated by an aircraft's airfoil blades.
The variable to be predicted is continuous (sound pressure level). Therefore, this is an approximation project.
The fundamental goal is to model the sound pressure level as a function of the airfoil features and airspeed.
The first step is to prepare the data set, the source of information for the approximation problem. It is composed of:
The file airfoil_self_noise.csv contains the data for this example. Here the number of variables (columns) is 6, and the number of instances (rows) is 1503. It can be loaded as:
DataSet data_set("path_to_source/airfoil_self_noise.csv",',',true);
In that way, this problem has the 6 following variables:
The instances are divided into training, selection, and testing subsets at random, containing 60%, 20%, and 20% of the cases, respectively. More specifically, 753 samples are used here for training, 375 for validation, and 375 for testing. They can be split into random using:
data_set.split_samples_random();
Then, there will be six numerical variables in the data set. Once we have the data ready, we will get the information of the variables, such as names and statistical descriptives
const Tensor<string, 1> inputs_names = data_set.get_input_variables_names();
const Tensor<string, 1> targets_names = data_set.get_target_variables_names();
To get the input variables number and target variables number, we use the following command
const Index input_variables_number = data_set.get_input_variables_number();
const Index target_variables_number = data_set.get_target_variables_number();
For more information about the data set methods, see DataSet class.
The second step is to choose the correct neural network architecture. For approximation problems, it is usually composed by:
The NeuralNetwork class is responsible for building the neural network and properly organizing the layers of neurons using the following constructor. If you need more complex architectures, you should see NeuralNetwork class.
const Index hidden_neurons_number = 12;
NeuralNetwork neural_network(NeuralNetwork::Approximation,
{input_variables_number, hidden_neurons_number, target_variables_number});
Therefore, we have already created a good-looking model. Thus we proceed to the learning process with TrainingStrategy.
The third step is to set the training strategy, which is composed of:
Firstly, we construct the training strategy object
TrainingStrategy training_strategy(&neural_network, &data_set);
then, set the error term
training_strategy.set_loss_method(TrainingStrategy::MEAN_SQUARED_ERROR);
and finally the optimization algorithm
training_strategy.set_optimization_method(TrainingStrategy::ADAPTIVE_MOMENT_ESTIMATION);
OpenNN builds by default the training strategy object using the quasi-Newton method as the optimization algorithm and normalized squared error as the loss method. We can now start the training process by using the command
training_strategy.perform_training();
If we need to go further, OpenNN allows control of the optimization, for example
AdaptiveMomentEstimation* adam = training_strategy.get_adaptive_moment_estimation_pointer();
adam->set_loss_goal(type(1.0e-3));
adam->set_maximum_epochs_number(10000);
adam->set_display_period(1000);
training_strategy.perform_training();
For more information about the training strategy methods, see TrainingStrategy class.
The fourth step is to evaluate our model. For that purpose, we need to use the testing analysis class, whose goal is to validate the model's generalization performance. Here, we compare the neural network outputs to the corresponding targets in the testing instances of the data set.
As in the previous cases, we start by building the testing analysis object
TestingAnalysis testing_analysis(&neural_network, &data_set);
and perform the testing, in our case we use linear regression analysis
const TestingAnalysis::LinearRegressionAnalysis linear_regression_analysis
= testing_analysis.perform_linear_regression_analysis()[0];
linear_regression_analysis.print();
For more information about the testing analysis methods, see TestingAnalysis class.
The model is now ready to estimate the self-noise of new airfoils with satisfactory quality over the same data range.
To generate predictions with new data, you can use
neural_network.calculate_outputs();
For instance, the new inputs are:
and in OpenNN we can write it as
Tensor<type, 2> inputs(1,4);
inputs.setValues({{type(6.782),type(0.136),type(50.860),type(0.011)}});
neural_network.calculate_outputs(inputs);
or save the model.
neural_network.save_expression_c("../data/expression.txt");
neural_network.save_expression_python("../data/expression.txt");
The model can be implemented in python, php, ... .
Joining all steps, we obtain the following code:
// DataSet
DataSet data_set("../data/airfoil_self_noise.csv", ';', true);
const Index input_variables_number = data_set.get_input_variables_number();
const Index target_variables_number = data_set.get_target_variables_number();
// Neural Network
const Index hidden_neurons_number = 12;
NeuralNetwork neural_network(NeuralNetwork::Approximation,
{input_variables_number,hidden_neurons_number,target_variables_number});
ScalingLayer* scaling_layer_pointer = neural_network.get_scaling_layer_pointer();
scaling_layer_pointer->set_descriptives(inputs_descriptives);
scaling_layer_pointer->set_scalers(MinimumMaximum);
// Training Strategy
TrainingStrategy training_strategy(&neural_network, &data_set);
training_strategy.set_loss_method(TrainingStrategy::MEAN_SQUARED_ERROR);
training_strategy.set_optimization_method(TrainingStrategy::ADAPTIVE_MOMENT_ESTIMATION);
training_strategy.perform_training();
// Testing Analysis
TestingAnalysis testing_analysis(&neural_network, &data_set);
const TestingAnalysis::LinearRegressionAnalysis linear_regression_analysis
= testing_analysis.perform_linear_regression_analysis()[0];
linear_regression_analysis.print();
// Model deployment
Tensorinputs(1,4);
inputs.setValues({{type(6.782),type(0.136),type(50.860),type(0.011)}});
neural_network.calculate_outputs(inputs);
// Save results
neural_network.save_expression_c("../data/airfoil_self_noise.txt");
neural_network.save_expression_python("../data/airfoil_self_noise.py");
This code can be exported to your C++ project.