Neural Network Action Set

Create and Train a Neural Network

This section contains PROC CAS code.

Note: Input data must be accessible in your CAS session, either as a CAS table or as a transient-scope table. A CAS table has a two-level name: the first level is your CAS engine libref, and the second level is the table name. You refer to this table in the CAS procedure by specifying only the second level. For more information about two-level names, see Chapter 2, Shared Concepts (SAS Viya: Machine Learning Procedures). A transient-scope table is called directly from the action and exists in memory for the duration of the action. For more information about accessing data, see SAS Viya: System Programming Guide. For more information about PROC CAS and programming in CASL, see SAS Cloud Analytic Services: CASL Programmer’s Guide and SAS Cloud Analytic Services: CASL Reference.

The annTrain action creates and trains an artificial neural network (ANN) to approximate unknown functions for classification, regression, or autoencoding tasks.

This example uses the Iris data set in the Sashelp library to create a multilayer perceptron (MLP) neural network for a nominal target. The iris data published by Fisher (1936) contain 150 observations. The sepal length, sepal width, petal length, and petal width are measured in millimeters on 50 iris specimens from each of three species: Iris setosa, I. versicolor, and I. virginica. The four measurement types become input variables. The species name becomes the nominal target variable. The objective is to predict the species of an iris flower from measurements of its petal and sepal dimensions.

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. This DATA step assumes that your CAS engine libref is named mycas, but you can substitute any appropriately defined CAS engine libref.

 data mycas.iris;
    set sashelp.iris;
 run;

There are no missing values in the iris data. This is significant, because the annTrain action excludes observations that contain missing data from model training. If the input data that you want to use for neural network analysis contain a significant number of observations with missing values, you should replace or impute missing values before you perform model training. Because the iris data contain no missing values, the example does not perform variable replacement.

The example uses the annTrain action to create and train a neural network. The neural network approximates a function that predicts an iris flower species based on inputs of the length and width of its sepals and petals (measured in millimeters).


  proc cas;
        sampling.Stratified /
      table={name="iris",groupby={"species"}}                     /*1*/
      partInd=True                                                /*2*/
      samppct=30,                                                 /*3*/
      seed=12345,                                                 /*4*/
      output={
        casout={name="iris_partitioned", replace=true},           /*5*/
        copyVars="all"                                            /*6*/
         };
  run;

  /* Use the map data in the newly added partition column to create */
  /* separate CAS tables for Neural Net training and validation.    */


  proc cas;

  /* data explorations */
  table.columninfo/table='iris_partitioned';
  table.fetch/table='iris_partitioned' to=5;
  simple.freq/table='iris_partitioned' inputs='species';
  run;

  trnTable = {name="iris_partitioned",where="0=_partind_"};       /*7*/
  vldTable = {name="iris_partitioned",where="1=_partind_"};       /*8*/


  /* Use the annTrain action to create and train a MLP neural network */
  /* for a nominal target SPECIES.                                    */


  neuralNet.annTrain /
    table=trnTable,
    target="species"                                               /*9 */
    inputs={"sepallength","sepalwidth","petallength","petalwidth"} /*10*/
    nominals={"species"}                                           /*11*/
    hiddens={2}                                                    /*12*/
    seed=12345,                                                    /*13*/
    randDist="UNIFORM",                                            /*14*/
    scaleInit=1,                                                   /*15*/
    combs={"LINEAR"},                                              /*16*/
    targetAct="SOFTMAX",                                           /*17*/
    errorFunc="ENTROPY",                                           /*18*/
    std="MIDRANGE",                                                /*19*/
    validTable=vldTable,                                           /*20*/
    casout={name="Nnet_train_model", replace=TRUE}                 /*21*/
    nloOpts={                                                      /*22*/
     optmlOpt={maxIters=250, fConv=1e-10},                         /*23*/
     lbfgsOpt={numCorrections=6},                                  /*24*/
     validate={frequency=1}                                        /*25*/
     };
  run;
  1. Use the sampling.Stratified action to partition the Iris input data by the target variable Species.

  2. Add the partition indicator column _Partind_ to the output table. The _Partind_ column contains integer values that map to data partitions.

  3. Create a sampled partition consisting of 30% of table observations by Species. The remaining 70% of table observations form the second partition.

  4. Specify a random seed value of 12345 to be used for sampling function.

  5. Name the output table that the sampling_stratified action created (with a new partition information column), iris_partitioned. If a table by that name exists in CAS memory, the existing table is overwritten by the new iris_partitioned table content.

  6. Specify all the variables in the source table to be transferred to the sampled CAS table.

  7. Use the map data in the newly added partition column to create separate CAS tables for neural network training and validation. Let the CAS training table trnTable be a subset of all observations in the iris_partitioned table where the integer value of the column _Partind_ is equal to 1.

  8. Use the map data in the newly added partition column to create separate CAS tables for neural network training and validation. Let the CAS validation table vldTable be a subset of all observations in the iris_partitioned table where the integer value of the column _Partind_ is equal to 0.

  9. Use the annTrain action to create and train a MLP neural network by using the table trnTable with the target variable Species.

  10. Specify the four input variables to be used as analysis variables for the ANN analysis.

  11. Request that the target variable Species be treated as a nominal variable for analysis.

  12. Specify the number of hidden neurons for each hidden layer in the neural network feedforward model. For example, hiddens={2} specifies one hidden layer with two hidden neurons.

  13. Specify the random seed to use to perform sampling and partitioning tasks.

  14. Request that a UNIFORM distribution be used for randomly generating the initial neural network connection weights.

  15. Specify a scaling factor for connection weights relative to the number of units in the previous layer. The default value for the scaleInit parameter is 1. Setting the value of the scaleInit parameter to 2 increases the scale of the connection weights.

  16. Specify the LINEAR combination function for the neurons in each hidden layer.

  17. Specify the activation function for the neurons in the output layer. The SOFTMAX function is used by default for nominal variables.

  18. Specify the error function to train the network. ENTROPY is the default setting for nominal targets.

  19. Specify the standardization to use on the interval variables. When the value of the std parameter is MIDRANGE, the variables are scaled to a midrange of 0 and a half-range of 1. Variables will have a minimum value of –1 and a maximum value of 1.

  20. Specify the CAS input table name for the validation table to operate on. This enables early stopping of the iteration process by using the optmlOpt parameter. Validation and training tables must share the same layout.

  21. Specify the Nnet_train_model as the output CAS table.

  22. Enable neural algorithm solver optimization tools.

  23. Specify 250 maximum iterations for optimization, and also specify 1E–10 as the threshold stopping value for the objective function.

  24. Enable the LBFGS solver, using up to six corrections in the LBFGS update. LBFGS is an optimization algorithm in the quasi-Newton method family that approximates the Broyden-Fletcher-Goldfarb-Shanno (BFGS) algorithm by using a limited amount of computer memory.

  25. Set the validation option by using only the frequency parameter. When the value of the frequency parameter is 1, validation will occur every epoch. When frequency is 0, no validation will occur.

Output 29.3.1 displays an overview of the Fisher’s iris data used for the exercise. If you ran a table.columnInfo command on the Iris input data table in CAS, this is the input train and validation data structure.

Output 29.3.1: Column Information

Results from table.columnInfo

Column Information for IRIS_PARTITIONED in Caslib CASUSERHDFS(xianhu)
ColumnLabelIdTypeLengthFormatted
Length
SpeciesIris Species1char1010
SepalLengthSepal Length (mm)2double812
SepalWidthSepal Width (mm)3double812
PetalLengthPetal Length (mm)4double812
PetalWidthPetal Width (mm)5double812
_PartInd_Partition Indicator6double812


If you use the table.fetch command on the input table in CAS, you can look at example data rows, displayed in Output 29.3.2.

Output 29.3.2: Fetched Rows

Results from table.fetch

Selected Rows from Table IRIS_PARTITIONED
_Index_Iris SpeciesSepal Length (mm)Sepal Width (mm)Petal Length (mm)Petal Width (mm)Partition Indicator
1Setosa50331420
2Setosa51331750
3Setosa52341420
4Setosa50351660
5Setosa48301430


If you use the simple.freq command on the input table in CAS, you can verify that there are 50 observations from each of three iris species, for a total of 150 observations in the input data table, as displayed in Output 29.3.3.

Output 29.3.3: Frequency for Species

Results from simple.freq

Frequency for IRIS_PARTITIONED
ColumnCharacter
Value
Formatted
Value
LevelFrequency
SpeciesSetosaSetosa150
SpeciesVersicolorVersicolor250
SpeciesVirginicaVirginica350


When you successfully complete the training process for the input table Iris by using neuralNet.annTrain, your results will show a training data iteration history with Objective Function, Loss, and Validation Error columns, as displayed in Output 29.3.4.

Output 29.3.4: Optimization Iteration History

Results from neuralNet.annTrain

Iteration History
ProgressObjective
Function
LossValid
Error
13.62979819033.62979819030.377778
22.77910136932.77910136930.333333
32.57829263632.57829263630.333333
41.72829289861.72829289860.222222
51.4373748151.4373748150.111111
61.27796584631.27796584630.111111
70.91758035340.91758035340.044444
80.6076478570.6076478570.044444
90.24995418480.24995418480.044444
100.18269305570.18269305570.044444
110.15400361880.15400361880.044444
120.13609732280.13609732280.044444
130.11550679650.11550679650.044444
140.07886476590.07886476590.044444
150.0518415130.0518415130.044444
160.03628799790.03628799790.044444
170.02579277220.02579277220.044444
180.02222747240.02222747240.044444
190.01496604610.01496604610.044444
200.00705984410.00705984410.044444
210.00217436250.00217436250.044444
220.000923020.000923020.044444
230.00039781820.00039781820.044444
240.00017944010.00017944010.044444
250.00008191140.00008191140.044444
260.00003795790.00003795790.044444
270.00001773970.00001773970.044444


Below the "Iteration History" table, you should see a "Convergence Status" table. For a successful neural network model, the "Convergence Status" should report, "The optimization converged," as displayed in Output 29.3.5.

Output 29.3.5: Convergence Status

Convergence Status
The optimization converged.


A successful model training session includes summary results for the output model, as shown in Output 29.3.6.

Output 29.3.6: Model Information

Neural Net Model Info for IRIS_PARTITIONED
ModelNeural Net
Number of Observations Used105
Number of Observations Read105
Target/Response VariableSpecies
Number of Nodes9
Number of Input Nodes4
Number of Output Nodes3
Number of Hidden Nodes2
Number of Hidden Layers1
Number of Weight Parameters14
Number of Bias Parameters5
ArchitectureMLP
Number of Neural Nets1
Objective Value0.0000177397
Misclassification Error for Validation (%)4.4444444444


These results reiterate critical model building factors, such as model type; observations read; target variable; summary of the neural network model input, hidden, and output nodes; weight and bias parameters; final objective value; and the misclassification error for the scored validation data set.

At the bottom of the table, you see the final misclassification error percentage as determined by the validation data. If you were to use this neural network model as a predictive function, and your data came from a pool that had the same data distributions as the Iris validation table, you could expect that 93%–94% of the species predictions would be correct.

Create and Train a Neural Network

This section contains Lua code for the analysis in the CASL version of this example, which contains details about the results.

Note: In order to run this code, the data that are described in the CASL version need to be accessible to the CAS server. One way to do this is to convert the Iris data to the comma-separated-value (CSV) file Iris.csv and then use the following code to load the CSV file into CAS:

s:loadtable{casLib="casuser", path="Iris.csv"}

For more information about coding in Lua, see Getting Started with SAS Viya for Lua and SAS Viya: System Programming Guide.

 swat = require 'swat'                                             --1

 -- Change the host and port to match your site

 s = swat.CAS{"cloud.example.com", 5570}

 -- load the SAS data table Iris.csv from a server-side file
 s:upload{"/u/userDir/Iris.csv", casout={name="iris"}}             --2


 result = s:simple_summary{                                        --3
   table={
     name="iris",
     groupBy="species"
   },
 }

 print(result['ByGroup1.Summary'])                                 --4


 -- Use the sampling_Stratified action to partition the Iris input
 -- data by variable SPECIES into training (70%) and validation
 -- (30%) tables. The data is saved with a Partn_Val column that maps
 -- each observation to a training or validation partition.  The
 -- partitioned data is saved in CAS as iris_partitioned.

 result = s:sampling_stratified{                                   --5
      table={
     name="iris",
     groupby={{
       name="species"}}},                                          --6
   partind=true,
   samppct=70,                                                     --7
   samppct2=30,                                                    --8
   seed=12345,                                                     --9
   output={
     casOut={name="iris_partitioned"},                             --10
     copyVars="ALL",                                               --11
     partindname="Partn_Val"                                       --12
     }
   }

 -- Use the map data in the newly added Partn_Val column to create
 -- separate CAS tables for Neural Net training and validation.

 trnTable={
   name="iris_partitioned",where="1=Partn_Val"}                    --13

 vldTable={                                                        --14
   name="iris_partitioned",where="2=Partn_Val"}

 -- Use the annTrain action to create and train a MLP neural network
 -- for a nominal target SPECIES.

 r=s:neuralNet_annTrain{                                          --15
   table=
     trnTable,
   target="species",                                              --16
   nominals={{
     name="species"}},
   inputs={
     "sepallength","sepalwidth","petallength","petalwidth"},      --17
   listNode="ALL",                                                --18
   arch="MLP",                                                    --19
   hiddens=2,                                                     --20
   combs={"LINEAR"},                                              --21
   targetAct="SOFTMAX",                                           --22
   errorFunc="ENTROPY",                                           --23
   randDist="UNIFORM",                                            --24
   scaleInit=1,                                                   --25
   seed=12345,                                                    --26
   std="MIDRANGE",                                                --27
   validTable=vldTable,                                           --28
   casout={
     name="Nnet_train_model",                                     --29
     replace=TRUE},

   nloOpts={
     lbfgsOpt={
     numCorrections=6},                                           --30
     optmlOpt={
       maxIters=250,                                              --31
       fConv=1e-10},                                              --32
     validate={
       frequency=1}                                               --33
     }
   }

  1. Load the SAS Wrapper for Analytics Transfer (SWAT) architecture. SWAT is a family of modules in various languages that are used to access and interact with CAS.

  2. Load the SAS data table Iris.csv from a server-side file.

  3. Create a simple summary of the Iris table and sort the table by the variable Species.

  4. Print a copy of the Iris table summary.

  5. Issue a call to perform stratified sampling action on the Iris table.

  6. Specify stratified sampling of the Iris table, grouped by the nominal variable Species. When the Iris table is sampled and partitioned, a column called _Partind_ is created. The _Partind_ column uses integer values to indicate the partition that each observation belongs to.

  7. Specify that the first partition is a sample of 70% of observations (stratified by the Species variable).

  8. Specify that the second partition is a sample of 30% of observations (stratified by the Species variable).

  9. Specify a random seed value of 12345 to be used for sampling function.

  10. Request that the output file from the sampling_stratified action be named iris_partitioned.

  11. Request that all variables in the table be transferred to the CAS table.

  12. Assign the label Partn_Val to be the heading for the _partind_ column. The _partind_ column contains indicator values that are used to assign the observations in the iris_partitioned table into training and validation data sets.

  13. Use the map data in the Partn_Val column of the iris_partitioned table to create a training table in CAS. The training table is the subset composed of all observations in the iris_partitioned table where the value of Partn_Val is 1.

  14. Use the map data in the Partn_Val column of the iris_partitioned table to create a validation table in CAS. The validation table is the subset composed of all observations in the partitioned_Iris table where the value of Partn_Val is 2.

  15. Request that the annTrain action be used to create and train a MLP neural network named trnTable with a target variable Species.

  16. Request that the target variable be named Species, and also request that the Species variable be treated as a nominal variable for analysis.

  17. Specify the four input variables to be used as analysis variables.

  18. Specify the nodes to be included in the CAS table that is generated by the neural network scoring action. The ALL request includes all the nodes in the CAS table.

  19. Specify the network architecture to be trained. The MLP architecture specifies a multilayer perceptron with one or more hidden layers.

  20. Specify the number of hidden neurons for each hidden layer in the neural network feedforward model. For example, hiddens=2 specifies one hidden layer with two hidden neurons.

  21. Specify the LINEAR combination function for the neurons in each hidden layer.

  22. Specify the activation function for the neurons in the output layer. The SOFTMAX function is used by default for nominal variables.

  23. Specify the error function to train the network. ENTROPY is the default setting for nominal targets.

  24. Request that a UNIFORM distribution be used for randomly generating the initial neural network connection weights.

  25. Specify a scaling factor for connection weights relative to the number of units in the previous layer. The default value of the scaleInit parameter is 1. Setting the value of the scaleInit parameter to 2 increases the scale of the connection weights.

  26. Specify the random seed used to perform sampling and partitioning tasks.

  27. Specify the standardization to use on the interval variables. When the value of the std parameter is MIDRANGE, the variables are scaled to a midrange of 0 and a half-range of 1. Variables will have a minimum value of –1 and a maximum value of 1.

  28. Specify the CAS input table name for the validation table to operate on. This enables early stopping of the iteration process by using the optmlOpt parameter. Validation and training tables must share the same layout.

  29. Specify Nnet_train_model as the output CAS table. If a table already exists by that name, the existing table is overwritten by the new table content.

  30. Enable the LBFGS solver, using up to six corrections in the LBFGS update. LBFGS is an optimization algorithm in the quasi-Newton method family that approximates the Broyden-Fletcher-Goldfarb-Shanno (BFGS) algorithm by using a limited amount of computer memory.

  31. Specify 250 maximum iterations for optimization.

  32. Specify 1E–10 as the threshold stopping value for the objective function.

  33. Request validation by using only the frequency parameter. Validation will occur every epoch. When frequency is 0, no validation will occur.

Create and Train a Neural Network

This section contains Python code for the analysis in the CASL version of this example, which contains details about the results.

Note: In order to run this code, the data that are described in the CASL version need to be accessible to the CAS server. One way to do this is to convert the Iris data to the comma-separated-value (CSV) file Iris.csv and then use the following code to load the CSV file into CAS:

s.upload_file('Iris.csv')

For more information about coding in Python, see Getting Started with SAS Viya for Python and SAS Viya: System Programming Guide.

  import swat                                                       #1

  #  Specify the host and port information match your site

  s = swat.CAS("cloud.example.com", nnnn)

  from IPython.core.display import display                          # 2

  result = s.table.upload(
    path="iris.csv",
    casout={
      "name":"iris",
      "replace":True}                                               # 3
    )

  iris = s.CASTable(result.tableName)                               # 4


  # Display Table Info for Iris

  ti = iris.table.tableInfo().TableInfo                             # 5
  display(HTML('<h3>Table Information</h3>'))
  display(ti.ix[:,'Name':'JavaCharSet'])
  display(ti.ix[:,'ModTime':])



  # Display Table Details for Iris

  td = iris.table.tableDetails().TableDetails                       # 6
  display(HTML('<h3>Table Details</h3>'))
  display(td.ix[:,'Node':'VardataSize'])
  display(td.ix[:,'Mapped':])



  # Use the sampling_Stratified action to partition the Iris input
  # data by variable SPECIES into training (70%) and validation
  # (30%) tables.

  result = s.sampling.stratified(                                    # 7
       table={
      "name":"iris",
      "groupby":[{
        "name":"species"}]},

      partind=True,                                                  # 8

    output={                                                         # 9
      "casout":{
        "name":"iris_partitioned",
        "replace":True},
        "copyVars":"ALL",
        "partindname":"Partn_Val"                                    # 10
        },

    samppct=70,                                                      # 11
    seed=12345)                                                      # 12


  # Use the map data in the newly added Partn_Val column to create
  # separate CAS tables for Neural Net training and validation.

  trnTable={                                                         # 13
    "name":"iris_partitioned",
    "where":"1=Partn_Val"}

  vldTable={                                                         # 14
    "name":"iris_partitioned",
    "where":"0=Partn_Val"}

  -- Use the annTrain action to create and train a MLP neural network
  -- for a nominal target SPECIES.

  results = s.neuralNet.annTrain(                                    # 15
    table=trnTable,
    target="species",

    "nominals"=[{                                                    # 16
      "name":"species"}],

    inputs=[{                                                        # 17
      "name":{
        "sepallength",
        "sepalwidth",
        "petallength",
        "petalwidth"}}
      ],
    listNode="ALL",                                                  # 18
    arch="MLP",                                                      # 19
    hiddens={2},                                                     # 20
    combs={"LINEAR"},                                                # 21
    targetAct="SOFTMAX",                                             # 22
    errorFunc="ENTROPY",                                             # 23
    randDist="UNIFORM",                                              # 24
    scaleInit=1,                                                     # 25
    seed=12345,                                                      # 26
    std="MIDRANGE",                                                  # 27

    validTable=vldTable,                                             # 28

    casOut={                                                         # 29
      "name":"Nnet_train_model",
      "replace":True
      },

    nloOpts={                                                        # 30
      "lbfgsOpt":{"numCorrections":6},                               # 31
      "optmlOpt":{                                                   # 32
        "maxIters":250,                                              # 33
        "fConv":1e-10                                                # 34
        },
      "validate":{"frequency":1}}                                    # 35
    )

  1. Load the SAS Wrapper for Analytics Transfer (SWAT) architecture. SWAT is a family of modules in various languages that are used to access and interact with CAS. You must specify the SWAT host and port information to match your site. In this example, the MPP environment host is cloud.example.com, and nnnn represents a four-digit port number assignment. Your parameter values will be different.

  2. Establish iris as a Python variable to reference the in-memory CAS table.

  3. Load the SAS data table Iris.csv from a server-side file. If there is already a table named Iris residing in CAS memory at loading, the new content overwrites the old table.

  4. Specify Iris as the name for result tables from this action.

  5. Print a copy of the Iris table information summary.

  6. Print a copy of the Iris table details summary.

  7. Request stratified sampling of Iris table, grouped by the nominal variable Species.

  8. Request that when the Iris table is sampled and partitioned, a column called _Partind_ be created. The _Partind_ column uses integer values to indicate the partition that each observation belongs to.

  9. Request that the output file from the sampling_stratified action be named iris_partitioned. If another table by that name exists in CAS memory at the time of creation, the old table is overwritten with the new content. The copyvars specification assigns all variables in the table to be transferred to the newly partitioned table in CAS.

  10. Assign the label Partn_Val to be the heading for the _partind_ column. The _partind_ column contains indicator values that are used to assign the observations in the table iris_partitioned into training and validation data sets.

  11. Create a training partition sample of 70% of observations (stratified by the variable Species). The remaining 30% of observations make up the validation partition.

  12. Specify a random seed value of 12345 to be used for sampling function.

  13. Use the map data in the Partn_Val column of the iris_partitioned table to create a training table in CAS. The training table is the subset composed of all observations in the iris_partitioned table where the value of Partn_Val = 1.

  14. Use the map data in the Partn_Val column of the iris_partitioned table to create a validation table in CAS. The validation table is the subset composed of all observations in the iris_partitioned table where the value of Partn_Val = 0.

  15. Use the annTrain action to create and train a MLP neural network by using the table trnTable with the target variable Species.

  16. Request that the target variable Species be treated as a nominal variable for analysis.

  17. Specify the four input variables to be used as analysis variables.

  18. Specify the nodes to be included in the CAS table that is generated by the neural network scoring action. The ALL request includes all the nodes in the CAS table.

  19. Specify the network architecture to be trained. The MLP architecture specifies a multilayer perceptron with one or more hidden layers.

  20. Specify the number of hidden neurons for each hidden layer in the neural network feedforward model. For example, "hiddens"={2} specifies one hidden layer with two hidden neurons.

  21. Specify the LINEAR combination function for the neurons in each hidden layer.

  22. Specify the activation function for the neurons in the output layer. The SOFTMAX function is used by default for nominal variables.

  23. Specify the error function to train the network. ENTROPY is the default setting for nominal targets.

  24. Request that a UNIFORM distribution be used for randomly generating the initial neural network connection weights.

  25. Specify a scaling factor for connection weights relative to the number of units in the previous layer. The default value of the scaleInit parameter is 1. Specifying 2 as the value of the scaleInit parameter increases the scale of the connection weights.

  26. Specify the random seed to use to perform sampling and partitioning tasks.

  27. Specify the standardization to use on the interval variables. When the value of the std parameter is MIDRANGE, the variables are scaled to a midrange of 0 and a half-range of 1. Variables will have a minimum value of –1 and a maximum value of 1.

  28. Specify the CAS input table name for the validation table to operate on. This enables early stopping of the iteration process by using the optmlOpt parameter. Validation and training tables must share the same layout.

  29. Specify Nnet_train_model as the output CAS table. If a table by that name already exists, the existing table is overwritten by the new table content.

  30. Enable neural algorithm solver optimization tools.

  31. Enable the LBFGS solver, using up to six corrections in the LBFGS update. LBFGS is an optimization algorithm in the quasi-Newton method family that approximates the Broyden-Fletcher-Goldfarb-Shanno (BFGS) algorithm by using a limited amount of computer memory.

  32. Specify common option set specifications.

  33. Specify 250 maximum iterations for optimization.

  34. Specify 1E–10 as the threshold stopping value for the objective function.

  35. Request validation by using only the frequency parameter. Validation will occur every epoch. When frequency is 0, no validation will occur.

Create and Train a Neural Network

This section contains R code for the analysis in the CASL version of this example, which contains details about the results.

Note: In order to run this code, the data that are described in the CASL version need to be accessible to the CAS server. One way to do this is to convert the iris data to the comma-separated-value (CSV) file iris.csv and then use the following code to load the CSV file into CAS:

m <- cas.read.csv(s, "iris.csv", casOut=list(name="iris"))

For more information about coding in R, see Getting Started with SAS Viya for R and SAS Viya: System Programming Guide.

This section contains R code. For more information about coding in the R language, see Getting Started with SAS Viya for R.

The following code loads the table iris onto the server, partitions the table into the tables trnTable and vldTable, and then performs the training by using the neuralNet.annTrain action:

 cas.read.csv(s,
              "iris.csv",
              header = TRUE,
              casOut = list(name = "iris", replace = TRUE))

 loadActionSet(s, 'sampling')

 result<-cas.sampling.stratified(s,
                table   = list(name = "iris", groupBy = list("species")),
                partInd = TRUE,
                samppct = 30,
                seed    = 12345,
                output  = list(casout = list(name = "iris_partitioned", replace = TRUE),
                               copyVars = "ALL"))

 # Use the map data in the newly added partition column to create
 # separate CAS tables for Neural Net training and validation

 # data explorations
 loadActionSet(s, 'table')
 cInfoResult <- cas.table.columnInfo(s,
                    table = list(name = "iris_partitioned"))

 cas.table.fetch(s,
                 table = list(name = "iris_partitioned"),
                 to    = 5)

 loadActionSet(s, 'simple')
 freqResults <- cas.simple.freq(s,
                    table  = list(name = "iris_partitioned"),
                    inputs = list("species"))

 trnTable = list(name = "iris_partitioned", where = "0=_partind_")
 vldTable = list(name = "iris_partitioned", where = "1=_partind_")

 # Use the annTrain action to create and train a MLP neural network
 # for a nominal target SPECIES.
 loadActionSet(s, 'neuralNet')
 annResults <- cas.neuralNet.annTrain(s,
            table      = trnTable,
            target     = "species",
            inputs     = list("sepallength", "sepalwidth", "petallength", "petalwidth"),
            nominals   = list("species"),
            hiddens    = list(2),
            seed       = 12345,
            randDist   = "UNIFORM",
            scaleInit  = 1,
            combs      = list("LINEAR"),
            targetAct  = "SOFTMAX",
            errorFunc  = "ENTROPY",
            std        = "MIDRANGE",
            validTable = vldTable,
            casout     = list(name = "nnet_train_model", replace = TRUE),
            nloOpts    = list(optmlOpt = list(maxIters = 250, fConv = 1e-10),
                                  lbfgsOpt = list(numCorrections = 6),
                                  validate = list(frequency = 1)))

The following command displays the tables that are produced by this action call:

For details about the results of this analysis, see the CASL version of this example.

Last updated: August 04, 2026