Calculates the softsign `(x/(1+|x|))` of the given input tensor element-wise.
| 2881 | |
| 2882 | |
| 2883 | class SoftSign(Operator): |
| 2884 | """ |
| 2885 | Calculates the softsign `(x/(1+|x|))` of the given input tensor element-wise. |
| 2886 | """ |
| 2887 | |
| 2888 | def __init__(self): |
| 2889 | super(SoftSign, self).__init__() |
| 2890 | |
| 2891 | def forward(self, x): |
| 2892 | """ |
| 2893 | Return `(x/(1+|x|))`, where x is CTensor. |
| 2894 | """ |
| 2895 | # y = x / (1 + np.abs(x)) |
| 2896 | if training: |
| 2897 | self.input = x |
| 2898 | x1 = singa.AddFloat(singa.Abs(x), 1.0) |
| 2899 | y = singa.__div__(x, x1) |
| 2900 | |
| 2901 | return y |
| 2902 | |
| 2903 | def backward(self, dy): |
| 2904 | """ |
| 2905 | Args: |
| 2906 | dy (CTensor): the gradient tensor from upper operations |
| 2907 | Returns: |
| 2908 | CTensor, the gradient over input |
| 2909 | """ |
| 2910 | dx = singa.AddFloat(singa.Abs(self.input), 1.0) |
| 2911 | dx = singa.PowFloat(singa.Square(dx), -1.0) |
| 2912 | dx = singa.__mul__(dy, dx) |
| 2913 | return dx |
| 2914 | |
| 2915 | |
| 2916 | def softsign(x): |