Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

fast sigmoid aproximations

1,744 views
Skip to first unread message

Kasper H

unread,
Sep 7, 2002, 6:07:32 AM9/7/02
to
I'm curious about any fast sigmoid (logistic & tanh) function
approximations you may know about. I'd be grateful if you could detail
them here for me.

Thanks.

dan michaels

unread,
Sep 9, 2002, 10:26:00 AM9/9/02
to
Kasper H <kaspe...@franklin.net> wrote in message news:<grjjnus78n8n3uff3...@4ax.com>...

> I'm curious about any fast sigmoid (logistic & tanh) function
> approximations you may know about. I'd be grateful if you could detail
> them here for me.


What about a piecewise linear function, with a constant slope region
in the middle and saturation levels on the 2 ends? Fast and nonlinear.

.........+----
......../
......./
...---+


- dan michaels
www.oricomtech.com
===========================

Thies Heidecke

unread,
Sep 10, 2002, 8:33:12 PM9/10/02
to

"Kasper H" <kaspe...@franklin.net> schrieb im Newsbeitrag
news:grjjnus78n8n3uff3...@4ax.com...

> I'm curious about any fast sigmoid (logistic & tanh) function
> approximations you may know about. I'd be grateful if you could detail
> them here for me.
Hi Kasper,
there are many possible solutions. Which is appropriate for your task
depends on your needs:
Is precision important or just raw speed?
Do you have memory to spare or do you want a "cpu-only"-approximation?

just two ideas:
-Precalculate a look-up-table with the Sigmoid-function values
and perform a linear (or perhaps cubic) interpolation to get
intermediate values.
Pro: very fast
Con: occupies memory
-Get a good interpolation-polynom that fits your performance- and
precision-needs and calculate the function-values this way.

just for fun i let my GA calculate the coefficients of the following
polynom. It's designed for the range [-4.5, 4.5] and has a maximum
deviation of 0.002 from the exact values in this range. For values
between 4.5 and 9 i evolved another poly of lower order. for higher
values the error is so low that the function returns just 1 or -1
respectively.

some c-code:

float fast_sigmoid(float x) {
float absx = (float)fabs(x);
float xx;
if(absx>8.713655f) {
if(x>0) return 1.0f;
else return 0.0f;
} else {
xx = x*x;
if(absx>4.5f) {
if(x>0) return (float)(((3.2e-7*xx-8.544e-5)*xx+9.99869e-3)*x+0.953157);
else return (float)(((3.2e-7*xx-8.544e-5)*xx+9.99869e-3)*x+0.046843);
} else {
return
(float)((((((-5e-8*xx+3.6e-6)*xx-1.0621e-4)*xx+1.75410e-3)*xx-0.02045660)*xx+0
.24990936)*x+0.499985);
}
}
}

The values returned by this code have a maximum error of ~0.0026 at -4.5 and
4.5

I hope this was helpful to you.
> Thanks.
No problem

Greetings,
Thies


Kasper H

unread,
Sep 11, 2002, 6:29:42 PM9/11/02
to
Thanks for your response Thies. It is very interesting.

TrolletAtskynetDOTbe

unread,
Sep 17, 2002, 4:18:43 AM9/17/02
to

I've been puzzled by the idea that it may look like a transistor's
transfer function - the most complex part of a neuron implemented with
one transistor, calucating output in one cycle?

... but you need some stuff to try it :-)

Atle


Jonathan Dinerstein

unread,
Sep 21, 2002, 12:23:24 PM9/21/02
to
Kasper H <kaspe...@franklin.net> wrote in message news:<grjjnus78n8n3uff3...@4ax.com>...

I discovered a fast activation function that I like a lot. It's very
simple, fast, and doesn't require a lookup table. I only found one
reference to it on the internet, where it was called fast-sigmoid or
fsigmoid, but here it is:

x / (1 + abs(x))

I've used it in a backprop neural net, and it works great. The only
challenge is the derivative, which is a little complex, but I computed
it using Mathematica.

Jonathan Dinerstein
jondin...@yahoo.com

Alexis

unread,
Sep 27, 2002, 5:01:59 AM9/27/02
to
Kasper H <kaspe...@franklin.net> wrote in message news:<grjjnus78n8n3uff3...@4ax.com>...
> I'm curious about any fast sigmoid (logistic & tanh) function
> approximations you may know about. I'd be grateful if you could detail
> them here for me.
>

Thats funny, I just made some tests about this yesterday. I basically
used a simple look-up table instead of computing the sigmoid each
time, and its exactly 100 times faster!

Heres the C++ code (sigmoid is defined a C++ function object)

#include <iostream>
#include <sstream>
#include <memory>
#include <vector>
#include <list>
#include <cmath>
#include <memory>
#include <boost/timer.hpp>

class Sigmoid
{
public:
Sigmoid(int start, int end, int precision);
~Sigmoid() {};

float operator() (float value) const;

float sigmoid(float value){
return (1.0f / (1.0f + exp(-value)));
}

private:
// std::vector<float> array;
float* array;

long precision_, start_, end_;
};

Sigmoid::Sigmoid(int start, int end, int precision):
// array((end-start)*precision),
precision_(precision),
start_(start),
end_(end)
{
array = new float[(end-start)*precision];
for(long i=0 ; i< (end-start)*precision ; ++i){
float value = (static_cast<float>(i)/
static_cast<float>(precision))-
static_cast<float>(end_);
// std::cout << value << " ";
array[i] = (1.0f / (1.0f + exp(-value)));
// std::cout << i << " " << array[i] << std::endl;
}
}

// float Sigmoid::operator() (float value) const
// {
// float ret=0.0f;
// if(value > static_cast<float>(end_)){
// ret = 1.0f;
// }else if(value < static_cast<float>(start_)){
// ret = 0.0f;
// }else{
// ret = array[static_cast<long>(((value +
// static_cast<float>(end_))*
// static_cast<float>(precision_)))];
// }
// return ret;
// }

float Sigmoid::operator() (float value) const
{
float ret=0.0f;
if(value > static_cast<float>(end_)){
ret = 1.0f;
}else if(value < static_cast<float>(start_)){
ret = 0.0f;
}else{
ret = (1.0f / (1.0f + exp(-value)));
}
return ret;
// return (1.0f / (1.0f + exp(-value)));
}

using boost::timer;

int main(void)
{
timer full;
double tstart=0.0, tstart2=0.0;
int start=-15, end=15, precision=1000000;

Sigmoid activation(start, end, precision);

// return 0;

timer loop;
for(float value=start-10 ; value<end+10 ; value +=
1.0f/(float)precision){
// std :: cout << activation(value) << " ";
// std::cout << activation.sigmoid(value) << " " << value <<
std::endl;
activation(value);
}
std::cout << "loop=" << loop.elapsed() << std::endl;
std::cout << "run=" << full.elapsed() << std::endl;
}

SKarrila

unread,
Sep 27, 2002, 9:22:24 AM9/27/02
to
The SNNS manual calls this "Elliott" activation function, sorry I haven't
got further refs.

Seppo

"Jonathan Dinerstein" <jondin...@yahoo.com> wrote in message
news:bf0fe52f.02092...@posting.google.com...

a

unread,
Sep 27, 2002, 12:12:38 PM9/27/02
to
Have a look at
http://www.dontveter.com/bpr/activate.html

It has this act.fn. plus a few other fast ones.

It states the deriv.fn. of
y = x / (1 + |x|)
is
1/((1+|x|)*(1+|x|))

Marc

GOGAR

unread,
Sep 28, 2002, 8:02:32 AM9/28/02
to
How significant do you suppose the speed of the sigmoid function is compared
to all the multiplications involved with propagating the values through the
network?

Chris

"Alexis" <nur...@ematic.com> wrote in message
news:2f0c7ab9.02092...@posting.google.com...

Alexis

unread,
Sep 29, 2002, 7:37:39 AM9/29/02
to
1) Well, first of all, if one aims at improving speed, he shouldnt be
biased in any way. Therefore, any potential improvement is a step
torwards the final goal. I havent had time to benchmark the speed
gain, but I will.

2) I dont totally agree with you. I dont think the sigmoid function is
not significant compared to the rest of processing. Its probably not
the main bottleneck, but you can deny its not costly to make a call to
the exp function. And as I said, any speed gain is welcome.

3) you should read again the subject of this thread.

Alexis

"GOGAR" <ange...@kabelfoon.nl> wrote in message news:<an45ej$g3t$1...@news.kabelfoon.nl>...

pradeep kumar reddy

unread,
Oct 17, 2021, 1:27:32 PM10/17/21
to
can provide link of paper
0 new messages