2010-05-22 27 views
9

Tôi có một mạng lưới thần kinh được viết bằng Java trong đó sử dụng một hàm truyền sigmoid quy định như sau:Đẩy mạnh tính toán Math trong Java

private static double sigmoid(double x) 
{ 
    return 1/(1 + Math.exp(-x)); 
} 

và điều này được gọi là nhiều lần trong đào tạo và tính toán sử dụng mạng. Có cách nào đẩy nhanh tốc độ này không? Nó không phải là nó chậm, nó chỉ là nó được sử dụng rất nhiều, do đó, một tối ưu hóa nhỏ ở đây sẽ là một lợi ích tổng thể lớn.

+3

Giá trị của x có lặp đi lặp lại hay có nhiều khả năng chúng sẽ luôn khác nhau mỗi khi phương thức được gọi? – DaveJohnston

+0

Ngoài ra, kết quả cần phải chính xác đến mức nào? –

+0

@Dave - phụ thuộc vào độ chính xác mong muốn, nhưng chúng đều là số dấu chấm động, vì vậy khá nhiều độc đáo – Simon

Trả lời

20

Đối với mạng thần kinh, bạn không cần giá trị chính xác của hàm sigmoid. Vì vậy, bạn có thể tính toán trước 100 giá trị và tái sử dụng giá trị gần nhất với đầu vào của bạn, hoặc thậm chí tốt hơn (như một chú thích đã nêu) làm một phép nội suy từ các giá trị lân cận.

Cách bạn có thể thực hiện việc này được mô tả trong số article này (liên kết bị đánh cắp từ answer of s-lott).

Đây là hàm sigmoid: Sigmoid function graph

Như bạn có thể thấy, chỉ có giá trị từ -10 < x < 10 là thú vị chút nào. Và, như một bình luận đã nêu, hàm này là đối xứng. Bạn chỉ phải lưu trữ một nửa giá trị.


Edit: Tôi xin lỗi mà tôi đã giới thiệu đồ thị sai ở đây. Tôi đã sửa nó.

+1

Có thể cái gì đó lớn hơn 100 nếu bạn muốn chính xác hơn một chút. Một bảng tra cứu 5000 (nhưng có lẽ thậm chí 1000) giá trị sẽ hoàn toàn đủ IMHO. – nico

+2

Để có độ chính xác cao hơn, tốt hơn nên thực hiện phép nội suy tuyến tính giữa hai giá trị gần nhất. –

+2

Vấn đề là symetrical, vì vậy bạn chỉ cần một nửa giá trị. Tính toán phía bên kia là tầm thường. –

0

Từ quan điểm toán học, tôi không thấy bất kỳ khả năng nào để tối ưu hóa nó.

1

Đó là một chức năng khá mượt mà, vì vậy lược đồ tra cứu và nội suy có thể là quá đủ.

Khi tôi vẽ hàm trên một phạm vi -10 <= x <= 10, tôi nhận được độ chính xác năm vị trí ở mức cực đại. Điều đó có đủ tốt cho ứng dụng của bạn không?

5

Nếu bạn có rất nhiều các nút trong đó giá trị của x là bên ngoài -10 .. + 10 hộp, bạn chỉ có thể bỏ qua để tính toán những giá trị nào cả, ví dụ như vậy ..

if(x < -10) 
    y = 0; 
else if(x > 10) 
    y = 1; 
else 
    y = 1/(1 + Math.exp(-x)); 
return y; 

Tất nhiên, điều này gây ra chi phí của các kiểm tra có điều kiện cho MỌI tính toán, vì vậy nó chỉ đáng giá nếu bạn có nhiều nút bão hòa.

Một điều đáng nhắc đến là, nếu bạn đang sử dụng backpropagation, và bạn phải đối phó với độ dốc của hàm, tốt hơn là tính toán nó theo từng phần thay vì 'như được viết'.

Tôi không thể nhớ lại độ dốc tại thời điểm này, nhưng đây là những gì tôi đang nói về việc sử dụng một sigmoid lưỡng cực làm ví dụ. Thay vì tính cách này

y = (1 - exp(-x))/(1 + exp(-x)); 

mà lượt truy cập exp() hai lần, bạn có thể cache lên các tính toán tốn kém trong các biến tạm thời, như vậy

temp = exp(-x); 
y = (1 - temp)/(1 + temp); 

Có rất nhiều nơi để đặt các loại điều này để sử dụng trong lưới BP.

Các vấn đề liên quan