1import numpy 2 3from chainer.backends import cuda 4from chainer import function_node 5from chainer import utils 6from chainer.utils import type_check 7 8 9class Expm1(function_node.FunctionNode): 10 11 @property 12 def label(self): 13 return 'expm1' 14 15 def check_type_forward(self, in_types): 16 type_check._argname(in_types, ('x',)) 17 type_check.expect(in_types[0].dtype.kind == 'f') 18 19 def forward_cpu(self, x): 20 self.retain_outputs((0,)) 21 return utils.force_array(numpy.expm1(x[0])), 22 23 def forward_gpu(self, x): 24 self.retain_outputs((0,)) 25 return cuda.cupy.expm1(x[0]), 26 27 def backward(self, indexes, gy): 28 y = self.get_retained_outputs()[0] 29 return (y + 1.0) * gy[0], 30 31 32def expm1(x): 33 """Elementwise exponential minus one function. 34 35 Args: 36 x (:class:`~chainer.Variable` or :ref:`ndarray`): Input variable. 37 38 Returns: 39 ~chainer.Variable: Output variable. 40 """ 41 return Expm1().apply((x,))[0] 42