Changeset 40319
- Timestamp:
- Jan 23, 2018, 10:11:50 AM (8 years ago)
- Location:
- trunk/Ohana/src/opihi
- Files:
-
- 2 added
- 8 edited
-
cmd.data/Makefile (modified) (2 diffs)
-
cmd.data/init.c (modified) (2 diffs)
-
cmd.data/nnet.c (modified) (2 diffs)
-
cmd.data/nnet_commands.c (modified) (5 diffs)
-
cmd.data/nnet_train.c (modified) (12 diffs)
-
cmd.data/nnet_train.save.c (added)
-
cmd.data/test/nnet.sh (added)
-
include/data.h (modified) (2 diffs)
-
lib.data/Makefile (modified) (2 diffs)
-
lib.data/nnet.c (modified) (15 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Ohana/src/opihi/cmd.data/Makefile
r40291 r40319 99 99 $(SRC)/medimage_commands.$(ARCH).o \ 100 100 $(SRC)/mset.$(ARCH).o \ 101 $(SRC)/needles.$(ARCH).o \ 101 $(SRC)/needles.$(ARCH).o \ 102 $(SRC)/nnet.$(ARCH).o \ 103 $(SRC)/nnet_commands.$(ARCH).o \ 104 $(SRC)/nnet_train.$(ARCH).o \ 105 $(SRC)/nnet_apply.$(ARCH).o \ 102 106 $(SRC)/peak.$(ARCH).o \ 103 107 $(SRC)/periodogram.$(ARCH).o \ … … 189 193 $(INC)/external.h \ 190 194 $(INC)/shell.h \ 195 $(INC)/data.h \ 191 196 $(INC)/dvomath.h \ 192 197 $(INC)/display.h -
trunk/Ohana/src/opihi/cmd.data/init.c
r40291 r40319 89 89 int mset PROTO((int, char **)); 90 90 int needles PROTO((int, char **)); 91 int nnet_command PROTO((int, char **)); 91 92 int peak PROTO((int, char **)); 92 93 int periodogram PROTO((int, char **)); … … 270 271 {1, "imset", mset, "insert a vector in an image"}, 271 272 {1, "needles", needles, "plot vectors needles"}, 273 {1, "nnet", nnet_command, "Neural Network commands"}, 272 274 {1, "parity", parity, "set image parity"}, 273 275 {1, "peak", peak, "find vector peak in range"}, -
trunk/Ohana/src/opihi/cmd.data/nnet.c
r40317 r40319 1 1 # include "data.h" 2 3 int nnet_list (int argc, char **argv);4 int nnet_create (int argc, char **argv);5 int nnet_delete (int argc, char **argv);6 int nnet_train (int argc, char **argv);7 int nnet_apply (int argc, char **argv);8 int nnet_show (int argc, char **argv);9 2 10 3 static Command nnet_commands[] = { 11 4 {1, "list", nnet_list, "list nnets"}, 12 {1, "init", nnet_init, "initialize a nnet"},13 5 {1, "delete", nnet_delete, "delete a nnet"}, 14 6 {1, "show", nnet_show, "display nnet values"}, 15 7 {1, "create", nnet_create, "create a nnet"}, 8 {1, "set", nnet_set, "set nnet node values"}, 9 {1, "get", nnet_get, "get nnet node values"}, 16 10 {1, "train", nnet_train, "train nnet on a set of data"}, 17 11 {1, "apply", nnet_apply, "apply nnet to a set of data"}, … … 25 19 gprint (GP_ERR, "USAGE: nnet (command)\n"); 26 20 gprint (GP_ERR, " nnet list : list nnets\n"); 27 gprint (GP_ERR, " nnet init (nnet) : removes all pages from nnet\n");28 21 gprint (GP_ERR, " nnet delete (nnet) : delete a nnet\n"); 29 22 gprint (GP_ERR, " nnet show (nnet) : show values for a nnet\n"); 30 23 gprint (GP_ERR, " nnet create (nnet) (Ninput) [Nnodes] [Nnodes] ... (Noutput) : create a nnet\n"); 24 gprint (GP_ERR, " nnet set (nnet) [weights] [biases] ... [weights] [biases] : set nnet weights (images) and biases (vectors)\n"); 25 gprint (GP_ERR, " nnet get (nnet) [weights] [biases] ... [weights] [biases] : get nnet weights (images) and biases (vectors)\n"); 31 26 gprint (GP_ERR, " nnet train (nnet) [input] [input] ... [output] [output] ... : train nnet on data from a set of vectors\n"); 32 27 gprint (GP_ERR, " nnet apply (nnet) [input] [input] ... [output] [output] ... : apply nnet to input data and generate output\n"); -
trunk/Ohana/src/opihi/cmd.data/nnet_commands.c
r40317 r40319 12 12 } 13 13 14 /** Fix These ... 15 int nnet_init (int argc, char **argv) { 16 14 int nnet_delete (int argc, char **argv) { 15 16 # if (0) 17 17 int status; 18 18 Nnet *nnet; 19 19 20 20 if (argc != 2) { 21 gprint (GP_ERR, "USAGE: nnet init (nnet)\n");22 return FALSE;23 }24 25 nnet = FindNnet (argv[1]);26 if (nnet != NULL) {27 status = DeleteNnet (nnet);28 if (!status) abort ();29 }30 31 CreateNnet (argv[1]);32 return TRUE;33 }34 35 int nnet_delete (int argc, char **argv) {36 37 int status;38 Nnet *nnet;39 40 if (argc != 2) {41 21 gprint (GP_ERR, "USAGE: nnet delete (nnet)\n"); 42 22 return FALSE; … … 51 31 status = DeleteNnet (nnet); 52 32 if (!status) abort (); 33 # endif 34 53 35 return TRUE; 54 36 } … … 56 38 int nnet_show (int argc, char **argv) { 57 39 40 # if (0) 58 41 Nnet *nnet; 59 42 … … 70 53 71 54 ListPages (nnet); 72 return TRUE; 73 } 74 **/ 55 # endif 56 57 return TRUE; 58 } 75 59 76 60 int nnet_create (int argc, char **argv) { … … 97 81 } 98 82 83 int nnet_set (int argc, char **argv) { 84 85 Buffer *matrix; 86 Vector *vector; 87 88 if (argc < 5) { 89 gprint (GP_ERR, "USAGE: nnet set (nnet) [weights] [biases] ... [weights] [biases] : set nnet weights (images) and biases (vectors)\n"); 90 return FALSE; 91 } 92 93 Nnet *nnet = FindNnet (argv[1]); 94 if (nnet == NULL) { 95 gprint (GP_ERR, "nnet %s not found, create it first\n", argv[1]); 96 return FALSE; 97 } 98 99 // compare argc and nnet[0].Nlayer 100 if (argc - 2 != nnet[0].Nlayer * 2) { 101 gprint (GP_ERR, "ERROR: invalid number of arguments\n"); 102 gprint (GP_ERR, "USAGE: nnet set (nnet) [weights] [biases] ... [weights] [biases] : set nnet weights (images) and biases (vectors)\n"); 103 return FALSE; 104 } 105 106 // check for existence of each matrix & vector (and check sizes) 107 for (int L = 1; L < nnet[0].Nlayer; L++) { 108 int Narg = 2*(L - 1) + 2; 109 if ((matrix = SelectBuffer (argv[Narg + 0], OLDBUFFER, FALSE)) == NULL) { 110 gprint (GP_ERR, "unknown input image %s\n", argv[Narg + 0]); 111 gprint (GP_ERR, "USAGE: nnet set (nnet) [weights] [biases] ... [weights] [biases] : set nnet weights (images) and biases (vectors)\n"); 112 return (FALSE); 113 } 114 if ((vector = SelectVector (argv[Narg + 1], OLDVECTOR, FALSE)) == NULL) { 115 gprint (GP_ERR, "unknown input vector %s\n", argv[Narg + 1]); 116 gprint (GP_ERR, "USAGE: nnet set (nnet) [weights] [biases] ... [weights] [biases] : set nnet weights (images) and biases (vectors)\n"); 117 return (FALSE); 118 } 119 120 if (vector->Nelements != nnet[0].Nnodes[L]) { 121 gprint (GP_ERR, "invalid bias vector length %s (%d vs %d)\n", argv[Narg + 1], vector->Nelements, nnet[0].Nnodes[L]); 122 gprint (GP_ERR, "USAGE: nnet set (nnet) [weights] [biases] ... [weights] [biases] : set nnet weights (images) and biases (vectors)\n"); 123 } 124 125 if (matrix->matrix.Naxis[0] != nnet[0].Nnodes[L-1]) { 126 gprint (GP_ERR, "invalid weight image size for %s (Nx = %d vs %d)\n", argv[Narg + 0], (int) matrix->matrix.Naxis[0], nnet[0].Nnodes[L-1]); 127 gprint (GP_ERR, "USAGE: nnet set (nnet) [weights] [biases] ... [weights] [biases] : set nnet weights (images) and biases (vectors)\n"); 128 } 129 130 if (matrix->matrix.Naxis[1] != nnet[0].Nnodes[L]) { 131 gprint (GP_ERR, "invalid weight image size for %s (Ny = %d vs %d)\n", argv[Narg + 0], (int) matrix->matrix.Naxis[1], nnet[0].Nnodes[L]); 132 gprint (GP_ERR, "USAGE: nnet set (nnet) [weights] [biases] ... [weights] [biases] : set nnet weights (images) and biases (vectors)\n"); 133 } 134 135 } 136 137 for (int L = 1; L < nnet[0].Nlayer; L++) { 138 139 int Narg = 2*(L - 1) + 2; 140 matrix = SelectBuffer (argv[Narg + 0], OLDBUFFER, FALSE); // I've checked the argv entry above so I do not need to check again... 141 vector = SelectVector (argv[Narg + 1], OLDVECTOR, FALSE); 142 143 opihi_flt *vecvalue = vector[0].elements.Flt; 144 for (int i = 0; i < nnet[0].Nnodes[L]; i++) { 145 nnet[0].biases[L][i] = vecvalue[i]; 146 } 147 148 float *matvalue = (float *) matrix[0].matrix.buffer; 149 for (int j = 0; j < nnet[0].Nnodes[L]; j++) { 150 for (int i = 0; i < nnet[0].Nnodes[L-1]; i++) { 151 int k = i + j*nnet[0].Nnodes[L-1]; 152 nnet[0].weight[L][k] = matvalue[k]; 153 } 154 } 155 156 } 157 158 return TRUE; 159 } 160 161 int nnet_get (int argc, char **argv) { 162 163 Buffer *matrix; 164 Vector *vector; 165 166 if (argc < 5) { 167 gprint (GP_ERR, "USAGE: nnet get (nnet) [weights] [biases] ... [weights] [biases] : get nnet weights (images) and biases (vectors)\n"); 168 return FALSE; 169 } 170 171 Nnet *nnet = FindNnet (argv[1]); 172 if (nnet == NULL) { 173 gprint (GP_ERR, "nnet %s not found, create it first\n", argv[1]); 174 return FALSE; 175 } 176 177 // compare argc and nnet[0].Nlayer 178 if (argc - 2 != nnet[0].Nlayer * 2) { 179 gprint (GP_ERR, "ERROR: invalid number of arguments\n"); 180 gprint (GP_ERR, "USAGE: nnet set (nnet) [weights] [biases] ... [weights] [biases] : set nnet weights (images) and biases (vectors)\n"); 181 return FALSE; 182 } 183 184 // check for existence of each matrix & vector (and check sizes) 185 for (int L = 1; L < nnet[0].Nlayer; L++) { 186 int Narg = 2*(L - 1) + 2; 187 if ((matrix = SelectBuffer (argv[Narg + 0], ANYBUFFER, FALSE)) == NULL) { 188 gprint (GP_ERR, "unknown input image %s\n", argv[Narg + 0]); 189 gprint (GP_ERR, "USAGE: nnet set (nnet) [weights] [biases] ... [weights] [biases] : set nnet weights (images) and biases (vectors)\n"); 190 return (FALSE); 191 } 192 if ((vector = SelectVector (argv[Narg + 1], ANYVECTOR, FALSE)) == NULL) { 193 gprint (GP_ERR, "unknown input vector %s\n", argv[Narg + 1]); 194 gprint (GP_ERR, "USAGE: nnet set (nnet) [weights] [biases] ... [weights] [biases] : set nnet weights (images) and biases (vectors)\n"); 195 return (FALSE); 196 } 197 } 198 199 for (int L = 1; L < nnet[0].Nlayer; L++) { 200 201 int Narg = 2*(L - 1) + 2; 202 matrix = SelectBuffer (argv[Narg + 0], OLDBUFFER, FALSE); // I've checked the argv entry above so I do not need to check again... 203 vector = SelectVector (argv[Narg + 1], OLDVECTOR, FALSE); 204 205 ResetVector (vector, OPIHI_FLT, nnet[0].Nnodes[L]); 206 ResetBuffer (matrix, nnet[0].Nnodes[L-1], nnet[0].Nnodes[L], -32, 0.0, 1.0); 207 208 opihi_flt *vecvalue = vector[0].elements.Flt; 209 for (int i = 0; i < nnet[0].Nnodes[L]; i++) { 210 vecvalue[i] = nnet[0].biases[L][i]; 211 } 212 213 float *matvalue = (float *) matrix[0].matrix.buffer; 214 for (int j = 0; j < nnet[0].Nnodes[L]; j++) { 215 for (int i = 0; i < nnet[0].Nnodes[L-1]; i++) { 216 int k = i + j*nnet[0].Nnodes[L-1]; 217 matvalue[k] = nnet[0].weight[L][k]; 218 } 219 } 220 221 } 222 223 return TRUE; 224 } 225 -
trunk/Ohana/src/opihi/cmd.data/nnet_train.c
r40318 r40319 1 1 # include "data.h" 2 void sortseq (float *X, int *Y, int N); 2 3 // these are local only 4 float nnet_sigmoid (float value); 5 void nnet_sortseq (float *X, int *Y, int N); 6 int nnet_onelayer (Nnet *nnet, int L); 7 void nnet_reset_Nabla (Nnet *nnet); 8 void nnet_update_Nabla (Nnet *nnet); 9 void nnet_apply_Nabla (Nnet *nnet, int Nmini, float eta); 10 void 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); 3 12 4 13 int nnet_train (int argc, char **argv) { 14 15 int N; 5 16 6 17 int Nepoch = 10; … … 18 29 } 19 30 31 float eta = 1.0; // XXX how do I set this? does it need to update? 32 20 33 if (argc < 4) { 21 34 gprint (GP_ERR, "USAGE: nnet train (nnet) [input] [input] ... [output] [output] ...\n"); … … 97 110 // generate a random sequence : used to select random mini batches 98 111 for (int i = 0; i < Ntrial; i++) { seq[i] = i; rnd[i] = drand48(); } 99 sortseq (rnd, seq, Ntrial);112 nnet_sortseq (rnd, seq, Ntrial); 100 113 101 114 int Npass = Ntrial / Nmini; … … 116 129 117 130 // this recreates 'update_mini_batch' from http://neuralnetworksanddeeplearning.com/chap1.html 118 void nnet_descent_step (N Net *nnet, Vector **inVec, Vector **outVec, int *seq, int pass, int Nmini, float eta) {131 void nnet_descent_step (Nnet *nnet, Vector **inVec, Vector **outVec, int *seq, int pass, int Nmini, float eta) { 119 132 120 133 int Ntrial = inVec[0][0].Nelements; … … 122 135 nnet_reset_Nabla (nnet); 123 136 124 for (i = 0; (i < Nmini) && (pass*Nmini + i < Ntrial); i++) {137 for (int i = 0; (i < Nmini) && (pass*Nmini + i < Ntrial); i++) { 125 138 126 139 // N is the element of the mini batch on which we are currently operating 127 N = seq[pass*Nmini + i];140 int N = seq[pass*Nmini + i]; 128 141 129 142 // backprop generates a dNabla_b, dNabla_w pair for the element N of the input and output vectors … … 136 149 } 137 150 138 void nnet_backprop (N Net *nnet, Vector **inVec, Vector **outVec, int N) {151 void nnet_backprop (Nnet *nnet, Vector **inVec, Vector **outVec, int N) { 139 152 140 153 // start with the input values 141 142 // store the input values for this row (trial) in the input value vector143 154 int Nlayer = nnet[0].Nlayer; 144 int Ninput = nnet[0].Nnodes[0]; 145 int Noutput = nnet[0].Nnodes[Nlayer - 1]; // number of input + output nodes 146 147 for (int j = 0; j < Ninput; j++) { 155 156 // store the input values for this row (trial) in the input vector "svalue[0]" 157 for (int j = 0; j < nnet[0].Nnodes[0]; j++) { 148 158 nnet[0].svalue[0][j] = inVec[j][0].elements.Flt[N]; 149 159 } … … 153 163 // activation = sigmoid (z) 154 164 165 // feedforward operates on the vector saved in svalue[0] 166 // feedforward saves the zvalues [w * input + bias], svalues [sigmoid(z)], sprimes [sigmoid'(z)] as it runs 155 167 nnet_feedforward (nnet); 156 168 157 // backward pass (note for now these are vector operations: 158 for (L = Nlayer - 1; L > 0; L--) { 159 160 // sp is array of same size as zvalue for each layer 161 // sp = sigmoid_prime (nnet[0].zvalue[L]); sprime is precalculated in feedforward 169 // backward pass 170 for (int L = Nlayer - 1; L > 0; L--) { 162 171 163 172 if (L == Nlayer - 1) { 164 173 // starting point uses cost_derivative to compare last svalue set with truth output 165 // delta = cost_derivative( nnet[0].svalue[L], outVec, N) * sprime[L];174 // delta = cost_derivative(svalue[L], output) * sprime[L]; 166 175 for (int j = 0; j < nnet[0].Nnodes[L]; j++) { 167 nnet[0].delta[L][j] = cost_derivative(nnet[0].svalue[L][j], outVec[j][0].elements.Flt[N]) * nnet[0].sprime[L][j]; 176 // cost_derivative (svalue[L][j], output[j]) = svalue[L][j] - output[j] 177 // (because cost = (1/2)(svalue[L][j] - output[j])^2) 178 // NOTE: the (1/Npt) factor is pushed to the apply_Nabla step 179 // nnet[0].delta[L][j] = cost_derivative(nnet[0].svalue[L][j], outVec[j][0].elements.Flt[N]) * nnet[0].sprime[L][j]; 180 nnet[0].delta[L][j] = (nnet[0].svalue[L][j] - outVec[j][0].elements.Flt[N]) * nnet[0].sprime[L][j]; 168 181 } 169 182 } else { 170 // delta = (delta DOT transpose(weights[L+1])) * sp;183 // delta = DOT(delta, transpose(weight[L+1])) * sprime; 171 184 for (int j = 0; j < nnet[0].Nnodes[L]; j++) { 172 tmpdelta =0;185 float tmpdelta = 0.0; 173 186 for (int i = 0; i < nnet[0].Nnodes[L+1]; i++) { 174 int k = j + i*nnet[0].Nnodes[L]; 175 tmpdelta += nnet[0].weight[L][k] * nnet[0].delta[L+1][i]; // XXX check on the index values187 int k = j + i*nnet[0].Nnodes[L]; // note order of (i,j) : j is [L+1] direction 188 tmpdelta += nnet[0].weight[L][k] * nnet[0].delta[L+1][i]; 176 189 } 177 190 nnet[0].delta[L][j] = tmpdelta * nnet[0].sprime[L][j]; … … 179 192 } 180 193 181 // UPDATE 182 Nabla_b[L] = delta; 194 // NOTE on weight array: for a given layer, L, the matrix weight[L] maps the nodes in 195 // the previous layer (L-1) to those in L: Nnodes[L-1] -> Nnodes[L]. This is a matrix 196 // with dimensions (Nnodes[L-1] x Nnodes[L]). The Nnodes[L-1] is the fast dimension, 197 // so for an element (i,j), the index k = i + j*Nnodes[L-1]. 198 199 // Nabla_b[L] = delta; 200 for (int j = 0; j < nnet[0].Nnodes[L]; j++) { 201 nnet[0]. Nabla_b[L][j] = nnet[0].delta[L][j]; 202 } 183 203 184 // Nabla_w[L] = delta DOT transpose(nnet[0].svalue[L-1]);204 // Nabla_w[L] = DOT(delta, transpose(svalue[L-1])); 185 205 for (int j = 0; j < nnet[0].Nnodes[L]; j++) { 186 206 for (int i = 0; i < nnet[0].Nnodes[L-1]; i++) { 187 int k = i + j*nnet[0].Nnodes[n-1]; 188 nnet[0]. Nabla_w[n][k] = nnet[0].svalue[L-1][i] * nnet[0].delta[L][j]; 189 } 190 } 191 207 int k = i + j*nnet[0].Nnodes[L-1]; 208 nnet[0]. Nabla_w[L][k] = nnet[0].svalue[L-1][i] * nnet[0].delta[L][j]; 209 } 210 } 192 211 } 193 212 } 194 213 195 214 // support functions to loop over the Nabla entries 196 void nnet_apply_Nabla (N Net *nnet, int Nmini, float eta) {197 for (int n = 1; n < nnet[0].Nlayer; n++) {198 199 for (int j = 0; j < nnet[0].Nnodes[ n]; j++) {200 nnet[0].biases[ n][j] -= (eta / Nmini) * nnet[0].Nabla_b[n][j];201 202 for (int i = 0; i < nnet[0].Nnodes[ n-1]; i++) {203 int k = i + j*nnet[0].Nnodes[ n-1];204 nnet[0].weight s[n][k] -= (eta / Nmini) * nnet[0].Nabla_w[n][k];205 } 206 } 207 } 208 } 209 void nnet_update_Nabla (N Net *nnet) {210 for (int n = 1; n < nnet[0].Nlayer; n++) {211 212 for (int j = 0; j < nnet[0].Nnodes[ n]; j++) {213 nnet[0]. Nabla_b[ n][j] += nnet[0].dNabla_b[n][j];214 215 for (int i = 0; i < nnet[0].Nnodes[ n-1]; i++) {216 int k = i + j*nnet[0].Nnodes[ n-1];217 nnet[0]. Nabla_w[ n][k] += nnet[0].dNabla_w[n][k];218 } 219 } 220 } 221 } 222 void nnet_reset_Nabla (N Net *nnet) {223 for (int n = 1; n < nnet[0].Nlayer; n++) {224 225 for (int j = 0; j < nnet[0].Nnodes[ n]; j++) {226 227 nnet[0]. Nabla_b[ n][j] = 0;228 nnet[0].dNabla_b[ n][j] = 0;229 230 for (int i = 0; i < nnet[0].Nnodes[ n-1]; i++) {231 int k = i + j*nnet[0].Nnodes[ n-1];232 nnet[0]. Nabla_w[ n][k] = 0;233 nnet[0].dNabla_w[ n][k] = 0;215 void nnet_apply_Nabla (Nnet *nnet, int Nmini, float eta) { 216 for (int L = 1; L < nnet[0].Nlayer; L++) { 217 218 for (int j = 0; j < nnet[0].Nnodes[L]; j++) { 219 nnet[0].biases[L][j] -= (eta / Nmini) * nnet[0].Nabla_b[L][j]; 220 221 for (int i = 0; i < nnet[0].Nnodes[L-1]; i++) { 222 int k = i + j*nnet[0].Nnodes[L-1]; 223 nnet[0].weight[L][k] -= (eta / Nmini) * nnet[0].Nabla_w[L][k]; 224 } 225 } 226 } 227 } 228 void nnet_update_Nabla (Nnet *nnet) { 229 for (int L = 1; L < nnet[0].Nlayer; L++) { 230 231 for (int j = 0; j < nnet[0].Nnodes[L]; j++) { 232 nnet[0]. Nabla_b[L][j] += nnet[0].dNabla_b[L][j]; 233 234 for (int i = 0; i < nnet[0].Nnodes[L-1]; i++) { 235 int k = i + j*nnet[0].Nnodes[L-1]; 236 nnet[0]. Nabla_w[L][k] += nnet[0].dNabla_w[L][k]; 237 } 238 } 239 } 240 } 241 void nnet_reset_Nabla (Nnet *nnet) { 242 for (int L = 1; L < nnet[0].Nlayer; L++) { 243 244 for (int j = 0; j < nnet[0].Nnodes[L]; j++) { 245 246 nnet[0]. Nabla_b[L][j] = 0; 247 nnet[0].dNabla_b[L][j] = 0; 248 249 for (int i = 0; i < nnet[0].Nnodes[L-1]; i++) { 250 int k = i + j*nnet[0].Nnodes[L-1]; 251 nnet[0]. Nabla_w[L][k] = 0; 252 nnet[0].dNabla_w[L][k] = 0; 234 253 } 235 254 } … … 238 257 239 258 // the input values must already be copied to the input layer svalue[] 240 void nnet_feedforward (N Net *nnet) {259 void nnet_feedforward (Nnet *nnet) { 241 260 242 261 for (int i = 1; i < nnet[0].Nlayer; i++) { … … 246 265 } 247 266 248 // calcula rte z, sigmoid(z) for each layer (z = w*value + bias)249 int nnet_onelayer (N Net *nnet, int n) {250 251 if ( n< 1) return FALSE; // abort here?252 if ( n>= nnet[0].Nlayer) return FALSE; // abort here?253 254 // evaluating a single layer [ n], n > 0, n < Nlayer:255 int Ninput = nnet[0].Nnodes[ n- 1];256 int Noutput = nnet[0].Nnodes[ n];257 258 // input layer is [ n-1], output layer is [n]267 // calculate z, sigmoid(z) for each layer (z = w*value + bias) 268 int nnet_onelayer (Nnet *nnet, int L) { 269 270 if (L < 1) return FALSE; // abort here? 271 if (L >= nnet[0].Nlayer) return FALSE; // abort here? 272 273 // evaluating a single layer [L], n > 0, n < Nlayer: 274 int Ninput = nnet[0].Nnodes[L - 1]; 275 int Noutput = nnet[0].Nnodes[L]; 276 277 // input layer is [L-1], output layer is [L] 259 278 for (int j = 0; j < Noutput; j ++) { 260 279 float sum = 0; … … 262 281 // weight matrix order is (0, 1, ... Ninput-1, Ninput, Ninput + 1, ... Ninput * Noutput - 1) 263 282 int k = j * Ninput + i; 264 sum += nnet[0].weight[ n][k]*nnet[0].svalue[n-1][i];265 } 266 sum += nnet[0].biases[ n][j];267 nnet[0].zvalue[ n][j] = sum;268 nnet[0].svalue[ n][j] = nnet_sigmoid(sum);269 nnet[0].sprime[ n][j] = nnet[0].svalue[n][j] * (1 - nnet[0].svalue[n][j]);283 sum += nnet[0].weight[L][k]*nnet[0].svalue[L-1][i]; 284 } 285 sum += nnet[0].biases[L][j]; 286 nnet[0].zvalue[L][j] = sum; 287 nnet[0].svalue[L][j] = nnet_sigmoid(sum); 288 nnet[0].sprime[L][j] = nnet[0].svalue[L][j] * (1 - nnet[0].svalue[L][j]); 270 289 // note that d sigmoid / dz = sigmoid * (1 - sigmoid) 271 290 } … … 274 293 275 294 float nnet_sigmoid (float value) { 276 return 1.0 / (1.0 + exp(- sum));277 } 278 279 void sortseq (float *X, int *Y, int N) {295 return 1.0 / (1.0 + exp(-value)); 296 } 297 298 void nnet_sortseq (float *X, int *Y, int N) { 280 299 281 300 # define SWAPFUNC(A,B){ float ftmp; int itmp; \ -
trunk/Ohana/src/opihi/include/data.h
r40291 r40319 50 50 float **buffers; 51 51 } MedImageType; 52 53 /*** typedef structs used by the Neural Network functions (nnet_*) ***/ 54 typedef struct { 55 char *name; 56 int Nlayer; // Nlayers = input layer + output layer + hidden layers 57 int *Nnodes; // number of nodes per layer 58 float **weight; // a matrix between each layer 59 float **biases; // a vector for each layer 60 61 float **zvalue; // a vector of z values for each layer (= w*input + b) 62 float **svalue; // a vector of s values for each layer (= sigmoid(z)) 63 float **sprime; // 64 float **delta; // 65 66 float ** Nabla_b; // a vector of Nabla_b values for each layer 67 float **dNabla_b; // a vector of Nabla_b values for each layer 68 69 float ** Nabla_w; // a matrix of Nabla_w values for each layer 70 float **dNabla_w; // a matrix of Nabla_w values for each layer 71 } Nnet; 52 72 53 73 void InitData (void); … … 229 249 int GetKapaChannelFromString (char *string); 230 250 251 /*** Neural Network functions (nnet_*) ***/ 252 253 // in lib.data/nnet.c: 254 void InitNnets (); 255 void InitNnetData (Nnet *nnet, char *name); 256 257 void FreeNnets (); 258 void FreeNnetData (Nnet *nnet); 259 260 Nnet *GetNnet (int where); 261 Nnet *FindNnet (char *name); 262 Nnet *CreateNnet (char *name, int Nlayer); 263 void CreateNnetData (Nnet *nnet); 264 265 int DeleteNnet (Nnet *nnet); 266 void ListNnets (); 267 268 // in cmd.data/nnet.c: 269 int nnet_command (int argc, char **argv); 270 271 // in cmd.data/nnet_commands.c: 272 int nnet_init (int argc, char **argv); 273 int nnet_list (int argc, char **argv); 274 int nnet_delete (int argc, char **argv); 275 int nnet_show (int argc, char **argv); 276 int nnet_create (int argc, char **argv); 277 int nnet_set (int argc, char **argv); 278 int nnet_get (int argc, char **argv); 279 280 // in cmd.data/nnet_train.c: 281 int nnet_train (int argc, char **argv); 282 void nnet_feedforward (Nnet *nnet); 283 284 // in cmd.data/nnet_apply.c: 285 int nnet_apply (int argc, char **argv); 286 231 287 # endif -
trunk/Ohana/src/opihi/lib.data/Makefile
r39242 r40319 20 20 $(SDIR)/fft.$(ARCH).o \ 21 21 $(SDIR)/svdcmp.$(ARCH).o \ 22 $(SDIR)/svdcmp_bond_new.$(ARCH).o \22 $(SDIR)/svdcmp_bond_new.$(ARCH).o \ 23 23 $(SDIR)/bracket.$(ARCH).o \ 24 24 $(SDIR)/spline.$(ARCH).o \ … … 27 27 $(SDIR)/mrqmin.$(ARCH).o \ 28 28 $(SDIR)/mrq2dmin.$(ARCH).o \ 29 $(SDIR)/nnet.$(ARCH).o \ 29 30 $(SDIR)/precess.$(ARCH).o \ 30 31 $(SDIR)/starfuncs.$(ARCH).o \ -
trunk/Ohana/src/opihi/lib.data/nnet.c
r40317 r40319 1 1 # include "data.h" 2 3 typedef struct {4 char *name;5 int Nlayers; // Nlayers = input layer + output layer + hidden layers6 int *Nnodes; // number of nodes per layer7 float **weights; // a matrix between each layer8 float **biases; // a vector for each layer9 10 float **zvalue; // a vector of z values for each layer (= w*input + b)11 float **svalue; // a vector of s values for each layer (= sigmoid(z))12 float **sprime; //13 float **delta; //14 15 float ** Nabla_b; // a vector of Nabla_b values for each layer16 float **dNabla_b; // a vector of Nabla_b values for each layer17 18 float ** Nabla_w; // a matrix of Nabla_w values for each layer19 float **dNabla_w; // a matrix of Nabla_w values for each layer20 } NNet;21 2 22 3 static Nnet **nnets = NULL; /* nnet to store the list of all nnets */ … … 34 15 int i; 35 16 36 for (i = 0; i < Nnnets; i++) { 37 FreeNnet (nnets[i]); 17 if (!nnets) InitNnets(); 18 19 for (i = 0; i < Nnnets; i++) { 20 FreeNnetData (nnets[i]); 21 free (nnets[i]); 38 22 } 39 23 free (nnets); … … 46 30 nnet[0].name = strcreate (name); 47 31 48 nnet[0].Nlayer s= 0;32 nnet[0].Nlayer = 0; 49 33 nnet[0].Nnodes = NULL; 50 nnet[0].weight s= NULL;34 nnet[0].weight = NULL; 51 35 nnet[0].biases = NULL; 52 nnet[0]. avalue = NULL;36 nnet[0].svalue = NULL; 53 37 nnet[0].zvalue = NULL; 38 nnet[0].sprime = NULL; 39 nnet[0].delta = NULL; 54 40 55 41 nnet[0]. Nabla_b = NULL; … … 64 50 65 51 free (nnet[0].name); 66 for (i = 0; i < nnet[0].Nlayer s; i++) {67 free (nnet[0].weight s[i]);52 for (i = 0; i < nnet[0].Nlayer; i++) { 53 free (nnet[0].weight[i]); 68 54 free (nnet[0].biases[i]); 69 55 free (nnet[0].svalue[i]); … … 78 64 } 79 65 free (nnet[0].Nnodes); 80 free (nnet[0].weight s);66 free (nnet[0].weight); 81 67 free (nnet[0].biases); 82 68 free (nnet[0].svalue); … … 94 80 Nnet *GetNnet (int where) { 95 81 82 if (!nnets) InitNnets(); 83 96 84 if (where < 0) where += Nnnets; 97 85 if (where < 0) return NULL; … … 105 93 int i; 106 94 95 if (!nnets) InitNnets(); 96 107 97 for (i = 0; i < Nnnets; i++) { 108 98 if (!strcmp (nnets[i][0].name, name)) { … … 113 103 } 114 104 115 /* make a new named nnet with Nlayer s*/105 /* make a new named nnet with Nlayer */ 116 106 Nnet *CreateNnet (char *name, int Nlayer) { 117 107 118 108 int N; 119 109 Nnet *nnet; 110 111 if (!nnets) InitNnets(); 120 112 121 113 nnet = FindNnet (name); 122 114 if (nnet != NULL) { 123 115 FreeNnetData (nnet); 124 InitNnetData (nnet );116 InitNnetData (nnet, name); 125 117 return (nnet); 126 118 } … … 134 126 nnet[0].Nlayer = Nlayer; 135 127 ALLOCATE (nnet[0].Nnodes, int, Nlayer); 136 ALLOCATE (nnet[0].weight s, float *, Nlayer);128 ALLOCATE (nnet[0].weight, float *, Nlayer); 137 129 ALLOCATE (nnet[0].biases, float *, Nlayer); 138 130 ALLOCATE (nnet[0].svalue, float *, Nlayer); … … 155 147 ohana_gaussdev_init (); 156 148 157 for (int i = 1; i < Nlayer; i++) { 149 // NOTE : none of these elements are used for the first layer (the input layer) 150 // EXCEPT svalue[0] 151 152 nnet[0].weight[0] = NULL; 153 nnet[0].biases[0] = NULL; 154 nnet[0].zvalue[0] = NULL; 155 nnet[0].sprime[0] = NULL; 156 nnet[0].delta [0] = NULL; 157 nnet[0]. Nabla_b[0] = NULL; 158 nnet[0].dNabla_b[0] = NULL; 159 nnet[0]. Nabla_w[0] = NULL; 160 nnet[0].dNabla_w[0] = NULL; 161 162 ALLOCATE (nnet[0].svalue[0], float, nnet[0].Nnodes[0]); 163 164 for (int i = 1; i < nnet[0].Nlayer; i++) { 158 165 ALLOCATE (nnet[0].biases[i], float, nnet[0].Nnodes[i]); // biases for each node in the hidden and output layers only 159 166 for (int j = 0; j < nnet[0].Nnodes[i]; j++) { … … 161 168 } 162 169 163 ALLOCATE (nnet[0].weight s[i], float, nnet[0].Nnodes[i-1]*nnet[0].Nnodes[i]); // weightsconnected each node in the previous layer to the current layer (excludes input layer)170 ALLOCATE (nnet[0].weight[i], float, nnet[0].Nnodes[i-1]*nnet[0].Nnodes[i]); // weight connected each node in the previous layer to the current layer (excludes input layer) 164 171 for (int j = 0; j < nnet[0].Nnodes[i-1]*nnet[0].Nnodes[i]; j++) { 165 nnet[0].weight s[i][j] = ohana_gaussdev_rnd (0.0, 1.0);172 nnet[0].weight[i][j] = ohana_gaussdev_rnd (0.0, 1.0); 166 173 } 167 174 … … 171 178 ALLOCATE (nnet[0].delta [i], float, nnet[0].Nnodes[i]); // vectors for holding results / values for each node in the input, hidden, output layers 172 179 173 ALLOCATE (nnet[0]. Nabla_b, float, nnet[0].Nnodes[i]); 174 ALLOCATE (nnet[0].dNabla_b, float, nnet[0].Nnodes[i]); 175 176 ALLOCATE (nnet[0]. Nabla_w, float, nnet[0].Nnodes[i-1]*nnet[0].Nnodes[i]); 177 ALLOCATE (nnet[0].dNabla_w, float, nnet[0].Nnodes[i-1]*nnet[0].Nnodes[i]); 180 ALLOCATE (nnet[0]. Nabla_b[i], float, nnet[0].Nnodes[i]); 181 ALLOCATE (nnet[0].dNabla_b[i], float, nnet[0].Nnodes[i]); 182 ALLOCATE (nnet[0]. Nabla_w[i], float, nnet[0].Nnodes[i-1]*nnet[0].Nnodes[i]); 183 ALLOCATE (nnet[0].dNabla_w[i], float, nnet[0].Nnodes[i-1]*nnet[0].Nnodes[i]); 178 184 } 179 185 } … … 183 189 184 190 int i, N, NNNETS_2; 191 192 if (!nnets) InitNnets(); 185 193 186 194 /* find nnet in nnet list */ … … 204 212 } 205 213 206 FreeNnet (nnet); 214 FreeNnetData (nnet); 215 free (nnet); 207 216 return (TRUE); 208 217 } … … 213 222 int i, j; 214 223 224 if (!nnets) InitNnets(); 225 215 226 for (i = 0; i < Nnnets; i++) { 216 227 gprint (GP_ERR, "%-15s :", nnets[i][0].name); 217 for (j = 0; j < nnets[i][0].Nlayer s; i++) {228 for (j = 0; j < nnets[i][0].Nlayer; j++) { 218 229 gprint (GP_ERR, " %3d", nnets[i][0].Nnodes[j]); 219 230 }
Note:
See TracChangeset
for help on using the changeset viewer.
