pytorch/test/cpp/api/optim.cpp
Peter Goldsborough 28b1a3852c
Add backward() to Tensor and Variable (#7774)
* Add backward() to Tensor and Variable

* Add at:: in front of Tensor

* Trying to not move optional to appease windows?

* Move implementation into cpp file

* Undo some formatting changes
2018-05-24 17:31:41 -07:00

95 lines
2.5 KiB
C++

#include <catch.hpp>
#include <torch/nn/module.h>
#include <torch/nn/modules/linear.h>
#include <torch/nn/modules/sequential.h>
#include <torch/optimizers.h>
#include <test/cpp/api/util.h>
using namespace torch;
using namespace torch::nn;
bool test_optimizer_xor(Optimizer optim, std::shared_ptr<Sequential> model) {
float running_loss = 1;
int epoch = 0;
while (running_loss > 0.1) {
int64_t bs = 4;
auto inp = at::CPU(at::kFloat).tensor({bs, 2});
auto lab = at::CPU(at::kFloat).tensor({bs});
for (size_t i = 0; i < bs; i++) {
const int64_t a = std::rand() % 2;
const int64_t b = std::rand() % 2;
const int64_t c = static_cast<uint64_t>(a) ^ static_cast<uint64_t>(b);
inp[i][0] = a;
inp[i][1] = b;
lab[i] = c;
}
// forward
auto y = Var(lab, false);
std::function<at::Scalar()> closure = [&]() -> at::Scalar {
optim->zero_grad();
auto x = model->forward(Var(inp));
Variable loss = at::binary_cross_entropy(x, y);
loss.backward();
return at::Scalar(loss.data());
};
at::Scalar loss = optim->step(closure);
running_loss = running_loss * 0.99 + loss.toFloat() * 0.01;
if (epoch > 3000) {
return false;
}
epoch++;
}
return true;
}
TEST_CASE("optim") {
std::srand(0);
setSeed(0);
auto model = std::make_shared<Sequential>(
SigmoidLinear(Linear(2, 8).build()), SigmoidLinear(Linear(8, 1).build()));
// FLAKY!
// SECTION("lbfgs") {
// auto optim = LBFGS(model, 5e-2).max_iter(5).make();
// REQUIRE(test_optimizer_xor(optim, model));
// }
SECTION("sgd") {
auto optim =
SGD(model, 1e-1).momentum(0.9).nesterov().weight_decay(1e-6).make();
REQUIRE(test_optimizer_xor(optim, model));
}
SECTION("adagrad") {
auto optim = Adagrad(model, 1.0).weight_decay(1e-6).lr_decay(1e-3).make();
REQUIRE(test_optimizer_xor(optim, model));
}
SECTION("rmsprop_simple") {
auto optim = RMSprop(model, 1e-1).centered().make();
REQUIRE(test_optimizer_xor(optim, model));
}
SECTION("rmsprop") {
auto optim = RMSprop(model, 1e-1).momentum(0.9).weight_decay(1e-6).make();
REQUIRE(test_optimizer_xor(optim, model));
}
/*
// This test appears to be flaky, see
https://github.com/pytorch/pytorch/issues/7288 SECTION("adam") { auto optim =
Adam(model, 1.0).weight_decay(1e-6).make(); REQUIRE(test_optimizer_xor(optim,
model));
}
*/
SECTION("amsgrad") {
auto optim = Adam(model, 0.1).weight_decay(1e-6).amsgrad().make();
REQUIRE(test_optimizer_xor(optim, model));
}
}