粒子群优化算法(Particle Swarm Optimization, PSO)是在1995年由美国社会心理学家James Kennedy和电气工程师Russell Eberhart共同提出的,其基本思想是受他们早期对鸟类群体行为研究结果的启发,并利用了生物学家Frank Heppner的生物群体模型。PSO算法与遗传算法类似,是一种基于迭代的优化算法,但无交叉变异等操作,其搜索过程是通过粒子在解空间中不断更新自己的速度和位置,以追随最优粒子而进行的。
PSO算法首先随机的初始化一个粒子群体,通过迭代寻找最优解,在每一次迭代过程中,每个粒子目前所找到的最优解为pBest,整个种群目前所找到的最优解为gBest,每个粒子通过这两极值来更新自己的速度和位置,相应的公式为:
v = v + c1 * rand() * (pbest - present) + c2 * rand() * (gbest - present)
present = persent + v
其中,v为粒子的速度,present为粒子的位置(在具体应用中pBest, gBest, v, present为向量),rand()产生0到1之间的随机数,c1和c2为学习因子。在进化迭代过程中,须根据实际需要为v和present指定范围。
PSO算法可用于BP神经网络的网络权值优化中,传统的BP神经网络采用误差反向传播来调整网络连接权值,该方法容易陷入局部最优解,而PSO算法可以在更大的空间内搜索,在一定程度上避免了以上问题。
将神经网络各层的连接权值编码成粒子,适应度值则为使用该组权值时的网络输出均方误差,利用之前描述的粒子群算法,在预设的迭代次数内搜索最优的网络权值。
以下的Matlab程序演示了PSO优化BP网络的过程,程序的目的是使用BP神经网络进行正弦函数逼近,使用3层神经网络,隐含层由3个神经元组成,粒子群共包含20个粒子,每个粒子的长度为10。其中BP网络使用Matlab自带的工具箱,非工具箱的实现可参考:BP网络的函数逼近在Matlab中的实现
07 | net = newff(p, t, n, { 'tansig' , 'purelin' }, 'trainlm' ); |
10 | swarmLength = 10; %粒子长度 |
13 | swarm = rand (swarmCount, swarmLength); %初始粒子群,即粒子的位置 |
14 | v = rand (swarmCount, swarmLength); %粒子的速度 |
15 | swarmfitness = zeros(swarmCount, 1, 'double' ); %粒子的适应度值 |
16 | pBest = rand (swarmCount, swarmLength); %个体最优值 |
17 | pBestfitness = zeros(swarmCount, 1, 'double' ); %个体最优适应度值 |
18 | pBestfitness(:, :) = 100; |
19 | gBest = rand (1, swarmLength); %全局最优值 |
20 | gBestfitness = 100; %全局最优适应度值 |
23 | maxEpoch = 2000; %最大训练次数 |
24 | errGoal = 0.01; %期望误差最小值 |
26 | while (epoch < maxEpoch && gBestfitness > errGoal) |
27 | for i = 1 : swarmCount |
29 | net.iw{1, 1} = swarm(i, 1 : 3)'; |
30 | net.b{1} = swarm(i, 4 : 6)'; |
31 | net.lw{2, 1} = swarm(i, 7 : 9); |
32 | net.b{2} = swarm(i, 10 : 10); |
34 | sse = sum((tout - t) .^ 2) / length(t); |
35 | swarmfitness(i, 1) = sse; |
37 | if (pBestfitness(i, 1) > sse) |
38 | pBestfitness(i, 1) = sse; |
39 | pBest(i, :) = swarm(i, :); |
42 | if (gBestfitness > sse) |
44 | gBest(1, :) = swarm(i, :); |
50 | for i = 1 : swarmCount |
51 | v(i, :) = v(i, :) + c1 * rand (1, 1) * (pBest(i, :) - swarm(i, :)) + c2 * rand (1, 1) * (gBest(1, :) - swarm(i, :)); |
52 | tmp = find(v(i, :) > vMax); |
55 | swarm(i, :) = swarm(i, :) + v(i, :); |
56 | tmp = find(swarm(i, :) > pMax); |
63 | net.iw{1, 1} = gBest(1, 1 : 3)'; |
64 | net.b{1} = gBest(1, 4 : 6)'; |
65 | net.lw{2, 1} = gBest(1, 7 : 9); |
66 | net.b{2} = gBest(1, 10 : 10); |
69 | figure, plot(p, t, 'k-' ); |
针对粒子群算法的改进研究也非常多,如我们江南大学的孙俊老师提出的量子粒子群算法(Quantum-behaved Particle Swarm Optimization)在学术圈内就具有较大影响,在量子空间中,粒子可以在整个可行解空间中进行搜索,因而QPSO算法的全局搜索性能远远优于标准PSO算法。最近的研究中使用了自适应神经模糊系统(Adaptive Neuro-Fuzzy System),后续计划使用QPSO算法对模糊系统进行优化。
--End--