提交 e2e6cc46 authored 作者: Frederic's avatar Frederic

Add ultra_fast_sigmoid.

上级 149e6717
......@@ -3,4 +3,5 @@ from conv import conv2d, ConvOp
from Conv3D import *
from ConvGrad3D import *
from ConvTransp3D import *
from sigm import softplus, sigmoid, sigmoid_inplace, scalar_sigmoid
from sigm import (softplus, sigmoid, sigmoid_inplace,
scalar_sigmoid, ultra_fast_sigmoid)
......@@ -124,6 +124,74 @@ sigmoid_inplace = elemwise.Elemwise(
pprint.assign(sigmoid, printing.FunctionPrinter('sigmoid'))
class UltraFastScalarSigmoid(scalar.UnaryScalarOp):
"""
This is just speed opt. Not for stability.
"""
@staticmethod
def st_impl(x):
x = 0.5 * x
# The if is a tanh approximate.
if x >= 0:
if x < 1.7:
z = (1.5 * x / (1 + x))
elif x < 3:
z = (0.935409070603099 + 0.0458812946797165 * (x - 1.7))
else:
z = 0.99505475368673
else:
xx = -x
if xx < 1.7:
z = (1.5 * xx / (1 + xx))
elif xx < 3:
z = (0.935409070603099 + 0.0458812946797165 * (xx - 1.7))
else:
z = 0.99505475368673
z = -z
return 0.5 * (z + 1.)
def impl(self, x):
return UltraFastScalarSigmoid.st_impl(x)
def c_code(self, node, name, inp, out, sub):
x, = inp
z, = out
dtype = node.outputs[0].type.dtype_specs()[1]
return """
%(dtype)s x = 0.5 * %(x)s;
// The if is a tanh approximate.
if(x>=0) {
%(z)s = (x<1.7 ? (1.5*x/(1+x)) :
(x<3 ? (0.935409070603099 + 0.0458812946797165*(x-1.7)):
0.99505475368673));
} else {
%(dtype)s xx = -x;
%(z)s = -(xx<1.7 ? (1.5*xx/(1+xx)) :
(xx<3 ? (0.935409070603099 + 0.0458812946797165*(xx-1.7)):
0.99505475368673));
}
//%(z)s = 0.5*(ultrafasttanh(0.5*x)+1.);
%(z)s = 0.5*(%(z)s+1.);
""" % locals()
ultra_fast_scalar_sigmoid = UltraFastScalarSigmoid(
scalar.upgrade_to_float, name='ultra_fast_scalar_sigmoid')
ultra_fast_sigmoid = elemwise.Elemwise(ultra_fast_scalar_sigmoid,
name='ultra_fast_sigmoid')
ultra_fast_sigmoid_inplace = elemwise.Elemwise(
UltraFastScalarSigmoid(scalar.transfer_type(0)),
inplace_pattern={0: 0},
name='ultra_fast_sigmoid_inplace',
)
pprint.assign(ultra_fast_sigmoid,
printing.FunctionPrinter('ultra_fast_sigmoid'))
class ScalarSoftplus(scalar.UnaryScalarOp):
@staticmethod
def static_impl(x):
......
......@@ -9,8 +9,13 @@ from theano import config
from theano.tests import unittest_tools as utt
from theano.tensor.nnet import sigmoid, sigmoid_inplace, softplus, tensor
from theano.tensor.nnet.sigm import (
compute_mul, is_1pexp, parse_mul_tree, perform_sigm_times_exp,
register_local_1msigmoid, simplify_mul)
compute_mul, is_1pexp, parse_mul_tree, perform_sigm_times_exp,
register_local_1msigmoid, simplify_mul,
ultra_fast_sigmoid,
)
from theano.tensor.tests.test_basic import (makeBroadcastTester, rand,
check_floatX,
_good_broadcast_unary_normal_no_complex)
class T_sigmoid(unittest.TestCase):
......@@ -21,6 +26,18 @@ class T_sigmoid(unittest.TestCase):
utt.verify_grad(sigmoid, [numpy.random.rand(3, 4)])
UltraFastSigmoidTester = makeBroadcastTester(
op=ultra_fast_sigmoid,
expected=lambda inputs: check_floatX(
inputs, 1/(1+numpy.exp(-inputs))),
good=_good_broadcast_unary_normal_no_complex,
#grad=_grad_broadcast_unary_normal,
name='UltraFastSigmoidTester',
#test_name=False,
# This is an approx of the sigmoid. That is why we raise eps
eps=5e-2)
class T_softplus(unittest.TestCase):
def setUp(self):
utt.seed_rng()
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论