上一篇文章讲述了如何对预测的结果进行合理化修正,本文主要讲述的是对神经网络本身的学习算法进行优化。
一般优化神经网络有三种模式,一种为优化神经网络的连接结构,一种为优化神经网络的学习算法,一种为既优化连接结构,又优化学习算法。由于笔者的知识水平有限,所以采用第二种方法——优化神经网络的学习算法作为本实例的优化模型。
神经网络的学习算法有很多种,包括传统的爬山法亦或是拟牛顿法,而目前智能优化算法的兴起使得其对神经网络的学习算法进行替换有了可能。智能优化算法有很多种,每一种都有着其特性,可以根据实际问题来决定使用哪种算法。本实例中主要采用的是粒子群算法(PSO)作为神经网络的学习算法。粒子群算法为群智能算法的一种,为目前比较新兴的智能优化算法,所以相关的文献较少,但是其收敛速度快,不易收敛于局部极值点和并行搜索的特性使得其目前成为了较为热门的研究方向。本文采用标准粒子群算法(带惯性权重)作为神经网络的学习算法,算法本身在这里不再介绍,这里主要讲述粒子群算法如何作为神经网络的学习算法。
粒子群算法与其他的智能算法一样,都需要一定数量的种群。对于粒子群算法来说,粒子种群数量的大小对算法本身的性能来说影响有限,所以可以根据个人使用的机器性能不同,据实际情况来规定种群规模。
神经网络的学习过程可以归纳为,修正神经网络的权值以及阈值,使神经网络的输出误差逐渐减小的过程。对于前向神经网络来说,其输出与网络中的每一个权值和阈值有关。也就是说,其输出是以所有权值和阈值为自变量的相关函数。这样就解决了如何使用智能优化算法解决神经网络的学习问题。具体的解决办法是这样的。将神经网络模型建立以后,将其所有的权值矩阵和阈值矩阵以一定的顺序排列成一个行向量,将其作为一个粒子,在一定的范围初始化之后,送入PSO算法内进行递归择优。那么如何评价粒子的好坏就成了一个问题。评价一个粒子的优劣程度可以使用一个适应度函数来进行判断。适应度函数是智能优化算法与神经网络进行结合的最为重要的一部分。一个粒子的适应度表达了这个粒子的质量,那么对于神经网络来说,它的质量无疑就是对输入样本的拟合度,即样本序列的总偏差。针对每一个粒子,我们可以将其蕴含的信息依照一定的顺序还原成神经网络的权值和阈值矩阵(设为3层网络)。在得到了神经网络所有层的权值矩阵和阈值矩阵之后,设神经网络的输入样本序列为input,则隐层的输出W1out为logsig(input*W1-B1)。其中,W1为输入层与隐层之间的权值矩阵,B1为隐层的阈值矩阵。数学表达中,常用-B1的方式表达。而在matlab的神经网络工具箱中,采用的是+B1的方式。这个问题困扰了我很久,虽然就是一个简简单单的符号,但是就是无法与神经网络工具箱进行对接,最后还是研究了很久的源代码才解决。对于输出层来说与上同理,这里不再赘述。
当然,也可以不用自己设定适应度函数,可以直接将权值与阈值数据带入创建的神经网络中,直接调用sim()进行结果的输出,计算适应度也可以,这样操作足够简单,但最大的缺陷就是速度极其的慢。自己设定的适应度函数原理上与神经网络工具箱相同,但是只是单纯的数学计算会大大的提高运算效率。
当粒子群算法择优完毕后,将粒子按原来约定好的顺序还原为权值矩阵和阈值矩阵,带入创建好的网络,这样粒子群算法作为神经网络的学习算法的过程就完成了。经过计算,仅仅需要递归60步,算法就已经收敛。下面是根据学习数据计算出的拟合曲线。
我们可以很清晰的看出,虽然算法很快的收敛了,但是拟合的精细程度并不高。我们分析算法本身的特性可以看出,粒子群算法的本质仍然为随机的全局搜索算法,其全局搜索的本质就是其粒子运动的随机性。粒子随机运动无疑会加快算法的收敛,但也会大大影响对极值区域的精细化搜索。
我们在选用粒子群算法作为神经网络的学习算法时,主要看重的就是其优异的全局搜索的特性,能够避开局部的极值点,找到最佳的搜索区域。但是其过于快速的收敛会大大的影响拟合情况及预测性能。我们希望神经网络的学习算法在找到最优区域的同时,能够有针对性的搜索到全局极值点。在前文中,我分析到,传统的BP算法易陷入到局部极值区域。其之所以有这样的缺陷,是因为误差的修正来源于误差梯度,节点总是朝着误差梯度的负方向修正权值与阈值。对于局部的搜索,可以说传统BP算法是一个不错的选择。我们可以将粒子群算法和传统的BP算法做一个组合,改善拟合情况。利用PSO算法优异的全局搜索能力以及搜索效率,使用它确定一块优秀的分布区域,再使用传统BP算法,完成极值点附近的精细化搜索,确定最优解。下面给出代码。
N=60;%粒子种群数量
D=inputNum*hiddenNum+hiddenNum+hiddenNum*outputNum+outputNum;%每个粒子的维度
MaxGEN=200;%最大循环次数
c1=3;%学习率
c2=3;
Wmax=1.7;%惯性权值
Wmin=0.1;
Xmax=3;%查找范围
Xmin=-3;
Vmax=0.005;%粒子速度范围
Vmin=-0.005;
%%初始化种群个体
x=rand(N,D)*(Xmax-Xmin)+Xmin;
v=rand(N,D)*(Vmax-Vmin)+Vmin;
%%初始化个体最优位置和最优值
p=x;
pbest=ones(N,1);
for i=1:N
pbest(i)=funcl(x(i,:),p1,t1,hiddenNum);
end
%%%初始化全局最优位置和最优值
g=ones(1,D);%保存最优个体
gbest=inf;%保存最优适应度值
for i=1:N
if(pbest(i)<gbest)
g=p(i,:);
gbest=pbest(i);
end
end
gb=ones(1,MaxGEN);
%%%按照公式依次迭代,直到满足精度或者达到迭代次数
tic;
for i=1:MaxGEN
for j=1:N
%%%更新个体最优位置和最优值
if funcl(x(j,:),p1,t1,hiddenNum)<pbest(j)
p(j,:)=x(j,:);
pbest(j)=funcl(x(j,:),p1,t1,hiddenNum);
end
%%%更新全局最优位置和最优值
if pbest(j)<gbest
g=p(j,:);
gbest=pbest(j);
end
%%%计算动态惯性权重数
w=Wmax-(Wmax-Wmin)*i/MaxGEN;
%%%更新位置和速度值
v(j,:)=w*v(j,:)+c1*rand*(p(j,:)-x(j,:))+c2*rand*(g-x(j,:));
x(j,:)=x(j,:)+v(j,:);
%%%边界条件处理
for ii=1:D
if (v(j,ii)>Vmax) | (v(j,ii)<Vmin)
v(j,ii)=rand*(Vmax-Vmin)+Vmin;
end
if (x(j,ii)>Xmax) | (x(j,ii)<Xmin)
x(j,ii)=rand*(Xmax-Xmin)+Xmin;
end
end
end
%%%记录历代最优值
gb(i)=gbest;
disp(gbest);
end;
toc;
%%%将pso算法优化后的权值阈值矩阵带入建好的神经网络中
w1=g(1,1:inputNum*hiddenNum);
b1=g(1,inputNum*hiddenNum+1:inputNum*hiddenNum+hiddenNum);
w2=g(1,inputNum*hiddenNum+hiddenNum+1:inputNum*hiddenNum+hiddenNum+hiddenNum*outputNum);
b2=g(1,inputNum*hiddenNum+hiddenNum+hiddenNum*outputNum+1:inputNum*hiddenNum+hiddenNum+hiddenNum*outputNum+outputNum);
net.IW{1,1}=reshape(w1,hiddenNum,inputNum);
net.LW{2,1}=reshape(w2,outputNum,hiddenNum);
net.b{1}=b1';
net.b{2}=b2';
%%%计算pso算法训练后的拟合结果
wout=sim(net,p1);
disp('pso拟合评价');
errorCal(wout,t1,trainNum,1);
%%%网络再由bp算法进行下一步的训练
net=train(net,p1,t1);
%%%经过pso算法和bp算法的复合训练后得出的结果
wout1=sim(net,p1);
我的分享就在这里结束了,所有源代码均在github上,网址为https://github.com/FutureFighter111/DataAnalysis-Graduation-Project-
希望大家可以多多指正讨论,也希望可以帮助一些人。