NNET Procedure
Example 25.2 Finding the Best Neural Network Configuration
This example illustrates how to use the AUTOTUNE statement to search for the best set of hyperparameters within the domains that you specify. The data set (iris) is the same data set that is used in the section Getting Started: NNET Procedure. The AUTOTUNE statement searches for the best network for iris within two hidden layers (each of which has specified ranges), and it also searches for the best L1 and L2 regularization values based on the specified ranges. Only one controller node is used in the example.
You can load the sashelp.iris data set into your CAS session by naming your CAS engine libref in the first statement of the following DATA step. These statements assume that your CAS engine libref is named mylib, but you can substitute any appropriately defined CAS engine libref.
data mylib.iris;
set sashelp.iris;
run;
The following statements run PROC NNET and output the results to ODS tables. The AUTOTUNE statement activates the tuning optimization algorithm, which applies the specified ranges in the local searching process.
proc nnet data=mylib.iris;
input SepalLength SepalWidth PetalLength PetalWidth;
target Species / level=nominal;
train outmodel=mylib.nnetModel2 seed=1517878693;
autotune useparameters=custom objective=MCE searchmethod=GA
tuningparameters=(nhidden(LB=1 UB=2 INIT=1)
nunits1(LB=1 UB=10 INIT=1)
nunits2(LB=1 UB=15 INIT=2)
regl1(LB=1e-04 UB=1e-02 INIT=1e-03)
regl2(LB=1e-04 UB=1e-02 INIT=1e-03)
);
optimization algorithm=LBFGS maxiter=100;
run;
Output 25.2.1 shows the setup values that are used by the tuner.
Output 25.2.1: Tuner Information
| Tuner Information | |
|---|---|
| Model Type | Neural Net |
| Tuner Objective Function | Misclassification |
| Search Method | GA |
| Population Size | 10 |
| Maximum Iterations | 5 |
| Maximum Tuning Time in Seconds | 36000 |
| Validation Type | Single Partition |
| Validation Partition Fraction | 0.30 |
| Log Level | 2 |
| Seed | 1517878693 |
| Number of Parallel Evaluations | 19 |
| Number of Workers per Subsession | 1 |
Output 25.2.2 shows the results that are reported by the NNET procedure. The first row displays results from the default settings, the second row displays the best results that are found by the tuner, and the third row displays the second-best results that are found.
Output 25.2.2: Tuner Results
| Tuner Results Default and Best Configurations | |||||||
|---|---|---|---|---|---|---|---|
| Evaluation | Hidden Layers | Neurons in Hidden Layer 1 | Neurons in Hidden Layer 2 | L1 Regularization | L2 Regularization | Misclassification | Evaluation Time in Seconds |
| 0 | 1 | 1 | 0 | 0.001000 | 0.001000 | 0.3333 | 2.01 |
| 23 | 1 | 6 | 0 | 0.001179 | 0.000231 | 0.0000 | 1.46 |
| 51 | 1 | 6 | 0 | 0.001179 | 0.000231 | 0.0000 | 1.66 |
| 52 | 1 | 6 | 0 | 0.001179 | 0.000231 | 0.0000 | 1.62 |
| 65 | 1 | 6 | 0 | 0.001179 | 0.000231 | 0.0000 | 1.45 |
| 67 | 1 | 6 | 0 | 0.001179 | 0.000231 | 0.0000 | 1.55 |
| 81 | 1 | 6 | 0 | 0.001179 | 0.000231 | 0.0000 | 1.46 |
| 83 | 1 | 6 | 0 | 0.001179 | 0.000231 | 0.0000 | 1.71 |
| 12 | 1 | 6 | 0 | 0.001000 | 0.001000 | 0.0222 | 23.28 |
| 14 | 2 | 1 | 8 | 0.001000 | 0.001000 | 0.0222 | 24.02 |
| 17 | 2 | 6 | 8 | 0.010000 | 0.001000 | 0.0222 | 24.02 |
Output 25.2.3 shows the best values of the tuning parameters from the tuning process.
Output 25.2.3: Best Configuration
| Best Configuration | |
|---|---|
| Evaluation | 23 |
| Hidden Layers | 1 |
| Neurons in Hidden Layer 1 | 6 |
| Neurons in Hidden Layer 2 | 0 |
| L1 Regularization | 0.00117874 |
| L2 Regularization | 0.00023089 |
| Misclassification | 0 |
Output 25.2.4 shows the tuner summary.
Output 25.2.4: Tuner Summary
| Tuner Summary | |
|---|---|
| Initial Configuration Objective Value | 0.3333 |
| Best Configuration Objective Value | 0 |
| Worst Configuration Objective Value | 0.3333 |
| Initial Configuration Evaluation Time in Seconds | 2.0096 |
| Best Configuration Evaluation Time in Seconds | 1.4565 |
| Number of Improved Configurations | 4 |
| Number of Evaluated Configurations | 86 |
| Total Tuning Time in Seconds | 34.5837 |
| Parallel Tuning Speedup | 3.9902 |
Output 25.2.5 shows the run time for each task during the searching process. It is evident that the tuner spent the vast majority of its time on training; this behavior is similar to most tuner runs. Therefore, it is important to understand that tuning might take a very long time by nature if the training time is long. Typically, networks that have more neurons or larger training samples take more time; also, if the value of the MAXITER= option is very large and the nonlinear objective function converges slowly, the run time could be very long. In general, tuner performance should not be a concern, because you typically use tuning only once in a while.
Output 25.2.5: Tuner Timing
| Tuner Task Timing | ||
|---|---|---|
| Task | Seconds | Percent |
| Model Training | 71.80 | 52.03 |
| Model Scoring | 42.24 | 30.61 |
| Total Objective Evaluations | 114.06 | 82.66 |
| Tuner | 23.93 | 17.34 |
| Total CPU Time | 138.00 | 100.00 |
Output 25.2.6 shows the relative importance of each hyperparameter.
Output 25.2.6: Hyperparameter Importance
| Hyperparameter Importance | |
|---|---|
| Hyperparameter | Relative Importance |
| REGL1 | 1.0000 |
| NUNITS1 | 0.9351 |
| REGL2 | 0.4244 |
| NUNITS2 | 0.0297 |
| NHIDDEN | 0.0192 |
Output 25.2.7 displays a scatter plot of all configurations that the tuner tried. The objective values are shown on the Y axis, and the evaluation numbers are shown on the X axis.
Output 25.2.7: Evaluation History Plot

The plot in Output 25.2.8 displays how the best found objective value and the elapsed time changed with each iteration of the tuner.
Output 25.2.8: Iteration History Plot
