답변:
이것은해야합니다 :
import math
def sigmoid(x):
return 1 / (1 + math.exp(-x))
이제 다음을 호출하여 테스트 할 수 있습니다.
>>> sigmoid(0.458)
0.61253961344091512
업데이트 : 위의 내용은 주로 주어진 표현식을 파이썬 코드로 일대일로 직접 변환하기위한 것입니다. 그것은되어 있지 시험 또는 수치 사운드 구현 것으로 알려져 있습니다. 매우 강력한 구현이 필요하다는 것을 알고 있다면 사람들이 실제로이 문제를 생각한 다른 곳이 있다고 확신합니다.
math.exp
에 np.exp
당신은 런타임 경고를 얻을 것이다 있지만, NaN을을받지 않습니다.
math.exp
numpy 배열과 함께 사용하면 다음 과 같은 오류가 발생할 수 있습니다 TypeError: only length-1 arrays can be converted to Python scalars
. 이를 피하려면을 사용해야합니다 numpy.exp
.
x = max(-709,x)
표현식 앞에 추가하여 수치 적 불안정성을 완화 할 수 있습니까 ?
scipy에서도 사용 가능합니다 : http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.logistic.html
In [1]: from scipy.stats import logistic
In [2]: logistic.cdf(0.458)
Out[2]: 0.61253961344091512
이것은 다른 scipy 함수의 비용이 많이 드는 래퍼 일뿐입니다 (물류 함수를 확장하고 변환 할 수 있기 때문에).
In [3]: from scipy.special import expit
In [4]: expit(0.458)
Out[4]: 0.61253961344091512
퍼포먼스가 계속해서 걱정된다면 계속 읽으십시오 expit
.
In [5]: def sigmoid(x):
....: return 1 / (1 + math.exp(-x))
....:
In [6]: %timeit -r 1 sigmoid(0.458)
1000000 loops, best of 1: 371 ns per loop
In [7]: %timeit -r 1 logistic.cdf(0.458)
10000 loops, best of 1: 72.2 µs per loop
In [8]: %timeit -r 1 expit(0.458)
100000 loops, best of 1: 2.98 µs per loop
예상 logistic.cdf
보다 (훨씬) 느립니다 expit
. C ( http://docs.scipy.org/doc/numpy/reference/ufuncs.html )로 작성된 범용 함수 이므로 호출 오버 헤드 가 있기 때문에 단일 값으로 호출 할 때 expit
여전히 파이썬 sigmoid
함수 보다 속도가 느립니다 . 이 오버 헤드는 단일 값으로 호출 될 때 컴파일 된 특성으로 인한 계산 속도 향상보다 큽니다 . 그러나 큰 배열에 관해서는 무시할 수 있습니다.expit
In [9]: import numpy as np
In [10]: x = np.random.random(1000000)
In [11]: def sigmoid_array(x):
....: return 1 / (1 + np.exp(-x))
....:
(당신의 작은 변화를 알 수 있습니다 math.exp
에 대한 np.exp
첫 번째는 배열을 지원하지 않습니다 (을하지만, 훨씬 더 빨리 당신이 계산하는 하나 개의 값이있는 경우입니다))
In [12]: %timeit -r 1 -n 100 sigmoid_array(x)
100 loops, best of 1: 34.3 ms per loop
In [13]: %timeit -r 1 -n 100 expit(x)
100 loops, best of 1: 31 ms per loop
그러나 실제로 성능이 필요한 경우 일반적인 관행은 RAM에 저장되어있는 시그 모이 드 함수의 미리 계산 된 테이블을 가지고 약간의 속도와 정밀도 및 메모리를 교환하는 것입니다 (예 : http://radimrehurek.com/2013/09). / word2vec-in-python-part-two-optimizing / )
또한 expit
버전 0.14.0부터 구현이 수치 적으로 안정적입니다. https://github.com/scipy/scipy/issues/3385
여기에 (설명 된대로이 수치 안정의 방법으로 물류 시그 모이를 구현하는 것이 방법은 여기 )
def sigmoid(x):
"Numerically-stable sigmoid function."
if x >= 0:
z = exp(-x)
return 1 / (1 + z)
else:
z = exp(x)
return z / (1 + z)
아니면 더 정확할 수도 있습니다.
import numpy as np
def sigmoid(x):
return math.exp(-np.logaddexp(0, -x))
내부적으로는 위와 동일한 조건을 구현하지만를 사용합니다 log1p
.
일반적으로 다항 로지스틱 시그 모이 드는 다음과 같습니다.
def nat_to_exp(q):
max_q = max(0.0, np.max(q))
rebased_q = q - max_q
return np.exp(rebased_q - np.logaddexp(-max_q, np.logaddexp.reduce(rebased_q)))
max_q
및 rebased_q
의해 tau
? 내가 그것을 시도하고 1에 해당하는 확률을 얻을 수 없기 때문에
q
)를 온도로 나눕니다 . rebased_q는 무엇이든 될 수 있습니다. 답을 바꾸지 않습니다. 수치 안정성을 향상시킵니다.
nat_to_exp
(당신이 당신의 다른 답변에서 언급 한)이 softmax에 해당? 그것의 복사-붙여 넣기는 1에 해당하지 않는 확률을 반환합니다
또 다른 방법
>>> def sigmoid(x):
... return 1 /(1+(math.e**-x))
...
>>> sigmoid(0.458)
pow
자주의 관점에서 구현 exp
및 log
사용 때문에, exp
직접하는 것은 거의 확실 좋습니다.
x
매우 음일 때 오버플로로 고통받습니다 .
tanh
함수 를 변환하여 다른 방법으로 :
sigmoid = lambda x: .5 * (math.tanh(.5 * x) + 1)
나는 많은 사람들이 S 자형 함수의 모양을 바꾸는 자유 매개 변수에 관심이 있다고 생각합니다. 많은 애플리케이션에서 두 번째로 미러 된 시그 모이 드 기능을 사용하려고합니다. 셋째, 예를 들어 출력 값이 0과 1 사이 인 간단한 정규화를 원할 수 있습니다.
시험:
def normalized_sigmoid_fkt(a, b, x):
'''
Returns array of a horizontal mirrored normalized sigmoid function
output between 0 and 1
Function parameters a = center; b = width
'''
s= 1/(1+np.exp(b*(x-a)))
return 1*(s-min(s))/(max(s)-min(s)) # normalize function to 0-1
그리고 그리기와 비교하기 :
def draw_function_on_2x2_grid(x):
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2)
plt.subplots_adjust(wspace=.5)
plt.subplots_adjust(hspace=.5)
ax1.plot(x, normalized_sigmoid_fkt( .5, 18, x))
ax1.set_title('1')
ax2.plot(x, normalized_sigmoid_fkt(0.518, 10.549, x))
ax2.set_title('2')
ax3.plot(x, normalized_sigmoid_fkt( .7, 11, x))
ax3.set_title('3')
ax4.plot(x, normalized_sigmoid_fkt( .2, 14, x))
ax4.set_title('4')
plt.suptitle('Different normalized (sigmoid) function',size=10 )
return fig
드디어:
x = np.linspace(0,1,100)
Travel_function = draw_function_on_2x2_grid(x)
Tensorflow에는 다음 sigmoid
기능 도 포함됩니다 .
https://www.tensorflow.org/versions/r1.2/api_docs/python/tf/sigmoid
import tensorflow as tf
sess = tf.InteractiveSession()
x = 0.458
y = tf.sigmoid(x)
u = y.eval()
print(u)
# 0.6125396
로지스틱 시그 모이 드 함수의 수치 적으로 안정적인 버전입니다.
def sigmoid(x):
pos_mask = (x >= 0)
neg_mask = (x < 0)
z = np.zeros_like(x,dtype=float)
z[pos_mask] = np.exp(-x[pos_mask])
z[neg_mask] = np.exp(x[neg_mask])
top = np.ones_like(x,dtype=float)
top[neg_mask] = z[neg_mask]
return top / (1 + z)
pandas DataFrame/Series
또는 numpy array
:상단 답변은 단일 포인트 계산에 최적화 된 방법이지만 이러한 방법을 팬더 시리즈 또는 numpy 배열에 적용하려면 apply
기본적으로 백그라운드에서 루프 용이며 모든 행을 반복하여 적용합니다. 이것은 매우 비효율적입니다.
코드 속도를 높이기 위해 벡터화 및 numpy 방송을 사용할 수 있습니다.
x = np.arange(-5,5)
np.divide(1, 1+np.exp(-x))
0 0.006693
1 0.017986
2 0.047426
3 0.119203
4 0.268941
5 0.500000
6 0.731059
7 0.880797
8 0.952574
9 0.982014
dtype: float64
또는 pandas Series
:
x = pd.Series(np.arange(-5,5))
np.divide(1, 1+np.exp(-x))
import numpy as np
def sigmoid(x):
s = 1 / (1 + np.exp(-x))
return s
result = sigmoid(0.467)
print(result)
위의 코드는 파이썬의 로지스틱 S 자형 함수입니다. 내가 알면 x = 0.467
, 시그 모이 드 함수 F(x) = 0.385
. 위의 코드에서 아는 x 값을 대체하려고 시도하면 다른 값이 F(x)
됩니다.
sigmoid = lambda x: 1 / (1 + math.exp(-x))