| 58 | } |
| 59 | |
| 60 | void TestTrain::do_train(SymbolVar dev_w_updated, const char* type) { |
| 61 | int iter = 0; |
| 62 | float err; |
| 63 | auto update_err = [&]() { |
| 64 | err = 0; |
| 65 | auto p0 = host_w->ptr<float>(), p1 = host_w_truth->ptr<float>(); |
| 66 | for (size_t i = 0; i < DIM; i++) { |
| 67 | auto d = p0[i] - p1[i]; |
| 68 | err += d * d; |
| 69 | } |
| 70 | err = sqrt(err / DIM); |
| 71 | mgb_log("iter %d: lr=%.2e err=%.5f", iter, learning_rate->get<float>(), err); |
| 72 | }; |
| 73 | auto copy_w = [&](DeviceTensorND& data) { |
| 74 | if (iter % 20 == 0) { |
| 75 | host_w->comp_node(data.comp_node()); |
| 76 | host_w->copy_from_fixlayout(data).sync(); |
| 77 | update_err(); |
| 78 | } |
| 79 | }; |
| 80 | auto func = graph->compile({{dev_w_updated, copy_w}}); |
| 81 | |
| 82 | func->to_json()->writeto_fpath(output_file(ssprintf("train-%s.json", type))); |
| 83 | |
| 84 | learning_rate->set<float>(-0.3 / NR_DATA); |
| 85 | update_err(); |
| 86 | ASSERT_GE(err, 1); |
| 87 | while (iter < 100) { |
| 88 | iter++; |
| 89 | func->execute(); |
| 90 | } |
| 91 | |
| 92 | ASSERT_LE(err, 1e-3); |
| 93 | if (expected_err == -1) { |
| 94 | expected_err = err; |
| 95 | } else { |
| 96 | MGB_ASSERT_FLOAT_EQ(err, expected_err); |
| 97 | } |
| 98 | } |
| 99 | |
| 100 | TEST_F(TestTrain, SimpleLinearRegression) { |
| 101 | SymbolVar dev_w = opr::SharedDeviceTensor::make(*graph, *host_w, {"w"}), |
nothing calls this directly
no test coverage detected