我试图使用我自己编写的神经网络来近似sine()函数。我已经在一个简单的OCR问题上测试了我的神经网络并且它有效,但我无法应用它来近似sine()。我的问题是在训练期间我的误差正好收敛到50%,所以我猜它完全是随机的。
我使用一个输入神经元作为输入(0到PI),并使用一个输出神经元作为结果。我有一个隐藏层,我可以在其中改变神经元的数量,但我目前正在尝试大约6-10。
我感觉问题是因为我使用sigmoid传递函数(这是我的应用程序中的一个要求),它只输出0到1之间,而sine()的输出介于-1和1之间。尝试纠正这个我尝试将输出乘以2然后减去1,但这并没有解决问题。我想我必须在某处做某种转换才能使这项工作。
有什么想法吗?
答案 0 :(得分: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")
答案 1 :(得分: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()'})
答案 2 :(得分:0)
没有理由你的网络不能正常工作,尽管6对于近似正弦波肯定是偏低的。我会尝试至少10个甚至20个。
如果这不起作用,那么我认为您需要提供有关系统的更多详细信息。即学习算法(反向传播?),学习速率等。
答案 3 :(得分:0)
如果使用香草梯度下降,我会得到相同的行为。尝试使用不同的训练算法。
就Java applet而言,我注意到了一些有趣的东西:如果我使用“双极sigmoid”并且我从一些非随机权重(例如使用Quadratic函数的先前训练的结果)开始,它会收敛)。