| 167 | , hidden(hidden_layers) {} |
| 168 | |
| 169 | void train(const array &input, const array &target, double lr_rbm = 1.0, |
| 170 | double lr_nn = 1.0, const int epochs_rbm = 15, |
| 171 | const int epochs_nn = 300, const int batch_size = 100, |
| 172 | double maxerr = 1.0, bool verbose = false) { |
| 173 | // Pre-training hidden layers |
| 174 | array X = input; |
| 175 | for (int i = 0; i < num_hidden; i++) { |
| 176 | if (verbose) { printf("Training Hidden Layer %d\n", i); } |
| 177 | |
| 178 | int visible = (i == 0) ? in_size : hidden[i - 1]; |
| 179 | |
| 180 | rbm r(visible, hidden[i]); |
| 181 | r.train(X, lr_rbm, epochs_rbm, batch_size, verbose); |
| 182 | |
| 183 | X = r.prop_up(X); |
| 184 | weights[i] = r.get_weights(); |
| 185 | |
| 186 | if (verbose) { printf("\n"); } |
| 187 | } |
| 188 | |
| 189 | weights[num_hidden] = |
| 190 | 0.05 * randu(hidden[num_hidden - 1] + 1, out_size) - 0.0025; |
| 191 | |
| 192 | const int num_samples = input.dims(0); |
| 193 | const int num_batches = num_samples / batch_size; |
| 194 | |
| 195 | // Training the entire network |
| 196 | for (int i = 0; i < epochs_nn; i++) { |
| 197 | for (int j = 0; j < num_batches; j++) { |
| 198 | int st = j * batch_size; |
| 199 | int en = std::min(num_samples - 1, st + batch_size - 1); |
| 200 | |
| 201 | array x = input(seq(st, en), span); |
| 202 | array y = target(seq(st, en), span); |
| 203 | |
| 204 | // Propagate the inputs forward |
| 205 | vector<array> signals = forward_propagate(x); |
| 206 | array out = signals[num_total - 1]; |
| 207 | |
| 208 | // Propagate the error backward |
| 209 | back_propagate(signals, y, lr_nn); |
| 210 | } |
| 211 | |
| 212 | // Validate with last batch |
| 213 | int st = (num_batches - 1) * batch_size; |
| 214 | int en = num_samples - 1; |
| 215 | array out = predict(input(seq(st, en), span)); |
| 216 | double err = error(out, target(seq(st, en), span)); |
| 217 | |
| 218 | // Check if convergence criteria has been met |
| 219 | if (err < maxerr) { |
| 220 | printf("Converged on Epoch: %4d\n", i + 1); |
| 221 | return; |
| 222 | } |
| 223 | |
| 224 | if (verbose) { |
| 225 | if ((i + 1) % 10 == 0) |
| 226 | printf("Epoch: %4d, Error: %0.4f\n", i + 1, err); |