3

我试图创建一个神经网络来估计 y = x ^ 2。所以我创建了一个合适的神经网络,并给它一些输入和输出的样本。我试图用 C++ 构建这个网络。但是结果和我预想的不一样。

使用以下输入:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 4 4 4 4 4 64 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71

以及以下输出:

0 1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289 324 361 400 441 484 529 576 625 676 729 784 841 900 961 1024 1089 1156 1225 1296 1369 1444 1521 1600 1681 1764 1849 1936 2025 2116 2209 2304 2401 2500 2601 2704 2809 2916 3025 3136 3249 3364 3481 3481 3600 3721 3844 3969 4096 4225 4225 4356 4489 4489 4624 4761 4761 4900 5041 4900 5041 1 4 9 16 25 841 900 961 1024 1089 1156 1225 1296 1369 1369 1444 1521 1600 1681 1764 1849 1936 2025 2116 2209 2209 2304 2500 2500 2500 2601 2704 2704 2704 2704 2709 2916 2809 2916 3025

我使用了拟合工具网络。与矩阵行。训练是 70%,验证是 15%,测试也是 15%。隐藏神经元的数量是两个。然后在命令行中我写了这个:

purelin(net.LW{2}*tansig(net.IW{1}*inputTest+net.b{1})+net.b{2})

其他信息:

我的 net.b[1] 是:-1.16610230053776 1.16667147712026

我的 net.b[2] 是:51.3266249426358

而 net.IW(1) 是:0.344272596370387 0.344111217766824

net.LW(2) 是:31.7635369693519 -31.8082184881063

当我的 inputTest 是 3 时,这个命令的结果是 16,而它应该是大约 9。我是不是在某个地方出错了?

我在 MATLAB中发现 Stack Overflow post Neural network包含一个类似我的问题的问题,但有一点不同,不同之处在于该问题的输入和输出范围是相同的,但在我的问题中不是。该解决方案说我需要扩大结果,但我怎样才能扩大我的结果呢?

4

1 回答 1

6

你是对的关于缩放。如链接答案中所述,默认情况下,神经网络将输入和输出缩放到范围 [-1,1]。这可以在网络处理功能配置中看到:

>> net = fitnet(2);

>> net.inputs{1}.processFcns
ans =
    'removeconstantrows'    'mapminmax'

>> net.outputs{2}.processFcns
ans =
    'removeconstantrows'    'mapminmax'

应用于输入/输出的第二个预处理函数mapminmax具有以下参数:

>> net.inputs{1}.processParams{2}
ans =
    ymin: -1
    ymax: 1

>> net.outputs{2}.processParams{2}
ans =
    ymin: -1
    ymax: 1

将两者映射到范围 [-1,1] (训练之前)。

这意味着经过训练的网络期望输入值在此范围内,并且输出值也在同一范围内。如果您想手动向网络提供输入,并自己计算输出,则必须在输入处缩放数据,并在输出处反转映射。

最后要记住的一件事是,每次训练ANN时,都会得到不同的权重。如果您想要可重现的结果,则需要修复随机数生成器的状态(每次都使用相同的种子对其进行初始化)。阅读有关 和 等函数的rng文档RandStream

您还必须注意,如果您将数据划分为训练/测试/验证集,则每次都必须使用相同的拆分(可能也受到我提到的随机性方面的影响)。


这是一个说明这个想法的例子(改编自我的另一篇文章):

%%# data
x = linspace(-71,71,200);            %# 1D input
y_model = x.^2;                      %# model
y = y_model + 10*randn(size(x)).*x;  %# add some noise

%%# create ANN, train, simulate
net = fitnet(2);                     %# one hidden layer with 2 nodes
net.divideFcn = 'dividerand';
net.trainParam.epochs = 50;
net = train(net,x,y);
y_hat = net(x);

%%# plot
plot(x, y, 'b.'), hold on
plot(x, x.^2, 'Color','g', 'LineWidth',2)
plot(x, y_hat, 'Color','r', 'LineWidth',2)
legend({'data (noisy)','model (x^2)','fitted'})
hold off, grid on

%%# manually simulate network
%# map input to [-1,1] range
[~,inMap] = mapminmax(x, -1, 1);
in = mapminmax('apply', x, inMap);

%# propagate values to get output (scaled to [-1,1])
hid = tansig( bsxfun(@plus, net.IW{1}*in, net.b{1}) ); %# hidden layer
outLayerOut = purelin( net.LW{2}*hid + net.b{2} );     %# output layer

%# reverse mapping from [-1,1] to original data scale
[~,outMap] = mapminmax(y, -1, 1);
out = mapminmax('reverse', outLayerOut, outMap);

%# compare against MATLAB output
max( abs(out - y_hat) )        %# this should be zero (or in the order of `eps`)

我选择使用该mapminmax功能,但您也可以手动完成。该公式是一个非常简单的线性映射:

y = (ymax-ymin)*(x-xmin)/(xmax-xmin) + ymin;

截屏

于 2012-08-07T20:01:11.377 回答