| 167 | } |
| 168 | |
| 169 | void test_softmaxm() |
| 170 | { |
| 171 | print_spinner(); |
| 172 | using net_type = tag1<softmaxm<tag2<input<matrix<float>>>>>; |
| 173 | net_type net; |
| 174 | |
| 175 | // Initialization |
| 176 | dlib::rand rnd(std::rand()); |
| 177 | const long nr = 2, nc = 3; |
| 178 | const int n_samples = 3, k = 1; |
| 179 | std::vector<matrix<float>> x(n_samples); |
| 180 | matrix<float> xtmp(nr, nc); |
| 181 | for (int ii = 0; ii < n_samples; ++ii) { |
| 182 | for (int jj = 0; jj < nr; ++jj) |
| 183 | for (int kk = 0; kk < nc; ++kk) { |
| 184 | float r = rnd.get_random_gaussian(); |
| 185 | if (r > 1 || r < -1) r = -std::numeric_limits<float>::infinity(); |
| 186 | xtmp(jj, kk) = r; |
| 187 | } |
| 188 | x[ii] = xtmp; |
| 189 | } |
| 190 | |
| 191 | // Convert input matrix to tensor |
| 192 | resizable_tensor input_tensor; |
| 193 | net.to_tensor(&x[0], &x[0] + n_samples, input_tensor); |
| 194 | net.forward(input_tensor); |
| 195 | |
| 196 | // Expected output tensor |
| 197 | resizable_tensor expected_output; |
| 198 | expected_output.copy_size(input_tensor); |
| 199 | for (int ii = 0; ii < n_samples; ++ii) { |
| 200 | for (int jj = 0; jj < nr; ++jj) { |
| 201 | matrix<float> m(1, nc); |
| 202 | bool all_neg_inf = true; |
| 203 | for (int kk = 0; kk < nc; ++kk) { |
| 204 | m(0, kk) = input_tensor.host()[tensor_index(input_tensor, ii, 0, jj, kk)]; |
| 205 | if (m(0, kk) > -std::numeric_limits<float>::infinity()) all_neg_inf = false; |
| 206 | } |
| 207 | |
| 208 | matrix<float> r(1, nc); |
| 209 | if (all_neg_inf) |
| 210 | for (int kk = 0; kk < nc; ++kk) r(0, kk) = 0.0f; |
| 211 | else { |
| 212 | // Stabilize the computation by subtracting the max value |
| 213 | float max_val = max(m); |
| 214 | matrix<float> exp_m = exp(m - max_val); |
| 215 | float sum_exp = sum(exp_m) + std::numeric_limits<float>::epsilon(); |
| 216 | r = exp_m / sum_exp; |
| 217 | } |
| 218 | for (int kk = 0; kk < nc; ++kk) |
| 219 | expected_output.host()[tensor_index(expected_output, ii, 0, jj, kk)] = r(0, kk); |
| 220 | } |
| 221 | } |
| 222 | |
| 223 | // Compare output tensor with expected output |
| 224 | auto& net_output = layer<tag1>(net).get_output(); |
| 225 | DLIB_TEST(max(abs(mat(net_output) - mat(expected_output))) < 1e-5); |
| 226 |
no test coverage detected