2009-10-14 41 views
18

Tôi đang cố gắng ước tính hàm sin() sử dụng mạng nơ-ron mà tôi đã tự viết. Tôi đã thử nghiệm mạng thần kinh của tôi trên một vấn đề OCR đơn giản đã và nó đã làm việc, nhưng tôi gặp khó khăn khi áp dụng nó để ước tính sin(). Vấn đề của tôi là trong quá trình huấn luyện, lỗi của tôi hội tụ chính xác 50%, vì vậy tôi đoán nó hoàn toàn ngẫu nhiên.Chức năng gần đúng với mạng nơron

Tôi đang sử dụng một nơron đầu vào cho đầu vào (0 đến PI) và một nơron đầu ra cho kết quả. Tôi có một lớp ẩn duy nhất trong đó tôi có thể thay đổi số lượng tế bào thần kinh nhưng hiện tại tôi đang thử khoảng 6-10.

Tôi có cảm giác vấn đề là vì tôi đang sử dụng hàm truyền hình sigmoid (yêu cầu trong ứng dụng của tôi) chỉ xuất ra từ 0 đến 1, trong khi đầu ra cho sin() là giữa -1 và 1. Để cố gắng sửa lỗi này, tôi đã thử nhân đầu ra với 2 và sau đó trừ đi 1, nhưng điều này không khắc phục được sự cố. Tôi nghĩ rằng tôi phải làm một số loại chuyển đổi ở đâu đó để thực hiện công việc này.

Bất kỳ ý tưởng nào?

+0

Nếu bạn quan tâm thấy việc triển khai nghiên cứu về xấp xỉ dựa trên NN, hãy xem [bài khảo sát về tính toán gần đúng] của tôi (https://www.academia.edu/20201007/A_Survey_Of_Techniques_for_Approximate_Computing) có thể trả lời chi tiết câu hỏi của bạn. – user984260

Trả lời

16

Sử dụng đơn vị đầu ra tuyến tính tuyến tính.

Dưới đây là một ví dụ đơn giản sử dụng R:

set.seed(1405) 
x <- sort(10*runif(50)) 
y <- sin(x) + 0.2*rnorm(x) 

library(nnet) 
nn <- nnet(x, y, size=6, maxit=40, linout=TRUE) 
plot(x, y) 
plot(sin, 0, 10, add=TRUE) 
x1 <- seq(0, 10, by=0.1) 
lines(x1, predict(nn, data.frame(x=x1)), col="green") 

neural net prediction

+0

Bằng đơn vị đầu ra tuyến tính, bạn có muốn tính f (net) = net cho đơn vị đầu ra không? Bởi vì tôi đã thử điều này và vẫn còn có cùng một vấn đề. – MahlerFive

+0

Chính xác, hàm tuyến tính f (x) = a * x – rcs

+0

Chi tiết nhỏ, nhưng siêu liên kết r-project.org của bạn không hoạt động mà không cần thêm "www." –

11

Khi bạn đào tạo mạng, bạn nên bình thường hóa các mục tiêu (chức năng tội lỗi) để khoảng [0,1], sau đó bạn có thể giữ chức năng chuyển đổi sigmoid.

sin(x) in [-1,1] => 0.5*(sin(x)+1) in [0,1] 

Train data: 
    input target target_normalized 
    ------------------------------------ 
    0   0   0.5 
    pi/4  0.70711 0.85355 
    pi/2  1   1 
    ... 

Lưu ý rằng chúng tôi đã ánh xạ mục tiêu trước khi đào tạo. Khi bạn đào tạo và mô phỏng mạng, bạn có thể ánh xạ lại đầu ra của mạng.


Sau đây là một mã MATLAB để minh họa:

%% input and target 
input = linspace(0,4*pi,200); 
target = sin(input) + 0.2*randn(size(input)); 

% mapping 
[targetMinMax,mapping] = mapminmax(target,0,1); 

%% create network (one hidden layer with 6 nodes) 
net = newfit(input, targetMinMax, [6], {'tansig' 'tansig'}); 
net.trainParam.epochs = 50; 
view(net) 

%% training 
net = init(net);       % init 
[net,tr] = train(net, input, targetMinMax); % train 
output = sim(net, input);     % predict 

%% view prediction 
plot(input, mapminmax('reverse', output, mapping), 'r', 'linewidth',2), hold on 
plot(input, target, 'o') 
plot(input, sin(input), 'g') 
hold off 
legend({'predicted' 'target' 'sin()'}) 

network output

0

Không có lý do mạng của bạn không nên làm việc, mặc dù 6 chắc chắn là ở phía bên thấp xấp xỉ sóng sin. Tôi muốn thử ít nhất 10 thậm chí có thể 20.

Nếu điều đó không hiệu quả thì tôi nghĩ bạn cần cung cấp thêm chi tiết về hệ thống của bạn. tức là thuật toán học tập (tuyên truyền ngược?), tỷ lệ học tập, v.v.

0

Tôi nhận được cùng một hành vi nếu sử dụng độ dốc vani. Hãy thử sử dụng một thuật toán đào tạo khác. Theo như Java applet có liên quan, tôi đã chú ý điều gì đó thú vị: nó hội tụ nếu tôi sử dụng "lưỡng cực sigmoid" và tôi bắt đầu với một số trọng lượng không ngẫu nhiên (chẳng hạn như kết quả từ một khóa huấn luyện trước đó bằng cách sử dụng Quadratic chức năng).

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