IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jan 27, 2018, 1:09:32 PM (8 years ago)
Author:
eugene
Message:

updated nnet to include better init, L2 regularization, cross-entropy cost function

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Ohana/src/opihi/cmd.data/nnet_train.c

    r40323 r40325  
    77void  nnet_reset_Nabla (Nnet *nnet);
    88void  nnet_update_Nabla (Nnet *nnet);
    9 void  nnet_apply_Nabla (Nnet *nnet, int Nmini, float eta);
     9void  nnet_apply_Nabla (Nnet *nnet, int Nmini, float eta, float lambda, int Ntrial);
    1010void  nnet_backprop (Nnet *nnet, Vector **inVec, Vector **outVec, int N);
    11 void  nnet_descent_step (Nnet *nnet, Vector **inVec, Vector **outVec, int *seq, int pass, int Nmini, float eta);
     11void  nnet_descent_step (Nnet *nnet, Vector **inVec, Vector **outVec, int *seq, int pass, int Nmini, float eta, float lambda);
     12
     13static int QUADRATIC_COST = 0;
    1214
    1315int nnet_train (int argc, char **argv) {
     
    3436    eta = atof (argv[N]);
    3537    remove_argument (N, &argc, argv);
     38  }
     39
     40  float lambda = 0.0; // XXX how do I set this? does it need to update?
     41  if ((N = get_argument (argc, argv, "-lambda"))) {
     42    remove_argument (N, &argc, argv);
     43    lambda = atof (argv[N]);
     44    remove_argument (N, &argc, argv);
     45  }
     46
     47  QUADRATIC_COST = 0;
     48  if ((N = get_argument (argc, argv, "-quadratic-cost"))) {
     49    remove_argument (N, &argc, argv);
     50    QUADRATIC_COST = 1;   
    3651  }
    3752
     
    121136      // for a given pass select seq elements pass*Nmini to pass*Nmini + Nmini - 1
    122137      // update the weights and biases using the mini batch subset
    123       nnet_descent_step (nnet, inVec, outVec, seq, pass, Nmini, eta);
     138      nnet_descent_step (nnet, inVec, outVec, seq, pass, Nmini, eta, lambda);
    124139      gprint (GP_ERR, "epoch %d of %d, pass %d of %d\n", epoch, Nepoch, pass, Npass);
    125140    }
     
    134149
    135150// this recreates 'update_mini_batch' from http://neuralnetworksanddeeplearning.com/chap1.html
    136 void nnet_descent_step (Nnet *nnet, Vector **inVec, Vector **outVec, int *seq, int pass, int Nmini, float eta) {
     151void nnet_descent_step (Nnet *nnet, Vector **inVec, Vector **outVec, int *seq, int pass, int Nmini, float eta, float lambda) {
    137152
    138153  int Ntrial = inVec[0][0].Nelements;
     
    151166  }
    152167
    153   nnet_apply_Nabla (nnet, Nmini, eta);
     168  nnet_apply_Nabla (nnet, Nmini, eta, lambda, Ntrial);
    154169}
    155170
     
    183198        // NOTE: the (1/Npt) factor is pushed to the apply_Nabla step
    184199        // nnet[0].delta[L][j] = cost_derivative(nnet[0].svalue[L][j], outVec[j][0].elements.Flt[N]) * nnet[0].sprime[L][j];
    185         nnet[0].delta[L][j] = (nnet[0].svalue[L][j] - outVec[j][0].elements.Flt[N]) * nnet[0].sprime[L][j];
     200
     201        if (QUADRATIC_COST) {
     202          nnet[0].delta[L][j] = (nnet[0].svalue[L][j] - outVec[j][0].elements.Flt[N]) * nnet[0].sprime[L][j];
     203        } else {
     204          nnet[0].delta[L][j] = (nnet[0].svalue[L][j] - outVec[j][0].elements.Flt[N]);
     205        }
     206
     207        // for quadratic cost, delta = (svalue[L] - output) * sprime[L]
     208        // for cross-entropy, delta = (svalue[L] - output)
     209
    186210      }
    187211    } else {
     
    218242
    219243// support functions to loop over the Nabla entries
    220 void nnet_apply_Nabla (Nnet *nnet, int Nmini, float eta) {
     244void nnet_apply_Nabla (Nnet *nnet, int Nmini, float eta, float lambda, int Ntrial) {
    221245  for (int L = 1; L < nnet[0].Nlayer; L++) {
    222246
     
    226250      for (int i = 0; i < nnet[0].Nnodes[L-1]; i++) {
    227251        int k = i + j*nnet[0].Nnodes[L-1];
    228         nnet[0].weight[L][k] -= (eta / Nmini) * nnet[0].Nabla_w[L][k];
     252        // nnet[0].weight[L][k] -= (eta / Nmini) * nnet[0].Nabla_w[L][k];
     253        // with lambda > 0.0, we have L2 regularization.  if lambda = 0.0, we recover the default implementation
     254        nnet[0].weight[L][k] = nnet[0].weight[L][k]*(1.0 - eta*lambda/Ntrial) - (eta / Nmini) * nnet[0].Nabla_w[L][k];
    229255      }
    230256    }
Note: See TracChangeset for help on using the changeset viewer.