我试图创建一个神经网络来估计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 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 -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 3600 3721 3844 3969 4096 4225 4356 4489 4624 4761 4900 5041 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 3600 3721 3844 3969 4096 4225 4356 4489 4624 4761 4900 5041
我使用了拟合工具网络。矩阵行。培训是70%验证是15%,测试也是15%。隐藏神经元的数量是2.然后在命令行中我写了这个:
purelin(net.LW{2}*tansig(net.IW{1}*inputTest+net.b{1})+net.b{2})
其他信息:
我的net.b [1]是:-1.16610230053776 1.16667147712026
my net.b [2]是:51.3266249426358
和net.IW(1)是:0.344272596370387 0.344111217766824
net.LW(2)是:31.7635369693519 -31.8082184881063
当我的inputTest为3时,该命令的结果为16,而它应该是大约9 如果我在某个地方犯了错误,请告诉我。谢谢
编辑: 我发现链接Neural network in MATLAB包含像我的问题一样的问题,但是有一些区别,差异在于那个问题,输入和输出的范围是相同的,但我的问题是否定的。该解决方案说我需要扩展结果,但我不知道如何扩展我的结果。任何想法?
答案 0 :(得分:6)
你是正确的缩放。正如linked answer中提到的,神经网络默认将输入和输出缩放到范围[-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](之前到训练)。
这意味着受过训练的网络需要此范围内的输入值,并且输出值也在相同范围内。如果要手动将输入提供给网络,并自行计算输出,则必须在输入时缩放数据,并在输出处反转映射。
最后要记住的是,每次训练人工神经网络时,你都会得到不同的权重。如果需要可重复的结果,则需要修复随机数生成器的状态(每次使用相同的种子初始化它)。阅读有关rng
和RandStream
等函数的文档。
您还必须注意,如果要将数据划分为训练/测试/验证集,则每次必须使用相同的分割(可能还受到我提到的随机性方面的影响)。
这是一个例子来说明这个想法(改编自我的另一个post):
%%# 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;