Bu bir lojistik sigmoid işlevidir:
Biliyorum x. Python'da şimdi nasıl F (x) hesaplayabilirim?
Diyelim x = 0.458.
F (x) =?
Bu bir lojistik sigmoid işlevidir:
Biliyorum x. Python'da şimdi nasıl F (x) hesaplayabilirim?
Diyelim x = 0.458.
F (x) =?
Yanıtlar:
Bunu yapmalı:
import math
def sigmoid(x):
return 1 / (1 + math.exp(-x))
Ve şimdi arayarak test edebilirsiniz:
>>> sigmoid(0.458)
0.61253961344091512
Güncelleme : Yukarıdaki ifadenin temel olarak verilen ifadenin Python koduna doğrudan birebir çevirisi olarak tasarlandığını unutmayın. O edilir değil test veya sayısal olarak ses uygulaması olarak da bilinir. Çok sağlam bir uygulamaya ihtiyacınız olduğunu biliyorsanız, insanların gerçekten bu soruna biraz düşündükleri başkaları olduğuna eminim.
math.exp
ile np.exp
Aşağıdaki videoyu çalışma zamanı uyarıları alacak olsa, NaN'ler alamayacak.
math.exp
gibi bazı hatalar verebilir numpy dizi: TypeError: only length-1 arrays can be converted to Python scalars
. Bundan kaçınmak için kullanmalısınız numpy.exp
.
x = max(-709,x)
, ifadeden önce eklenerek hafifletilebilir mi?
Scipy'de de mevcuttur: 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
bu da başka bir scipy fonksiyonunun sadece pahalı bir sarıcısıdır (çünkü lojistik fonksiyonunu ölçeklendirmenize ve çevirmenize izin verir):
In [3]: from scipy.special import expit
In [4]: expit(0.458)
Out[4]: 0.61253961344091512
Performanslar konusunda endişeleriniz varsa okumaya devam edin, aksi takdirde sadece kullanın 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
Beklendiği gibi logistic.cdf
(çok) daha yavaştır expit
. C ile yazılmış evrensel bir işlev olduğu için tek bir değerle çağrıldığında expit
python sigmoid
işlevinden hala daha yavaştır ( http://docs.scipy.org/doc/numpy/reference/ufuncs.html ) ile ve bu nedenle bir çağrı yükü vardır. Bu ek yük, expit
tek bir değerle çağrıldığında derlenmiş doğası tarafından verilen hesaplama hızından daha büyüktür . Ancak büyük diziler söz konusu olduğunda ihmal edilebilir hale gelir:
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))
....:
(İle arasındaki küçük değişikliği fark edeceksiniz math.exp
.np.exp
ilki diziler desteklemez (ama çok daha hızlı bilgi işlem için yalnızca bir değer varsa olduğunu))
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
Ancak gerçekten performansa ihtiyacınız olduğunda, yaygın bir uygulama, RAM'de bulunan sigmoid işlevinin önceden hesaplanmış bir tablosuna sahip olmak ve bir miktar hassasiyet ve bellek alıp biraz hızlandırmaktır (örneğin: http://radimrehurek.com/2013/09 / word2vec-in-python-bölüm-iki en iyileştirme / )
Ayrıca, expit
uygulamanın 0.14.0 sürümünden beri sayısal olarak kararlı olduğunu unutmayın : https://github.com/scipy/scipy/issues/3385
Lojistik sigmoidi sayısal olarak kararlı bir şekilde nasıl uygulayacağınız ( burada açıklandığı gibi ):
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)
Ya da belki de bu daha doğrudur:
import numpy as np
def sigmoid(x):
return math.exp(-np.logaddexp(0, -x))
Dahili olarak, yukarıdaki ile aynı koşulu uygular, ancak daha sonra kullanır log1p
.
Genel olarak, çok terimli lojistik sigmoid:
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
ve rebased_q
tarafından tau
? çünkü bunu denedim ve 1
q
) sıcaklığınıza bölün . rebased_q herhangi bir şey olabilir: cevabı değiştirmez; sayısal kararlılığı artırır.
nat_to_exp
softmax'a eşdeğer olduğundan emin misiniz (diğer cevabınızda belirttiğiniz gibi)? Kopyala-yapıştır, toplamı 1 olan olasılıkları döndürür
diğer yol
>>> def sigmoid(x):
... return 1 /(1+(math.e**-x))
...
>>> sigmoid(0.458)
pow
genellikle doğrudan uygulanır exp
ve log
bu yüzden exp
doğrudan kullanmak neredeyse kesinlikle daha iyidir.
x
çok olumsuz olduğunda taşmalardan muzdariptir .
tanh
İşlevi dönüştürerek başka bir yol :
sigmoid = lambda x: .5 * (math.tanh(.5 * x) + 1)
Birçoğunun sigmoid fonksiyonunun şeklini değiştirmek için serbest parametrelerle ilgilenebileceğini hissediyorum. İkinci olarak birçok uygulama için yansıtılmış bir sigmoid işlevi kullanmak istiyorsunuz. Üçüncü olarak, basit bir normalleştirme yapmak isteyebilirsiniz, örneğin çıktı değerleri 0 ile 1 arasındadır.
Deneyin:
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
Ve çizmek ve karşılaştırmak için:
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
En sonunda:
x = np.linspace(0,1,100)
Travel_function = draw_function_on_2x2_grid(x)
@ Unwind'dan iyi cevap. Ancak aşırı negatif sayıyı işleyemez (OverflowError atar).
Benim gelişimim:
def sigmoid(x):
try:
res = 1 / (1 + math.exp(-x))
except OverflowError:
res = 0.0
return res
Tensorflow ayrıca bir sigmoid
işlev içerir :
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
Lojistik sigmoid fonksiyonunun sayısal olarak kararlı bir versiyonu.
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)
Bir astar ...
In[1]: import numpy as np
In[2]: sigmoid=lambda x: 1 / (1 + np.exp(-x))
In[3]: sigmoid(3)
Out[3]: 0.9525741268224334
pandas DataFrame/Series
Veya kullanılırken vectorized yöntem numpy array
:En iyi yanıtlar, tek noktalı hesaplama için optimize edilmiş yöntemlerdir, ancak bu yöntemleri bir panda serisine veya numpy dizisine uygulamak istediğinizde, apply
, temelde arka planda döngü için olan ve her satırda yinelenecek ve yöntemi uygulayacaktır. Bu oldukça verimsiz.
Kodumuzu hızlandırmak için vektörleştirme ve numpy yayınlardan yararlanabiliriz:
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
Veya aşağıdakilerle pandas Series
:
x = pd.Series(np.arange(-5,5))
np.divide(1, 1+np.exp(-x))
şu şekilde hesaplayabilirsiniz:
import math
def sigmoid(x):
return 1 / (1 + math.exp(-x))
veya kavramsal, daha derin ve herhangi bir ithalat olmadan:
def sigmoid(x):
return 1 / (1 + 2.718281828 ** -x)
veya matrisler için numpy kullanabilirsiniz:
import numpy as np #make sure numpy is already installed
def sigmoid(x):
return 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)
Yukarıdaki kod python'daki lojistik sigmoid fonksiyonudur. Bunu x = 0.467
bilsem, Sigmoid fonksiyonu F(x) = 0.385
. Yukarıdaki kodda bildiğiniz herhangi bir x değerini değiştirmeyi deneyebilirsiniz ve farklı bir değer elde edersiniz F(x)
.
sigmoid = lambda x: 1 / (1 + math.exp(-x))