我想得到一个在 matlab 中运行的简单示例,它将使用神经网络从输入输出数据(基本上是模型识别)中学习任意函数,然后能够仅从输入数据中近似该函数。作为训练这个网络的手段,我在 matlab 中实现了一个简单的反向传播算法,但我无法获得接近令人满意的结果。我想知道我可能做错了什么以及我可以使用什么方法。
目标是让网络表示一个已识别的函数 f(x),该函数将一系列 x 作为输入,并输出从 x -> y 学习到的映射。
这是我到目前为止的 GNU 八度代码:
pkg load control signal
function r = sigmoid(z)
r = 1 ./ (1 + exp(-z));
end
function r = linear(z)
r = z;
end
function r = grad_sigmoid(z)
r = sigmoid(z) .* (1 - sigmoid(z));
end
function r = grad_linear(z)
r = 1;
end
function r = grad_tanh(z)
r = 1 - tanh(z) .^ 2;
end
function nn = nn_init(n_input, n_hidden1, n_hidden2, n_output)
nn.W2 = (rand(n_input, n_hidden1) * 2 - 1)'
nn.W3 = (rand(n_hidden1, n_hidden2) * 2 - 1)'
nn.W4 = (rand(n_hidden2, n_output) * 2 - 1)'
nn.lambda = 0.005;
end
function nn = nn_train(nn_in, state, action)
nn = nn_in;
[out, nn] = nn_eval(nn, state);
d4 = (nn.a4 - action) .* grad_linear(nn.W4 * nn.a3);
d3 = (nn.W4' * d4) .* grad_tanh(nn.W3 * nn.a2);
d2 = (nn.W3' * d3) .* grad_tanh(nn.W2 * nn.a1);
nn.W4 -= nn.lambda * (d4 * nn.a3');
nn.W3 -= nn.lambda * (d3 * nn.a2');
nn.W2 -= nn.lambda * (d2 * nn.a1');
end
function [out,nn] = nn_eval(nn_in, state)
nn = nn_in;
nn.z1 = state;
nn.a1 = nn.z1;
nn.a2 = tanh(nn.W2 * nn.a1);
nn.a3 = tanh(nn.W3 * nn.a2);
nn.a4 = linear(nn.W4 * nn.a3);
out = nn.a4;
end
nn = nn_init(1, 100, 100, 1);
t = 1:0.1:3.14*10;
input = t;
output = sin(input);
learned = zeros(1, length(output));
for j = 1:500
for i = 1:length(input)
nn = nn_train(nn, [input(i)], [output(i)]);
end
j
end
for i = 1:length(input)
learned(i) = nn_eval(nn, [input(i)]);
end
plot(t, output, 'g', t, learned, 'b');
pause
结果甚至不接近我想要的位置。它与我的反向传播实现有关吗?
我需要对代码进行哪些更改才能获得更好的近似值?