| @@ -1,6 +1,7 @@ | |||
| import numpy as np | |||
| import megengine as mge | |||
| import megengine.autodiff as ad | |||
| import megengine.functional as F | |||
| import megengine.module as M | |||
| import megengine.optimizer as optim | |||
| @@ -35,57 +36,54 @@ class XORNet(M.Module): | |||
| return x | |||
| @trace(symbolic=True) | |||
| def train_fun(data, label, net=None, opt=None): | |||
| net.train() | |||
| pred = net(data) | |||
| loss = F.cross_entropy_with_softmax(pred, label) | |||
| opt.backward(loss) | |||
| return pred, loss | |||
| @trace(symbolic=True) | |||
| def val_fun(data, label, net=None): | |||
| net.eval() | |||
| pred = net(data) | |||
| loss = F.cross_entropy_with_softmax(pred, label) | |||
| return pred, loss | |||
| @trace(symbolic=True) | |||
| def pred_fun(data, net=None): | |||
| net.eval() | |||
| pred = net(data) | |||
| pred_normalized = F.softmax(pred) | |||
| return pred_normalized | |||
| def main(): | |||
| if not mge.is_cuda_available(): | |||
| mge.set_default_device("cpux") | |||
| net = XORNet() | |||
| gm = ad.GradManager().attach(net.parameters()) | |||
| opt = optim.SGD(net.parameters(), lr=0.01, momentum=0.9) | |||
| batch_size = 64 | |||
| train_dataset = minibatch_generator(batch_size) | |||
| val_dataset = minibatch_generator(batch_size) | |||
| data = mge.tensor() | |||
| label = mge.tensor(np.zeros((batch_size,)), dtype=np.int32) | |||
| def train_fun(data, label): | |||
| opt.clear_grad() | |||
| with gm: | |||
| pred = net(data) | |||
| loss = F.cross_entropy_with_softmax(pred, label) | |||
| gm.backward(loss) | |||
| opt.step() | |||
| return pred, loss | |||
| def val_fun(data, label): | |||
| pred = net(data) | |||
| loss = F.cross_entropy_with_softmax(pred, label) | |||
| return pred, loss | |||
| @trace(symbolic=True, capture_as_const=True) | |||
| def pred_fun(data): | |||
| pred = net(data) | |||
| pred_normalized = F.softmax(pred) | |||
| return pred_normalized | |||
| data = np.random.random((batch_size, 2)).astype(np.float32) | |||
| label = np.zeros((batch_size,)).astype(np.int32) | |||
| train_loss = [] | |||
| val_loss = [] | |||
| for step, minibatch in enumerate(train_dataset): | |||
| if step > 1000: | |||
| break | |||
| data.set_value(minibatch["data"]) | |||
| label.set_value(minibatch["label"]) | |||
| opt.zero_grad() | |||
| _, loss = train_fun(data, label, net=net, opt=opt) | |||
| data = minibatch["data"] | |||
| label = minibatch["label"] | |||
| net.train() | |||
| _, loss = train_fun(data, label) | |||
| train_loss.append((step, loss.numpy())) | |||
| if step % 50 == 0: | |||
| minibatch = next(val_dataset) | |||
| _, loss = val_fun(data, label, net=net) | |||
| net.eval() | |||
| _, loss = val_fun(data, label) | |||
| loss = loss.numpy()[0] | |||
| val_loss.append((step, loss)) | |||
| print("Step: {} loss={}".format(step, loss)) | |||
| @@ -108,8 +106,10 @@ def main(): | |||
| ] | |||
| ) | |||
| data.set_value(test_data) | |||
| out = pred_fun(data, net=net) | |||
| # tracing only accepts tensor as input | |||
| data = mge.tensor(test_data, dtype=np.float32) | |||
| net.eval() | |||
| out = pred_fun(data) | |||
| pred_output = out.numpy() | |||
| pred_label = np.argmax(pred_output, 1) | |||
| @@ -125,11 +125,8 @@ def main(): | |||
| model_name = "xornet_deploy.mge" | |||
| if pred_fun.enabled: | |||
| print("Dump model as {}".format(model_name)) | |||
| pred_fun.dump(model_name, arg_names=["data"]) | |||
| else: | |||
| print("pred_fun must be run with trace enabled in order to dump model") | |||
| print("Dump model as {}".format(model_name)) | |||
| pred_fun.dump(model_name, arg_names=["data"]) | |||
| if __name__ == "__main__": | |||