22

我正在尝试使用我自己编写的神经网络来近似 sine() 函数。我已经在一个简单的 OCR 问题上测试了我的神经网络并且它有效,但是我无法将它应用于近似正弦()。我的问题是,在训练过程中,我的误差恰好收敛到 50%,所以我猜它是完全随机的。

我使用一个输入神经元作为输入(0 到 PI),一个输出神经元作为结果。我有一个隐藏层,我可以在其中改变神经元的数量,但我目前正在尝试大约 6-10 个。

我感觉问题是因为我使用的是 sigmoid 传递函数(这是我的应用程序中的要求),它只输出 0 和 1 之间,而 sine() 的输出在 -1 和 1 之间。尝试纠正我尝试将输出乘以 2,然后减去 1,但这并没有解决问题。我想我必须在某处进行某种转换才能使这项工作正常进行。

有任何想法吗?

4

4 回答 4

16

使用线性输出单元

这是一个使用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")

神经网络预测

于 2009-10-14T09:23:45.503 回答
12

训练网络时,应该将目标(sin 函数)归一化到 [0,1] 范围内,然后可以保留 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
    ...

请注意,我们在训练之前映射了目标。一旦你训练和模拟了网络,你就可以映射回网络的输出。


下面是一个MATLAB代码来说明:

%% 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()'})

网络 输出

于 2009-10-15T22:41:10.840 回答
0

如果使用香草梯度下降,我会得到相同的行为。尝试使用不同的训练算法。

就 Java 小程序而言,我确实注意到了一些有趣的事情:如果我使用“双极 sigmoid”并且我从一些非随机权重开始(例如之前使用二次函数训练的结果),它确实会收敛。

于 2012-06-22T05:30:57.733 回答
0

您的网络没有理由不工作,尽管 6 对于近似正弦波来说绝对是偏低的。我会尝试至少10个甚至20个。

如果这不起作用,那么我认为您需要提供有关系统的更多详细信息。即学习算法(反向传播?),学习率等。

于 2009-10-21T09:30:47.053 回答