参考书目:智能控制技术(第二版)
对于逼近正弦函数很多讲神经网络的书中都有涉及,算是比较简单的一个例子。对于这个网络来说,输入只有一个,那就是采样点(或者说时间点),输出显然只有一个,也就是一个与sin(x)较为相似的函数。在训练的过程中,sin(x)作为网络的期望值。激活函数选择常用的sigmoid函数,采样点的范围为[0,2π],在该范围内sin(x)仅有两个拐点,经过测试,隐层中含有3个神经元即可很好的完成逼近任务。(1-3-1网络结构)
clear
clc
%参数初始化
l = 0.05; %学习速率(步长)
n = 30; %采样点的数目
cells = 3; %隐层3个神经元
times = 3000; %学习次数
x= (linspace(0,2*pi,n)); %[0,2π]区间,均匀30个点
t= sin(x); %期望的函数
w1 = rand(cells,1)*0.05; %输入层3*1权值向量
w2 = rand(1,cells)*0.05; %1*3隐含层-输出层连接权值向量
b1 = rand(cells,1)*0.05; %3*1隐含层阈值向量
b2 = rand*0.05; %输出层阈值
counts = 1; %计数
e = zeros(1,times); %均方误差
%训练过程
for i = 1:times
ei = 0;
for a = 1:n
net1 = w1 * x(a) - b1;
out = logsig(net1);
net2 = w2 * out - b2;
y(a) = net2;
det2 = t(a) - y(a);
det1 = ((det2 * (w2)').*out).*(1 - out); %由链式求导得出
w1 = w1 + det1 * x(a) * l;
w2 = w2 + (det2*out)' * l;
b1 = b1 - det1 * l;
b2 = b2 - det2 * l;
ei = ei + det2^2;
end
e(i) = ei/n;
if e(i) < 0.0001 %期望误差
break;
end
counts = counts + 1;
end
%输出部分
for a = 1:n
net1 = w1 * x(a) - b1;
out = logsig(net1);
net2 = w2 * out - b2;
y(a) = net2;
end
subplot(2,1,1);
plot(x,t,'b-',x,y,'k*-');
grid on
title('BPsinx');
xlabel('xlable');
ylabel('y = sinx');
%Err curve
if(counts<times)
count = 1:counts;
sum = counts;
else
count = 1:times;
sum = times;
end
subplot(2,1,2);
plot(count,e(1:sum));
grid on
title('BPlearning curve');
xlabel('Iteration times');
ylabel('Mean err');
值得注意的是,网络逼近sin(x)完成后,仅仅在给定采样区间有效,超出这个区间后,网络输出并不能继续匹配sin(x)函数,若要逼近更多拐点的函数,应增加隐层神经元的数量。(1-3-1结构的最大能力好像是4个拐点)