提交 efa90388 authored 作者: Frederic Bastien's avatar Frederic Bastien

add a stabilization optimization for the grad of log(erfc).

上级 8bd24b6b
差异被折叠。
......@@ -1754,6 +1754,61 @@ class T_local_erfc(unittest.TestCase):
raise KnownFailureTest("the python code upcast somewhere internally some value of float32 to python float for part of its computation. That make that the c and python code don't generate the same value. You can ignore this error.")
assert all(numpy.isfinite(f(val)))
def test_local_grad_log_erfc_neg(self):
val = [-100,-30,-27,-26.4,-26.2,-26,-11,-10,-9,-3,-2,-1,0,1,2,3,9,10,11,27,26.4,26.2,26,28,30,100]
if theano.config.mode in ["DebugMode", "DEBUG_MODE", "FAST_COMPILE"]:
#python mode don't like the inv(0) in computation, but the switch don't select this value. So it is computed for no good reason.
val.remove(0)
if theano.config.mode in ["DebugMode", "DEBUG_MODE"] and theano.config.floatX=='float32':
# In float32 their is a plage of values close to 10 that we stabilize as it give bigger error then the stabilized version.
# The orig value in float32 -30.0, the stab value -20.1 the orig value in float64 -18.1.
val.remove(10)
val = numpy.asarray(val)
x = T.vector()
#their is some nan that will happear in the graph for the log of the negatives values
mode = copy.copy(self.mode)
mode.check_isfinite = False
mode.allow_remove_inf = True
mode_fusion = copy.copy(self.mode_fusion)
mode_fusion.check_isfinite = False
mode_fusion.allow_remove_inf = True
f = theano.function([x],T.grad(T.log(T.erfc(x)),x), mode=mode)
#theano.printing.debugprint(f)
assert len(f.maker.env.nodes)==22, len(f.maker.env.nodes)
assert not any([hasattr(n.op,'scalar_op') and n.op.scalar_op==scal.pow for n in f.maker.env.nodes])
assert all(numpy.isfinite(f(val)))
assert f.maker.env.outputs[0].dtype==theano.config.floatX
#test with a different mul constant
f = theano.function([x],T.mul(T.exp(T.neg(T.sqr(x))),-10.12837917)/T.erfc(x), mode=mode)
#theano.printing.debugprint(f)
assert len(f.maker.env.nodes)==22, len(f.maker.env.nodes)
assert f.maker.env.outputs[0].dtype==theano.config.floatX
assert not any([hasattr(n.op,'scalar_op') and n.op.scalar_op==scal.pow for n in f.maker.env.nodes])
assert all(numpy.isfinite(f(val)))
#test that we work without the mul
f = theano.function([x],T.exp(T.neg(T.sqr(x)))/T.erfc(x), mode=mode)
theano.printing.debugprint(f)
assert len(f.maker.env.nodes)==21, len(f.maker.env.nodes)
assert f.maker.env.outputs[0].dtype==theano.config.floatX
assert not any([hasattr(n.op,'scalar_op') and n.op.scalar_op==scal.pow for n in f.maker.env.nodes])
assert all(numpy.isfinite(f(val)))
f = theano.function([x],T.grad(T.log(T.erfc(x)),x), mode=mode_fusion)
assert len(f.maker.env.nodes)==1, len(f.maker.env.nodes)
assert f.maker.env.outputs[0].dtype==theano.config.floatX
assert not any([hasattr(n.op,'scalar_op') and n.op.scalar_op==scal.pow for n in f.maker.env.nodes])
#TODO: fix this problem
if theano.config.floatX=="float32" and theano.config.mode in ["DebugMode", "DEBUG_MODE"]:
#Showing this test error is a duplicate of the one in test_local_log_erfc. We hide it.
#raise KnownFailureTest("the python code upcast somewhere internally some value of float32 to python float for part of its computation. That make that the c and python code don't generate the same value. You can ignore this error. This happen in an intermediate step that don't show in the final result.")
pass
else:
assert all(numpy.isfinite(f(val)))
def speed_local_log_erfc(self):
val = numpy.random.rand(1e6)
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论