| 85 | } |
| 86 | |
| 87 | void train(const array &in, double lr = 0.1, int num_epochs = 15, |
| 88 | int batch_size = 100, int k = 1, bool verbose = false) { |
| 89 | const int num_samples = in.dims(0); |
| 90 | const int num_batches = num_samples / batch_size; |
| 91 | |
| 92 | for (int i = 0; i < num_epochs; i++) { |
| 93 | double err = 0; |
| 94 | |
| 95 | for (int j = 0; j < num_batches - 1; j++) { |
| 96 | int st = j * batch_size; |
| 97 | int en = std::min(num_samples - 1, st + batch_size - 1); |
| 98 | int num = en - st + 1; |
| 99 | |
| 100 | array v_pos = in(seq(st, en), span); |
| 101 | |
| 102 | array h_pos = vtoh(v_pos); |
| 103 | |
| 104 | array v_neg, h_neg; |
| 105 | |
| 106 | gibbs_hvh(v_neg, h_neg, h_pos, k); |
| 107 | |
| 108 | // Update weights |
| 109 | array c_pos = matmulTN(h_pos, v_pos); |
| 110 | array c_neg = matmulTN(h_neg, v_neg); |
| 111 | |
| 112 | array delta_w = lr * (c_pos - c_neg) / num; |
| 113 | array delta_vb = lr * sum(v_pos - v_neg) / num; |
| 114 | array delta_hb = lr * sum(h_pos - h_neg) / num; |
| 115 | |
| 116 | weights += delta_w; |
| 117 | v_bias += delta_vb; |
| 118 | h_bias += delta_hb; |
| 119 | |
| 120 | if (verbose) { err += error(v_pos, v_neg); } |
| 121 | } |
| 122 | |
| 123 | if (verbose) { |
| 124 | printf("Epoch %d: Reconstruction error: %0.4f\n", i + 1, |
| 125 | err / num_batches); |
| 126 | } |
| 127 | } |
| 128 | |
| 129 | if (verbose) printf("\n"); |
| 130 | } |
| 131 | }; |
| 132 | |
| 133 | int rbm_demo(bool /*console*/, int perc) { |