Skip to content

Commit

Permalink
reimplement cross-entropy operator in recommender example with NDArray (
Browse files Browse the repository at this point in the history
apache#8588)

* use ndarray in crossentropy

* add performance test in crossentropy
  • Loading branch information
solin319 authored and piiswrong committed Nov 8, 2017
1 parent 8dc09ec commit 6da0472
Showing 1 changed file with 22 additions and 11 deletions.
33 changes: 22 additions & 11 deletions example/recommenders/crossentropy.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"""Cross-entropy loss layer for MXNet.
"""
import os
import time

import numpy as np
import mxnet as mx
Expand Down Expand Up @@ -51,10 +52,10 @@ def forward(self, is_train, req, in_data, out_data, aux):
# d = number of dimensions
actually_calculate_loss = False
if actually_calculate_loss:
p = in_data[0].asnumpy() # shape=(b,d)
y = in_data[1].asnumpy()
out = y * np.log(p+self.eps) + (1.-y) * np.log((self.eps1) - p)
self.assign(out_data[0], req[0], mx.nd.array(out))
p = in_data[0] # shape=(b,d)
y = in_data[1]
out = y * mx.nd.log(p+self.eps) + (1.-y) * mx.nd.log((self.eps1) - p)
self.assign(out_data[0], req[0], out)
else:
# Just copy the predictions forward
self.assign(out_data[0], req[0], in_data[0])
Expand All @@ -70,19 +71,19 @@ def approx_backward(self, req, out_grad, in_data, out_data, in_grad, aux):
grad = 1/(p-1+y)
which is more numerically stable
"""
p = in_data[0].asnumpy() # shape=(b,d)
y = in_data[1].asnumpy()
p = in_data[0] # shape=(b,d)
y = in_data[1]
grad = -1. / (p - self.eps_1 + y)
self.assign(in_grad[0], req[0], mx.nd.array(grad))
self.assign(in_grad[0], req[0], grad)


def exact_backward(self, req, out_grad, in_data, out_data, in_grad, aux):
"""grad = (y-p)/(p-p^2)
"""
p = in_data[0].asnumpy() # shape=(b,d)
y = in_data[1].asnumpy() # seems right
p = in_data[0] # shape=(b,d)
y = in_data[1] # seems right
grad = (p - y) / ((p+self.eps) * (self.eps1 - p))
self.assign(in_grad[0], req[0], mx.nd.array(grad))
self.assign(in_grad[0], req[0], grad)


@mx.operator.register("CrossEntropyLoss")
Expand Down Expand Up @@ -126,5 +127,15 @@ def infer_shape(self, in_shape):
out = e.outputs[0].asnumpy()
if np.abs(out).max() > 1e20:
raise ValueError("output too high!")
print("Done with test")

print("performance test")
sz = (6,4)
d = mx.nd.array(rand.uniform(0.01,0.99,sz))
l = mx.nd.array(rand.randint(0,2,sz))
e = net.bind(ctx=mx.cpu(), args={'data':d, 'labs':l})
tic = time.time()
for i in range(5000):
e.forward()
e.outputs[0].wait_to_read()
print("5000 tests costs time: %f s" % (time.time()-tic))
print("Done with test")

0 comments on commit 6da0472

Please sign in to comment.