Đây là một hàm sigmoid logistic:
Tôi biết x. Làm cách nào để tính F (x) trong Python bây giờ?
Giả sử x = 0,458.
F (x) =?
Đây là một hàm sigmoid logistic:
Tôi biết x. Làm cách nào để tính F (x) trong Python bây giờ?
Giả sử x = 0,458.
F (x) =?
Câu trả lời:
Điều này nên làm điều đó:
import math
def sigmoid(x):
return 1 / (1 + math.exp(-x))
Và bây giờ bạn có thể kiểm tra nó bằng cách gọi:
>>> sigmoid(0.458)
0.61253961344091512
Cập nhật : Lưu ý rằng phần trên chủ yếu nhằm mục đích dịch trực tiếp một thành một của biểu thức đã cho thành mã Python. Nó không được thử nghiệm hoặc được biết là một triển khai âm thanh số. Nếu bạn biết bạn cần một triển khai rất mạnh mẽ, tôi chắc chắn có những người khác mà mọi người thực sự đã đưa ra vấn đề này.
math.exp
bằng np.exp
bạn sẽ không nhận được NaN, mặc dù bạn sẽ nhận được cảnh báo thời gian chạy.
math.exp
với mảng numpy có thể mang lại một số lỗi, như : TypeError: only length-1 arrays can be converted to Python scalars
. Để tránh nó, bạn nên sử dụng numpy.exp
.
x = max(-709,x)
trước biểu thức?
Nó cũng có sẵn trong 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
vốn chỉ là một trình bao bọc tốn kém (vì nó cho phép bạn chia tỷ lệ và dịch hàm logistic) của một hàm scipy khác:
In [3]: from scipy.special import expit
In [4]: expit(0.458)
Out[4]: 0.61253961344091512
Nếu bạn quan tâm về màn trình diễn tiếp tục đọc, nếu không chỉ cần sử dụng 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
Như mong đợi logistic.cdf
là (nhiều) chậm hơn expit
. expit
vẫn chậm hơn sigmoid
hàm python khi được gọi với một giá trị duy nhất vì đây là hàm phổ quát được viết bằng C ( http://docs.scipy.org/doc/numpy/reference/ufuncs.html ) và do đó có một cuộc gọi trên đầu. Chi phí này lớn hơn tốc độ tính toán expit
được đưa ra bởi bản chất được biên dịch của nó khi được gọi với một giá trị duy nhất. Nhưng nó trở nên không đáng kể khi nói đến mảng lớn:
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))
....:
(Bạn sẽ nhận thấy sự thay đổi nhỏ từ math.exp
sang np.exp
(cái đầu tiên không hỗ trợ mảng, nhưng nhanh hơn nhiều nếu bạn chỉ có một giá trị để tính toán))
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
Nhưng khi bạn thực sự cần hiệu năng, một thực tế phổ biến là có một bảng được tính toán trước của hàm sigmoid giữ RAM, và trao đổi một số độ chính xác và bộ nhớ cho một số tốc độ (ví dụ: http://radimrehurek.com/2013/09 / word2vec-in-python-part-hai-tối ưu hóa / )
Ngoài ra, lưu ý rằng expit
việc triển khai ổn định về số lượng kể từ phiên bản 0.14.0: https://github.com/scipy/scipy/issues/3385
Dưới đây là cách bạn sẽ triển khai sigmoid logistic theo cách ổn định về số lượng (như được mô tả ở đây ):
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)
Hoặc có lẽ điều này chính xác hơn:
import numpy as np
def sigmoid(x):
return math.exp(-np.logaddexp(0, -x))
Trong nội bộ, nó thực hiện các điều kiện tương tự như trên, nhưng sau đó sử dụng log1p
.
Nói chung, sigmoid logistic đa thức là:
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
và rebased_q
bởi tau
? bởi vì tôi đã thử điều đó và tôi không nhận được xác suất nào bằng 1
q
) cho nhiệt độ của bạn. rebasing_q có thể là bất cứ điều gì: nó không thay đổi câu trả lời; nó cải thiện sự ổn định số.
nat_to_exp
là tương đương với softmax (như bạn đã đề cập trong câu trả lời khác của bạn) không? Sao chép-dán của nó trả về xác suất không tổng bằng 1
cách khác
>>> def sigmoid(x):
... return 1 /(1+(math.e**-x))
...
>>> sigmoid(0.458)
pow
thường được thực hiện dưới dạng exp
và log
, vì vậy sử dụng exp
trực tiếp gần như chắc chắn tốt hơn.
x
rất tiêu cực.
Một cách khác bằng cách chuyển đổi tanh
chức năng:
sigmoid = lambda x: .5 * (math.tanh(.5 * x) + 1)
Tôi cảm thấy nhiều người có thể quan tâm đến các tham số miễn phí để thay đổi hình dạng của hàm sigmoid. Thứ hai cho nhiều ứng dụng bạn muốn sử dụng chức năng sigmoid được nhân đôi. Thứ ba, bạn có thể muốn thực hiện chuẩn hóa đơn giản, ví dụ các giá trị đầu ra nằm trong khoảng từ 0 đến 1.
Thử:
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
Và để vẽ và so sánh:
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
Cuối cùng:
x = np.linspace(0,1,100)
Travel_function = draw_function_on_2x2_grid(x)
Câu trả lời hay từ @unwind. Tuy nhiên, nó không thể xử lý số cực âm (ném OverflowError).
Cải thiện của tôi:
def sigmoid(x):
try:
res = 1 / (1 + math.exp(-x))
except OverflowError:
res = 0.0
return res
Tensorflow cũng bao gồm một sigmoid
chức năng:
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
Một phiên bản ổn định về số của hàm sigmoid logistic.
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)
Một lót ...
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
hoặc numpy array
:Các câu trả lời hàng đầu là các phương thức được tối ưu hóa để tính điểm đơn lẻ, nhưng khi bạn muốn áp dụng các phương thức này cho một chuỗi gấu trúc hoặc mảng numpy, nó đòi hỏi apply
, về cơ bản là vòng lặp trong nền và sẽ lặp lại trên mỗi hàng và áp dụng phương thức. Điều này khá không hiệu quả.
Để tăng tốc mã của chúng tôi, chúng tôi có thể sử dụng vector hóa và phát sóng 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
Hoặc với một pandas Series
:
x = pd.Series(np.arange(-5,5))
np.divide(1, 1+np.exp(-x))
bạn có thể tính toán nó như sau:
import math
def sigmoid(x):
return 1 / (1 + math.exp(-x))
hoặc khái niệm, sâu hơn và không có bất kỳ nhập khẩu:
def sigmoid(x):
return 1 / (1 + 2.718281828 ** -x)
hoặc bạn có thể sử dụng numpy cho ma trận:
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)
Đoạn mã trên là hàm sigmoid logistic trong python. Nếu tôi biết điều đó x = 0.467
, Hàm sigmoid , F(x) = 0.385
. Bạn có thể thử thay thế bất kỳ giá trị nào của x bạn biết trong đoạn mã trên và bạn sẽ nhận được một giá trị khác F(x)
.
sigmoid = lambda x: 1 / (1 + math.exp(-x))